code-coordinator 0.5.556__tar.gz → 0.5.558__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 (929) hide show
  1. {code_coordinator-0.5.556 → code_coordinator-0.5.558}/PKG-INFO +1 -1
  2. {code_coordinator-0.5.556 → code_coordinator-0.5.558}/code_coordinator.egg-info/PKG-INFO +1 -1
  3. {code_coordinator-0.5.556 → code_coordinator-0.5.558}/code_coordinator.egg-info/scm_version.json +2 -2
  4. {code_coordinator-0.5.556 → code_coordinator-0.5.558}/coord/bugbash.py +269 -58
  5. {code_coordinator-0.5.556 → code_coordinator-0.5.558}/coord/commands/bugbash.py +58 -12
  6. {code_coordinator-0.5.556 → code_coordinator-0.5.558}/coord/release_gate.py +69 -7
  7. {code_coordinator-0.5.556 → code_coordinator-0.5.558}/coord/win_native_bridge.py +217 -25
  8. {code_coordinator-0.5.556 → code_coordinator-0.5.558}/tests/test_bugbash.py +205 -16
  9. {code_coordinator-0.5.556 → code_coordinator-0.5.558}/tests/test_release_gate.py +80 -0
  10. {code_coordinator-0.5.556 → code_coordinator-0.5.558}/tests/test_win_native_bridge.py +197 -41
  11. {code_coordinator-0.5.556 → code_coordinator-0.5.558}/.claude/commands/board.md +0 -0
  12. {code_coordinator-0.5.556 → code_coordinator-0.5.558}/.claude/commands/complete-session.md +0 -0
  13. {code_coordinator-0.5.556 → code_coordinator-0.5.558}/.claude/commands/coordinator.md +0 -0
  14. {code_coordinator-0.5.556 → code_coordinator-0.5.558}/.githooks/_lib.sh +0 -0
  15. {code_coordinator-0.5.556 → code_coordinator-0.5.558}/.githooks/post-checkout +0 -0
  16. {code_coordinator-0.5.556 → code_coordinator-0.5.558}/.githooks/post-commit +0 -0
  17. {code_coordinator-0.5.556 → code_coordinator-0.5.558}/.githooks/post-merge +0 -0
  18. {code_coordinator-0.5.556 → code_coordinator-0.5.558}/.github/ISSUE_TEMPLATE/bug_report.md +0 -0
  19. {code_coordinator-0.5.556 → code_coordinator-0.5.558}/.github/coord-ci-acceptance.yml +0 -0
  20. {code_coordinator-0.5.556 → code_coordinator-0.5.558}/.github/workflows/auto-release.yml +0 -0
  21. {code_coordinator-0.5.556 → code_coordinator-0.5.558}/.github/workflows/publish.yml +0 -0
  22. {code_coordinator-0.5.556 → code_coordinator-0.5.558}/.github/workflows/test.yml +0 -0
  23. {code_coordinator-0.5.556 → code_coordinator-0.5.558}/.gitignore +0 -0
  24. {code_coordinator-0.5.556 → code_coordinator-0.5.558}/CLAUDE.md +0 -0
  25. {code_coordinator-0.5.556 → code_coordinator-0.5.558}/GOAL.md +0 -0
  26. {code_coordinator-0.5.556 → code_coordinator-0.5.558}/LICENSE +0 -0
  27. {code_coordinator-0.5.556 → code_coordinator-0.5.558}/MANIFEST.in +0 -0
  28. {code_coordinator-0.5.556 → code_coordinator-0.5.558}/README.md +0 -0
  29. {code_coordinator-0.5.556 → code_coordinator-0.5.558}/code_coordinator.egg-info/SOURCES.txt +0 -0
  30. {code_coordinator-0.5.556 → code_coordinator-0.5.558}/code_coordinator.egg-info/dependency_links.txt +0 -0
  31. {code_coordinator-0.5.556 → code_coordinator-0.5.558}/code_coordinator.egg-info/entry_points.txt +0 -0
  32. {code_coordinator-0.5.556 → code_coordinator-0.5.558}/code_coordinator.egg-info/requires.txt +0 -0
  33. {code_coordinator-0.5.556 → code_coordinator-0.5.558}/code_coordinator.egg-info/scm_file_list.json +0 -0
  34. {code_coordinator-0.5.556 → code_coordinator-0.5.558}/code_coordinator.egg-info/top_level.txt +0 -0
  35. {code_coordinator-0.5.556 → code_coordinator-0.5.558}/coord/__init__.py +0 -0
  36. {code_coordinator-0.5.556 → code_coordinator-0.5.558}/coord/_board_mapping.py +0 -0
  37. {code_coordinator-0.5.556 → code_coordinator-0.5.558}/coord/acceptance.py +0 -0
  38. {code_coordinator-0.5.556 → code_coordinator-0.5.558}/coord/acceptance_drivers.py +0 -0
  39. {code_coordinator-0.5.556 → code_coordinator-0.5.558}/coord/agent.py +0 -0
  40. {code_coordinator-0.5.556 → code_coordinator-0.5.558}/coord/agent_app.py +0 -0
  41. {code_coordinator-0.5.556 → code_coordinator-0.5.558}/coord/agent_update.py +0 -0
  42. {code_coordinator-0.5.556 → code_coordinator-0.5.558}/coord/agents/opencode/.gitignore +0 -0
  43. {code_coordinator-0.5.556 → code_coordinator-0.5.558}/coord/agents/opencode/agents/work.md +0 -0
  44. {code_coordinator-0.5.556 → code_coordinator-0.5.558}/coord/agents/opencode/routing.jsonc +0 -0
  45. {code_coordinator-0.5.556 → code_coordinator-0.5.558}/coord/approved_work.py +0 -0
  46. {code_coordinator-0.5.556 → code_coordinator-0.5.558}/coord/audit.py +0 -0
  47. {code_coordinator-0.5.556 → code_coordinator-0.5.558}/coord/auto_loop.py +0 -0
  48. {code_coordinator-0.5.556 → code_coordinator-0.5.558}/coord/backup.py +0 -0
  49. {code_coordinator-0.5.556 → code_coordinator-0.5.558}/coord/block_log.py +0 -0
  50. {code_coordinator-0.5.556 → code_coordinator-0.5.558}/coord/board_schema.py +0 -0
  51. {code_coordinator-0.5.556 → code_coordinator-0.5.558}/coord/board_service.py +0 -0
  52. {code_coordinator-0.5.556 → code_coordinator-0.5.558}/coord/board_wire.py +0 -0
  53. {code_coordinator-0.5.556 → code_coordinator-0.5.558}/coord/brain.py +0 -0
  54. {code_coordinator-0.5.556 → code_coordinator-0.5.558}/coord/branch_model.py +0 -0
  55. {code_coordinator-0.5.556 → code_coordinator-0.5.558}/coord/bug_intake.py +0 -0
  56. {code_coordinator-0.5.556 → code_coordinator-0.5.558}/coord/cargo_cache.py +0 -0
  57. {code_coordinator-0.5.556 → code_coordinator-0.5.558}/coord/ci_fix.py +0 -0
  58. {code_coordinator-0.5.556 → code_coordinator-0.5.558}/coord/ci_github.py +0 -0
  59. {code_coordinator-0.5.556 → code_coordinator-0.5.558}/coord/ci_gitlab.py +0 -0
  60. {code_coordinator-0.5.556 → code_coordinator-0.5.558}/coord/ci_store.py +0 -0
  61. {code_coordinator-0.5.556 → code_coordinator-0.5.558}/coord/claim.py +0 -0
  62. {code_coordinator-0.5.556 → code_coordinator-0.5.558}/coord/claude_setup_token.py +0 -0
  63. {code_coordinator-0.5.556 → code_coordinator-0.5.558}/coord/cli.py +0 -0
  64. {code_coordinator-0.5.556 → code_coordinator-0.5.558}/coord/client.py +0 -0
  65. {code_coordinator-0.5.556 → code_coordinator-0.5.558}/coord/codegen.py +0 -0
  66. {code_coordinator-0.5.556 → code_coordinator-0.5.558}/coord/commands/__init__.py +0 -0
  67. {code_coordinator-0.5.556 → code_coordinator-0.5.558}/coord/commands/_common.py +0 -0
  68. {code_coordinator-0.5.556 → code_coordinator-0.5.558}/coord/commands/acceptance.py +0 -0
  69. {code_coordinator-0.5.556 → code_coordinator-0.5.558}/coord/commands/agent_ops.py +0 -0
  70. {code_coordinator-0.5.556 → code_coordinator-0.5.558}/coord/commands/audit.py +0 -0
  71. {code_coordinator-0.5.556 → code_coordinator-0.5.558}/coord/commands/backup.py +0 -0
  72. {code_coordinator-0.5.556 → code_coordinator-0.5.558}/coord/commands/chat.py +0 -0
  73. {code_coordinator-0.5.556 → code_coordinator-0.5.558}/coord/commands/ci.py +0 -0
  74. {code_coordinator-0.5.556 → code_coordinator-0.5.558}/coord/commands/codegen.py +0 -0
  75. {code_coordinator-0.5.556 → code_coordinator-0.5.558}/coord/commands/dispatch.py +0 -0
  76. {code_coordinator-0.5.556 → code_coordinator-0.5.558}/coord/commands/dispatch_workers.py +0 -0
  77. {code_coordinator-0.5.556 → code_coordinator-0.5.558}/coord/commands/dr.py +0 -0
  78. {code_coordinator-0.5.556 → code_coordinator-0.5.558}/coord/commands/drive.py +0 -0
  79. {code_coordinator-0.5.556 → code_coordinator-0.5.558}/coord/commands/drive_queue.py +0 -0
  80. {code_coordinator-0.5.556 → code_coordinator-0.5.558}/coord/commands/gate_a.py +0 -0
  81. {code_coordinator-0.5.556 → code_coordinator-0.5.558}/coord/commands/gates.py +0 -0
  82. {code_coordinator-0.5.556 → code_coordinator-0.5.558}/coord/commands/issues.py +0 -0
  83. {code_coordinator-0.5.556 → code_coordinator-0.5.558}/coord/commands/lifecycle.py +0 -0
  84. {code_coordinator-0.5.556 → code_coordinator-0.5.558}/coord/commands/machine.py +0 -0
  85. {code_coordinator-0.5.556 → code_coordinator-0.5.558}/coord/commands/merge.py +0 -0
  86. {code_coordinator-0.5.556 → code_coordinator-0.5.558}/coord/commands/milestone.py +0 -0
  87. {code_coordinator-0.5.556 → code_coordinator-0.5.558}/coord/commands/plan_followup.py +0 -0
  88. {code_coordinator-0.5.556 → code_coordinator-0.5.558}/coord/commands/plans.py +0 -0
  89. {code_coordinator-0.5.556 → code_coordinator-0.5.558}/coord/commands/portal.py +0 -0
  90. {code_coordinator-0.5.556 → code_coordinator-0.5.558}/coord/commands/pr.py +0 -0
  91. {code_coordinator-0.5.556 → code_coordinator-0.5.558}/coord/commands/release.py +0 -0
  92. {code_coordinator-0.5.556 → code_coordinator-0.5.558}/coord/commands/repo.py +0 -0
  93. {code_coordinator-0.5.556 → code_coordinator-0.5.558}/coord/commands/report.py +0 -0
  94. {code_coordinator-0.5.556 → code_coordinator-0.5.558}/coord/commands/review.py +0 -0
  95. {code_coordinator-0.5.556 → code_coordinator-0.5.558}/coord/commands/scorecard.py +0 -0
  96. {code_coordinator-0.5.556 → code_coordinator-0.5.558}/coord/commands/sessions.py +0 -0
  97. {code_coordinator-0.5.556 → code_coordinator-0.5.558}/coord/commands/setup.py +0 -0
  98. {code_coordinator-0.5.556 → code_coordinator-0.5.558}/coord/commands/status.py +0 -0
  99. {code_coordinator-0.5.556 → code_coordinator-0.5.558}/coord/commands/store_migrate.py +0 -0
  100. {code_coordinator-0.5.556 → code_coordinator-0.5.558}/coord/commands/terminal.py +0 -0
  101. {code_coordinator-0.5.556 → code_coordinator-0.5.558}/coord/commands/test_gate.py +0 -0
  102. {code_coordinator-0.5.556 → code_coordinator-0.5.558}/coord/commands/tui.py +0 -0
  103. {code_coordinator-0.5.556 → code_coordinator-0.5.558}/coord/comments.py +0 -0
  104. {code_coordinator-0.5.556 → code_coordinator-0.5.558}/coord/config.py +0 -0
  105. {code_coordinator-0.5.556 → code_coordinator-0.5.558}/coord/config_reload.py +0 -0
  106. {code_coordinator-0.5.556 → code_coordinator-0.5.558}/coord/confirm_test.py +0 -0
  107. {code_coordinator-0.5.556 → code_coordinator-0.5.558}/coord/conflict_fix.py +0 -0
  108. {code_coordinator-0.5.556 → code_coordinator-0.5.558}/coord/dao.py +0 -0
  109. {code_coordinator-0.5.556 → code_coordinator-0.5.558}/coord/dashboard/__init__.py +0 -0
  110. {code_coordinator-0.5.556 → code_coordinator-0.5.558}/coord/dashboard/fixture.py +0 -0
  111. {code_coordinator-0.5.556 → code_coordinator-0.5.558}/coord/dashboard/index.html +0 -0
  112. {code_coordinator-0.5.556 → code_coordinator-0.5.558}/coord/dashboard/server.py +0 -0
  113. {code_coordinator-0.5.556 → code_coordinator-0.5.558}/coord/dashboard/terminal.py +0 -0
  114. {code_coordinator-0.5.556 → code_coordinator-0.5.558}/coord/db.py +0 -0
  115. {code_coordinator-0.5.556 → code_coordinator-0.5.558}/coord/dead_end.py +0 -0
  116. {code_coordinator-0.5.556 → code_coordinator-0.5.558}/coord/decomposition_chat.py +0 -0
  117. {code_coordinator-0.5.556 → code_coordinator-0.5.558}/coord/deploy/README.md +0 -0
  118. {code_coordinator-0.5.556 → code_coordinator-0.5.558}/coord/deploy/coord-agent.service +0 -0
  119. {code_coordinator-0.5.556 → code_coordinator-0.5.558}/coord/deploy/coord-backup.service +0 -0
  120. {code_coordinator-0.5.556 → code_coordinator-0.5.558}/coord/deploy/coord-backup.timer +0 -0
  121. {code_coordinator-0.5.556 → code_coordinator-0.5.558}/coord/deploy/coord-db-backup.service +0 -0
  122. {code_coordinator-0.5.556 → code_coordinator-0.5.558}/coord/deploy/coord-db-backup.sh +0 -0
  123. {code_coordinator-0.5.556 → code_coordinator-0.5.558}/coord/deploy/coord-db-backup.timer +0 -0
  124. {code_coordinator-0.5.556 → code_coordinator-0.5.558}/coord/deploy/coord-dr-verify.service +0 -0
  125. {code_coordinator-0.5.556 → code_coordinator-0.5.558}/coord/deploy/coord-dr-verify.timer +0 -0
  126. {code_coordinator-0.5.556 → code_coordinator-0.5.558}/coord/deploy/coord-drive-queue.service +0 -0
  127. {code_coordinator-0.5.556 → code_coordinator-0.5.558}/coord/deploy/coord-drive-queue.timer +0 -0
  128. {code_coordinator-0.5.556 → code_coordinator-0.5.558}/coord/deploy/coord-failure-notify.service +0 -0
  129. {code_coordinator-0.5.556 → code_coordinator-0.5.558}/coord/deploy/coord-fleet-watchdog.service +0 -0
  130. {code_coordinator-0.5.556 → code_coordinator-0.5.558}/coord/deploy/coord-fleet-watchdog.timer +0 -0
  131. {code_coordinator-0.5.556 → code_coordinator-0.5.558}/coord/deploy/coord-notify.service +0 -0
  132. {code_coordinator-0.5.556 → code_coordinator-0.5.558}/coord/deploy/coord-notify.timer +0 -0
  133. {code_coordinator-0.5.556 → code_coordinator-0.5.558}/coord/deploy/coord-release-propagate.service +0 -0
  134. {code_coordinator-0.5.556 → code_coordinator-0.5.558}/coord/deploy/coord-release-propagate.timer +0 -0
  135. {code_coordinator-0.5.556 → code_coordinator-0.5.558}/coord/deploy/coord-release-window.service +0 -0
  136. {code_coordinator-0.5.556 → code_coordinator-0.5.558}/coord/deploy/coord-release-window.timer +0 -0
  137. {code_coordinator-0.5.556 → code_coordinator-0.5.558}/coord/deploy/coord-serve.service +0 -0
  138. {code_coordinator-0.5.556 → code_coordinator-0.5.558}/coord/deploy/coord-web-dist-build.service +0 -0
  139. {code_coordinator-0.5.556 → code_coordinator-0.5.558}/coord/deploy/coord-web-dist-build.timer +0 -0
  140. {code_coordinator-0.5.556 → code_coordinator-0.5.558}/coord/deploy/coord-web.service +0 -0
  141. {code_coordinator-0.5.556 → code_coordinator-0.5.558}/coord/deploy_manifest.py +0 -0
  142. {code_coordinator-0.5.556 → code_coordinator-0.5.558}/coord/deploy_units.py +0 -0
  143. {code_coordinator-0.5.556 → code_coordinator-0.5.558}/coord/deprecation_telemetry.py +0 -0
  144. {code_coordinator-0.5.556 → code_coordinator-0.5.558}/coord/deps.py +0 -0
  145. {code_coordinator-0.5.556 → code_coordinator-0.5.558}/coord/diagnose.py +0 -0
  146. {code_coordinator-0.5.556 → code_coordinator-0.5.558}/coord/dispatch.py +0 -0
  147. {code_coordinator-0.5.556 → code_coordinator-0.5.558}/coord/dispatch_liveness.py +0 -0
  148. {code_coordinator-0.5.556 → code_coordinator-0.5.558}/coord/dist_name.py +0 -0
  149. {code_coordinator-0.5.556 → code_coordinator-0.5.558}/coord/dr_promote.py +0 -0
  150. {code_coordinator-0.5.556 → code_coordinator-0.5.558}/coord/dr_verify.py +0 -0
  151. {code_coordinator-0.5.556 → code_coordinator-0.5.558}/coord/drive.py +0 -0
  152. {code_coordinator-0.5.556 → code_coordinator-0.5.558}/coord/drive_queue.py +0 -0
  153. {code_coordinator-0.5.556 → code_coordinator-0.5.558}/coord/drive_sessions_snapshot.py +0 -0
  154. {code_coordinator-0.5.556 → code_coordinator-0.5.558}/coord/drive_state.py +0 -0
  155. {code_coordinator-0.5.556 → code_coordinator-0.5.558}/coord/events.py +0 -0
  156. {code_coordinator-0.5.556 → code_coordinator-0.5.558}/coord/failure_class.py +0 -0
  157. {code_coordinator-0.5.556 → code_coordinator-0.5.558}/coord/failure_classifier.py +0 -0
  158. {code_coordinator-0.5.556 → code_coordinator-0.5.558}/coord/filelock.py +0 -0
  159. {code_coordinator-0.5.556 → code_coordinator-0.5.558}/coord/fleet_config_health.py +0 -0
  160. {code_coordinator-0.5.556 → code_coordinator-0.5.558}/coord/forge_availability.py +0 -0
  161. {code_coordinator-0.5.556 → code_coordinator-0.5.558}/coord/freshness.py +0 -0
  162. {code_coordinator-0.5.556 → code_coordinator-0.5.558}/coord/gate_a.py +0 -0
  163. {code_coordinator-0.5.556 → code_coordinator-0.5.558}/coord/gate_b.py +0 -0
  164. {code_coordinator-0.5.556 → code_coordinator-0.5.558}/coord/gate_snapshot.py +0 -0
  165. {code_coordinator-0.5.556 → code_coordinator-0.5.558}/coord/gates.py +0 -0
  166. {code_coordinator-0.5.556 → code_coordinator-0.5.558}/coord/gen_board_fixture.py +0 -0
  167. {code_coordinator-0.5.556 → code_coordinator-0.5.558}/coord/github_ops.py +0 -0
  168. {code_coordinator-0.5.556 → code_coordinator-0.5.558}/coord/github_throttle.py +0 -0
  169. {code_coordinator-0.5.556 → code_coordinator-0.5.558}/coord/goal.py +0 -0
  170. {code_coordinator-0.5.556 → code_coordinator-0.5.558}/coord/graph_health.py +0 -0
  171. {code_coordinator-0.5.556 → code_coordinator-0.5.558}/coord/gtk_native_driver.py +0 -0
  172. {code_coordinator-0.5.556 → code_coordinator-0.5.558}/coord/health/__init__.py +0 -0
  173. {code_coordinator-0.5.556 → code_coordinator-0.5.558}/coord/health/aggregate.py +0 -0
  174. {code_coordinator-0.5.556 → code_coordinator-0.5.558}/coord/health/checks/__init__.py +0 -0
  175. {code_coordinator-0.5.556 → code_coordinator-0.5.558}/coord/health/checks/_ci_pin.py +0 -0
  176. {code_coordinator-0.5.556 → code_coordinator-0.5.558}/coord/health/checks/agent_install.py +0 -0
  177. {code_coordinator-0.5.556 → code_coordinator-0.5.558}/coord/health/checks/cargo_targets.py +0 -0
  178. {code_coordinator-0.5.556 → code_coordinator-0.5.558}/coord/health/checks/claude_binary.py +0 -0
  179. {code_coordinator-0.5.556 → code_coordinator-0.5.558}/coord/health/checks/config_drift.py +0 -0
  180. {code_coordinator-0.5.556 → code_coordinator-0.5.558}/coord/health/checks/coord_tui_ci_pin.py +0 -0
  181. {code_coordinator-0.5.556 → code_coordinator-0.5.558}/coord/health/checks/coord_web_ci_pin.py +0 -0
  182. {code_coordinator-0.5.556 → code_coordinator-0.5.558}/coord/health/checks/deploy_lane_facts.py +0 -0
  183. {code_coordinator-0.5.556 → code_coordinator-0.5.558}/coord/health/checks/disk.py +0 -0
  184. {code_coordinator-0.5.556 → code_coordinator-0.5.558}/coord/health/checks/fleet_board.py +0 -0
  185. {code_coordinator-0.5.556 → code_coordinator-0.5.558}/coord/health/checks/fleet_deploy_lanes.py +0 -0
  186. {code_coordinator-0.5.556 → code_coordinator-0.5.558}/coord/health/checks/fleet_phantom.py +0 -0
  187. {code_coordinator-0.5.556 → code_coordinator-0.5.558}/coord/health/checks/fleet_unit_drift.py +0 -0
  188. {code_coordinator-0.5.556 → code_coordinator-0.5.558}/coord/health/checks/graph.py +0 -0
  189. {code_coordinator-0.5.556 → code_coordinator-0.5.558}/coord/health/checks/graphify_cli.py +0 -0
  190. {code_coordinator-0.5.556 → code_coordinator-0.5.558}/coord/health/checks/index_lock.py +0 -0
  191. {code_coordinator-0.5.556 → code_coordinator-0.5.558}/coord/health/checks/issues_sync_staleness.py +0 -0
  192. {code_coordinator-0.5.556 → code_coordinator-0.5.558}/coord/health/checks/local_machine_identity.py +0 -0
  193. {code_coordinator-0.5.556 → code_coordinator-0.5.558}/coord/health/checks/plan_usage.py +0 -0
  194. {code_coordinator-0.5.556 → code_coordinator-0.5.558}/coord/health/checks/pr_churn.py +0 -0
  195. {code_coordinator-0.5.556 → code_coordinator-0.5.558}/coord/health/checks/release_cordon.py +0 -0
  196. {code_coordinator-0.5.556 → code_coordinator-0.5.558}/coord/health/checks/repo_state.py +0 -0
  197. {code_coordinator-0.5.556 → code_coordinator-0.5.558}/coord/health/checks/spawned_coord.py +0 -0
  198. {code_coordinator-0.5.556 → code_coordinator-0.5.558}/coord/health/checks/stalled_pipeline.py +0 -0
  199. {code_coordinator-0.5.556 → code_coordinator-0.5.558}/coord/health/checks/timer_active.py +0 -0
  200. {code_coordinator-0.5.556 → code_coordinator-0.5.558}/coord/health/checks/toolchain.py +0 -0
  201. {code_coordinator-0.5.556 → code_coordinator-0.5.558}/coord/health/checks/unit_drift.py +0 -0
  202. {code_coordinator-0.5.556 → code_coordinator-0.5.558}/coord/health/checks/unit_enablement.py +0 -0
  203. {code_coordinator-0.5.556 → code_coordinator-0.5.558}/coord/health/checks/wedged_drive_queue.py +0 -0
  204. {code_coordinator-0.5.556 → code_coordinator-0.5.558}/coord/health/checks/worktrees.py +0 -0
  205. {code_coordinator-0.5.556 → code_coordinator-0.5.558}/coord/health/cli.py +0 -0
  206. {code_coordinator-0.5.556 → code_coordinator-0.5.558}/coord/health/context.py +0 -0
  207. {code_coordinator-0.5.556 → code_coordinator-0.5.558}/coord/health/fleet_snapshot.py +0 -0
  208. {code_coordinator-0.5.556 → code_coordinator-0.5.558}/coord/health/models.py +0 -0
  209. {code_coordinator-0.5.556 → code_coordinator-0.5.558}/coord/health/pypi.py +0 -0
  210. {code_coordinator-0.5.556 → code_coordinator-0.5.558}/coord/health/registry.py +0 -0
  211. {code_coordinator-0.5.556 → code_coordinator-0.5.558}/coord/health/render.py +0 -0
  212. {code_coordinator-0.5.556 → code_coordinator-0.5.558}/coord/health/units.py +0 -0
  213. {code_coordinator-0.5.556 → code_coordinator-0.5.558}/coord/hooks.py +0 -0
  214. {code_coordinator-0.5.556 → code_coordinator-0.5.558}/coord/housekeeping.py +0 -0
  215. {code_coordinator-0.5.556 → code_coordinator-0.5.558}/coord/interactive.py +0 -0
  216. {code_coordinator-0.5.556 → code_coordinator-0.5.558}/coord/invariant_alarms.py +0 -0
  217. {code_coordinator-0.5.556 → code_coordinator-0.5.558}/coord/issue_store.py +0 -0
  218. {code_coordinator-0.5.556 → code_coordinator-0.5.558}/coord/issues_sync_status.py +0 -0
  219. {code_coordinator-0.5.556 → code_coordinator-0.5.558}/coord/liveness_auditor.py +0 -0
  220. {code_coordinator-0.5.556 → code_coordinator-0.5.558}/coord/mac_native_driver.py +0 -0
  221. {code_coordinator-0.5.556 → code_coordinator-0.5.558}/coord/machine_fault.py +0 -0
  222. {code_coordinator-0.5.556 → code_coordinator-0.5.558}/coord/machine_metrics.py +0 -0
  223. {code_coordinator-0.5.556 → code_coordinator-0.5.558}/coord/machine_onboard.py +0 -0
  224. {code_coordinator-0.5.556 → code_coordinator-0.5.558}/coord/machine_pause.py +0 -0
  225. {code_coordinator-0.5.556 → code_coordinator-0.5.558}/coord/machine_stats.py +0 -0
  226. {code_coordinator-0.5.556 → code_coordinator-0.5.558}/coord/merge_queue.py +0 -0
  227. {code_coordinator-0.5.556 → code_coordinator-0.5.558}/coord/milestone_chat.py +0 -0
  228. {code_coordinator-0.5.556 → code_coordinator-0.5.558}/coord/milestone_dispatch.py +0 -0
  229. {code_coordinator-0.5.556 → code_coordinator-0.5.558}/coord/milestone_gate.py +0 -0
  230. {code_coordinator-0.5.556 → code_coordinator-0.5.558}/coord/milestone_order.py +0 -0
  231. {code_coordinator-0.5.556 → code_coordinator-0.5.558}/coord/mock_author.py +0 -0
  232. {code_coordinator-0.5.556 → code_coordinator-0.5.558}/coord/models.py +0 -0
  233. {code_coordinator-0.5.556 → code_coordinator-0.5.558}/coord/network.py +0 -0
  234. {code_coordinator-0.5.556 → code_coordinator-0.5.558}/coord/new_issue_chat.py +0 -0
  235. {code_coordinator-0.5.556 → code_coordinator-0.5.558}/coord/notifier/__init__.py +0 -0
  236. {code_coordinator-0.5.556 → code_coordinator-0.5.558}/coord/notifier/baseline.py +0 -0
  237. {code_coordinator-0.5.556 → code_coordinator-0.5.558}/coord/notifier/cli.py +0 -0
  238. {code_coordinator-0.5.556 → code_coordinator-0.5.558}/coord/notifier/collect.py +0 -0
  239. {code_coordinator-0.5.556 → code_coordinator-0.5.558}/coord/notifier/digest.py +0 -0
  240. {code_coordinator-0.5.556 → code_coordinator-0.5.558}/coord/notifier/models.py +0 -0
  241. {code_coordinator-0.5.556 → code_coordinator-0.5.558}/coord/notifier/predicate.py +0 -0
  242. {code_coordinator-0.5.556 → code_coordinator-0.5.558}/coord/notifier/service.py +0 -0
  243. {code_coordinator-0.5.556 → code_coordinator-0.5.558}/coord/notifier/store.py +0 -0
  244. {code_coordinator-0.5.556 → code_coordinator-0.5.558}/coord/notifier/transport.py +0 -0
  245. {code_coordinator-0.5.556 → code_coordinator-0.5.558}/coord/notify.py +0 -0
  246. {code_coordinator-0.5.556 → code_coordinator-0.5.558}/coord/openapi.py +0 -0
  247. {code_coordinator-0.5.556 → code_coordinator-0.5.558}/coord/overlap_fence.py +0 -0
  248. {code_coordinator-0.5.556 → code_coordinator-0.5.558}/coord/overlap_predict.py +0 -0
  249. {code_coordinator-0.5.556 → code_coordinator-0.5.558}/coord/parentage.py +0 -0
  250. {code_coordinator-0.5.556 → code_coordinator-0.5.558}/coord/parentage_github.py +0 -0
  251. {code_coordinator-0.5.556 → code_coordinator-0.5.558}/coord/pipeline.py +0 -0
  252. {code_coordinator-0.5.556 → code_coordinator-0.5.558}/coord/plan_parser.py +0 -0
  253. {code_coordinator-0.5.556 → code_coordinator-0.5.558}/coord/plans.py +0 -0
  254. {code_coordinator-0.5.556 → code_coordinator-0.5.558}/coord/platform_paths.py +0 -0
  255. {code_coordinator-0.5.556 → code_coordinator-0.5.558}/coord/portal_bridge.py +0 -0
  256. {code_coordinator-0.5.556 → code_coordinator-0.5.558}/coord/portal_store.py +0 -0
  257. {code_coordinator-0.5.556 → code_coordinator-0.5.558}/coord/portal_sync.py +0 -0
  258. {code_coordinator-0.5.556 → code_coordinator-0.5.558}/coord/pr_body_lint.py +0 -0
  259. {code_coordinator-0.5.556 → code_coordinator-0.5.558}/coord/prereqs.py +0 -0
  260. {code_coordinator-0.5.556 → code_coordinator-0.5.558}/coord/progress.py +0 -0
  261. {code_coordinator-0.5.556 → code_coordinator-0.5.558}/coord/providers/__init__.py +0 -0
  262. {code_coordinator-0.5.556 → code_coordinator-0.5.558}/coord/providers/base.py +0 -0
  263. {code_coordinator-0.5.556 → code_coordinator-0.5.558}/coord/providers/claude.py +0 -0
  264. {code_coordinator-0.5.556 → code_coordinator-0.5.558}/coord/providers/claude_pty.py +0 -0
  265. {code_coordinator-0.5.556 → code_coordinator-0.5.558}/coord/providers/opencode.py +0 -0
  266. {code_coordinator-0.5.556 → code_coordinator-0.5.558}/coord/queue_diagnose.py +0 -0
  267. {code_coordinator-0.5.556 → code_coordinator-0.5.558}/coord/reconcile.py +0 -0
  268. {code_coordinator-0.5.556 → code_coordinator-0.5.558}/coord/reconcile_tick.py +0 -0
  269. {code_coordinator-0.5.556 → code_coordinator-0.5.558}/coord/refine_chat.py +0 -0
  270. {code_coordinator-0.5.556 → code_coordinator-0.5.558}/coord/release_cordon.py +0 -0
  271. {code_coordinator-0.5.556 → code_coordinator-0.5.558}/coord/release_propagate.py +0 -0
  272. {code_coordinator-0.5.556 → code_coordinator-0.5.558}/coord/release_verify.py +0 -0
  273. {code_coordinator-0.5.556 → code_coordinator-0.5.558}/coord/release_window.py +0 -0
  274. {code_coordinator-0.5.556 → code_coordinator-0.5.558}/coord/repo_dormancy.py +0 -0
  275. {code_coordinator-0.5.556 → code_coordinator-0.5.558}/coord/repo_edit.py +0 -0
  276. {code_coordinator-0.5.556 → code_coordinator-0.5.558}/coord/repo_onboard.py +0 -0
  277. {code_coordinator-0.5.556 → code_coordinator-0.5.558}/coord/reports.py +0 -0
  278. {code_coordinator-0.5.556 → code_coordinator-0.5.558}/coord/rest_schema.py +0 -0
  279. {code_coordinator-0.5.556 → code_coordinator-0.5.558}/coord/restart_cmd.py +0 -0
  280. {code_coordinator-0.5.556 → code_coordinator-0.5.558}/coord/revalidate.py +0 -0
  281. {code_coordinator-0.5.556 → code_coordinator-0.5.558}/coord/review.py +0 -0
  282. {code_coordinator-0.5.556 → code_coordinator-0.5.558}/coord/scorecard.py +0 -0
  283. {code_coordinator-0.5.556 → code_coordinator-0.5.558}/coord/self_health.py +0 -0
  284. {code_coordinator-0.5.556 → code_coordinator-0.5.558}/coord/serve_app.py +0 -0
  285. {code_coordinator-0.5.556 → code_coordinator-0.5.558}/coord/skills/coord-dispatch-verbs/SKILL.md +0 -0
  286. {code_coordinator-0.5.556 → code_coordinator-0.5.558}/coord/skills/drive-queue-preflight/SKILL.md +0 -0
  287. {code_coordinator-0.5.556 → code_coordinator-0.5.558}/coord/skills/fleet-restart-safety/SKILL.md +0 -0
  288. {code_coordinator-0.5.556 → code_coordinator-0.5.558}/coord/skills/merge-stuck-triage/SKILL.md +0 -0
  289. {code_coordinator-0.5.556 → code_coordinator-0.5.558}/coord/skills/pipeline-limbo-triage/SKILL.md +0 -0
  290. {code_coordinator-0.5.556 → code_coordinator-0.5.558}/coord/skills/portal-followup/SKILL.md +0 -0
  291. {code_coordinator-0.5.556 → code_coordinator-0.5.558}/coord/skills/release-now/SKILL.md +0 -0
  292. {code_coordinator-0.5.556 → code_coordinator-0.5.558}/coord/skills/review-verdict-recovery/SKILL.md +0 -0
  293. {code_coordinator-0.5.556 → code_coordinator-0.5.558}/coord/skills/tui-quadraui-workflow/SKILL.md +0 -0
  294. {code_coordinator-0.5.556 → code_coordinator-0.5.558}/coord/skills/update-issue/SKILL.md +0 -0
  295. {code_coordinator-0.5.556 → code_coordinator-0.5.558}/coord/smoke.py +0 -0
  296. {code_coordinator-0.5.556 → code_coordinator-0.5.558}/coord/smoke_tags.py +0 -0
  297. {code_coordinator-0.5.556 → code_coordinator-0.5.558}/coord/spend_ceiling.py +0 -0
  298. {code_coordinator-0.5.556 → code_coordinator-0.5.558}/coord/split_work.py +0 -0
  299. {code_coordinator-0.5.556 → code_coordinator-0.5.558}/coord/sql.py +0 -0
  300. {code_coordinator-0.5.556 → code_coordinator-0.5.558}/coord/stage_projection.py +0 -0
  301. {code_coordinator-0.5.556 → code_coordinator-0.5.558}/coord/state.py +0 -0
  302. {code_coordinator-0.5.556 → code_coordinator-0.5.558}/coord/store_migrate.py +0 -0
  303. {code_coordinator-0.5.556 → code_coordinator-0.5.558}/coord/store_parity.py +0 -0
  304. {code_coordinator-0.5.556 → code_coordinator-0.5.558}/coord/templates/deploy-cloudflare.node.yml +0 -0
  305. {code_coordinator-0.5.556 → code_coordinator-0.5.558}/coord/test_author.py +0 -0
  306. {code_coordinator-0.5.556 → code_coordinator-0.5.558}/coord/test_chat.py +0 -0
  307. {code_coordinator-0.5.556 → code_coordinator-0.5.558}/coord/test_orchestrator.py +0 -0
  308. {code_coordinator-0.5.556 → code_coordinator-0.5.558}/coord/test_report.py +0 -0
  309. {code_coordinator-0.5.556 → code_coordinator-0.5.558}/coord/tui_pty_driver.py +0 -0
  310. {code_coordinator-0.5.556 → code_coordinator-0.5.558}/coord/tui_release.py +0 -0
  311. {code_coordinator-0.5.556 → code_coordinator-0.5.558}/coord/uat_checks.py +0 -0
  312. {code_coordinator-0.5.556 → code_coordinator-0.5.558}/coord/usage.py +0 -0
  313. {code_coordinator-0.5.556 → code_coordinator-0.5.558}/coord/usage_limits.py +0 -0
  314. {code_coordinator-0.5.556 → code_coordinator-0.5.558}/coord/usage_rollup.py +0 -0
  315. {code_coordinator-0.5.556 → code_coordinator-0.5.558}/coord/win_native_driver.py +0 -0
  316. {code_coordinator-0.5.556 → code_coordinator-0.5.558}/coord/worker_events.py +0 -0
  317. {code_coordinator-0.5.556 → code_coordinator-0.5.558}/coordinator.example.yml +0 -0
  318. {code_coordinator-0.5.556 → code_coordinator-0.5.558}/deploy/coord-agent.service +0 -0
  319. {code_coordinator-0.5.556 → code_coordinator-0.5.558}/deploy/coord-backup.service +0 -0
  320. {code_coordinator-0.5.556 → code_coordinator-0.5.558}/deploy/coord-backup.timer +0 -0
  321. {code_coordinator-0.5.556 → code_coordinator-0.5.558}/deploy/coord-db-backup.service +0 -0
  322. {code_coordinator-0.5.556 → code_coordinator-0.5.558}/deploy/coord-db-backup.sh +0 -0
  323. {code_coordinator-0.5.556 → code_coordinator-0.5.558}/deploy/coord-db-backup.timer +0 -0
  324. {code_coordinator-0.5.556 → code_coordinator-0.5.558}/deploy/coord-dr-verify.service +0 -0
  325. {code_coordinator-0.5.556 → code_coordinator-0.5.558}/deploy/coord-dr-verify.timer +0 -0
  326. {code_coordinator-0.5.556 → code_coordinator-0.5.558}/deploy/coord-drive-queue.service +0 -0
  327. {code_coordinator-0.5.556 → code_coordinator-0.5.558}/deploy/coord-drive-queue.timer +0 -0
  328. {code_coordinator-0.5.556 → code_coordinator-0.5.558}/deploy/coord-failure-notify.service +0 -0
  329. {code_coordinator-0.5.556 → code_coordinator-0.5.558}/deploy/coord-failure-notify.sh +0 -0
  330. {code_coordinator-0.5.556 → code_coordinator-0.5.558}/deploy/coord-fleet-watchdog.service +0 -0
  331. {code_coordinator-0.5.556 → code_coordinator-0.5.558}/deploy/coord-fleet-watchdog.timer +0 -0
  332. {code_coordinator-0.5.556 → code_coordinator-0.5.558}/deploy/coord-notify.service +0 -0
  333. {code_coordinator-0.5.556 → code_coordinator-0.5.558}/deploy/coord-notify.timer +0 -0
  334. {code_coordinator-0.5.556 → code_coordinator-0.5.558}/deploy/coord-release-propagate.service +0 -0
  335. {code_coordinator-0.5.556 → code_coordinator-0.5.558}/deploy/coord-release-propagate.timer +0 -0
  336. {code_coordinator-0.5.556 → code_coordinator-0.5.558}/deploy/coord-release-window.service +0 -0
  337. {code_coordinator-0.5.556 → code_coordinator-0.5.558}/deploy/coord-release-window.timer +0 -0
  338. {code_coordinator-0.5.556 → code_coordinator-0.5.558}/deploy/coord-serve.service +0 -0
  339. {code_coordinator-0.5.556 → code_coordinator-0.5.558}/deploy/coord-web-dist-build.service +0 -0
  340. {code_coordinator-0.5.556 → code_coordinator-0.5.558}/deploy/coord-web-dist-build.sh +0 -0
  341. {code_coordinator-0.5.556 → code_coordinator-0.5.558}/deploy/coord-web-dist-build.timer +0 -0
  342. {code_coordinator-0.5.556 → code_coordinator-0.5.558}/deploy/coord-web-rollback.sh +0 -0
  343. {code_coordinator-0.5.556 → code_coordinator-0.5.558}/deploy/coord-web.service +0 -0
  344. {code_coordinator-0.5.556 → code_coordinator-0.5.558}/deploy/node-shim.sh +0 -0
  345. {code_coordinator-0.5.556 → code_coordinator-0.5.558}/docs/ADR_COORD_TUI_CI.md +0 -0
  346. {code_coordinator-0.5.556 → code_coordinator-0.5.558}/docs/ADR_COORD_WEB_ACCEPTANCE_SUITE.md +0 -0
  347. {code_coordinator-0.5.556 → code_coordinator-0.5.558}/docs/ADR_COORD_WEB_CI.md +0 -0
  348. {code_coordinator-0.5.556 → code_coordinator-0.5.558}/docs/ADR_COORD_WEB_DIST.md +0 -0
  349. {code_coordinator-0.5.556 → code_coordinator-0.5.558}/docs/ADR_PY_RUST_MIRRORS.md +0 -0
  350. {code_coordinator-0.5.556 → code_coordinator-0.5.558}/docs/AGENT_OPERATIONS.md +0 -0
  351. {code_coordinator-0.5.556 → code_coordinator-0.5.558}/docs/ARCHITECTURE.md +0 -0
  352. {code_coordinator-0.5.556 → code_coordinator-0.5.558}/docs/ARCH_SECURITY_GATES.md +0 -0
  353. {code_coordinator-0.5.556 → code_coordinator-0.5.558}/docs/COCKPIT.md +0 -0
  354. {code_coordinator-0.5.556 → code_coordinator-0.5.558}/docs/CONTROL_CENTER.md +0 -0
  355. {code_coordinator-0.5.556 → code_coordinator-0.5.558}/docs/COST_DISCIPLINE.md +0 -0
  356. {code_coordinator-0.5.556 → code_coordinator-0.5.558}/docs/CROSS_PLATFORM.md +0 -0
  357. {code_coordinator-0.5.556 → code_coordinator-0.5.558}/docs/CUSTOMER_FACING_APPS.md +0 -0
  358. {code_coordinator-0.5.556 → code_coordinator-0.5.558}/docs/CUSTOMER_PORTAL.md +0 -0
  359. {code_coordinator-0.5.556 → code_coordinator-0.5.558}/docs/DATA_STORE_SELECTION.md +0 -0
  360. {code_coordinator-0.5.556 → code_coordinator-0.5.558}/docs/DISASTER_RECOVERY.md +0 -0
  361. {code_coordinator-0.5.556 → code_coordinator-0.5.558}/docs/DRIVE_QUEUE.md +0 -0
  362. {code_coordinator-0.5.556 → code_coordinator-0.5.558}/docs/EPHEMERAL_WORKERS.md +0 -0
  363. {code_coordinator-0.5.556 → code_coordinator-0.5.558}/docs/FORGE_MIGRATION.md +0 -0
  364. {code_coordinator-0.5.556 → code_coordinator-0.5.558}/docs/GRAPHIFY_SETUP.md +0 -0
  365. {code_coordinator-0.5.556 → code_coordinator-0.5.558}/docs/ISSUE_GUIDANCE.md +0 -0
  366. {code_coordinator-0.5.556 → code_coordinator-0.5.558}/docs/MAC_MINI.md +0 -0
  367. {code_coordinator-0.5.556 → code_coordinator-0.5.558}/docs/MERGE_AUTO_DRAIN_TRUST_BAR.md +0 -0
  368. {code_coordinator-0.5.556 → code_coordinator-0.5.558}/docs/NOTIFIER.md +0 -0
  369. {code_coordinator-0.5.556 → code_coordinator-0.5.558}/docs/OPENCODE_VERIFICATION.md +0 -0
  370. {code_coordinator-0.5.556 → code_coordinator-0.5.558}/docs/OPERATING_GOTCHAS.md +0 -0
  371. {code_coordinator-0.5.556 → code_coordinator-0.5.558}/docs/OPERATOR_GUIDES.md +0 -0
  372. {code_coordinator-0.5.556 → code_coordinator-0.5.558}/docs/ORACLE_LOOP.md +0 -0
  373. {code_coordinator-0.5.556 → code_coordinator-0.5.558}/docs/PHONE_WEBAPP.md +0 -0
  374. {code_coordinator-0.5.556 → code_coordinator-0.5.558}/docs/PIPELINE_V2.md +0 -0
  375. {code_coordinator-0.5.556 → code_coordinator-0.5.558}/docs/PLATFORM_EVOLUTION.md +0 -0
  376. {code_coordinator-0.5.556 → code_coordinator-0.5.558}/docs/SECOND_BACKEND.md +0 -0
  377. {code_coordinator-0.5.556 → code_coordinator-0.5.558}/docs/STORE_SERVICE.md +0 -0
  378. {code_coordinator-0.5.556 → code_coordinator-0.5.558}/docs/TEST_FIRST_BUG_LANE.md +0 -0
  379. {code_coordinator-0.5.556 → code_coordinator-0.5.558}/docs/WEB_CONTROL_CENTER.md +0 -0
  380. {code_coordinator-0.5.556 → code_coordinator-0.5.558}/docs/WSL_WINDOWS_WORKER.md +0 -0
  381. {code_coordinator-0.5.556 → code_coordinator-0.5.558}/docs/mocks/web/README.md +0 -0
  382. {code_coordinator-0.5.556 → code_coordinator-0.5.558}/docs/mocks/web/_tokens.css +0 -0
  383. {code_coordinator-0.5.556 → code_coordinator-0.5.558}/docs/mocks/web/issue-detail.html +0 -0
  384. {code_coordinator-0.5.556 → code_coordinator-0.5.558}/docs/mocks/web/pipeline-narrow.html +0 -0
  385. {code_coordinator-0.5.556 → code_coordinator-0.5.558}/docs/mocks/web/pipeline-wide.html +0 -0
  386. {code_coordinator-0.5.556 → code_coordinator-0.5.558}/graphify-out/.gitignore +0 -0
  387. {code_coordinator-0.5.556 → code_coordinator-0.5.558}/install-agent.sh +0 -0
  388. {code_coordinator-0.5.556 → code_coordinator-0.5.558}/pyproject.toml +0 -0
  389. {code_coordinator-0.5.556 → code_coordinator-0.5.558}/scripts/audit_review_verdict_overrides.py +0 -0
  390. {code_coordinator-0.5.556 → code_coordinator-0.5.558}/scripts/azure-workers/bootstrap-shared.sh +0 -0
  391. {code_coordinator-0.5.556 → code_coordinator-0.5.558}/scripts/azure-workers/build-worker-image.sh +0 -0
  392. {code_coordinator-0.5.556 → code_coordinator-0.5.558}/scripts/azure-workers/coordinator-machine.py +0 -0
  393. {code_coordinator-0.5.556 → code_coordinator-0.5.558}/scripts/azure-workers/dr-down.sh +0 -0
  394. {code_coordinator-0.5.556 → code_coordinator-0.5.558}/scripts/azure-workers/dr-up.sh +0 -0
  395. {code_coordinator-0.5.556 → code_coordinator-0.5.558}/scripts/azure-workers/epic-down.sh +0 -0
  396. {code_coordinator-0.5.556 → code_coordinator-0.5.558}/scripts/azure-workers/epic-up.sh +0 -0
  397. {code_coordinator-0.5.556 → code_coordinator-0.5.558}/scripts/azure-workers/preflight.sh +0 -0
  398. {code_coordinator-0.5.556 → code_coordinator-0.5.558}/scripts/azure-workers/provision-server.sh +0 -0
  399. {code_coordinator-0.5.556 → code_coordinator-0.5.558}/scripts/azure-workers/provision-worker.sh +0 -0
  400. {code_coordinator-0.5.556 → code_coordinator-0.5.558}/scripts/azure-workers/scrub-and-generalize.sh +0 -0
  401. {code_coordinator-0.5.556 → code_coordinator-0.5.558}/scripts/azure-workers/tailnet-acl.hujson +0 -0
  402. {code_coordinator-0.5.556 → code_coordinator-0.5.558}/scripts/azure-workers/throwaway-vm.sh +0 -0
  403. {code_coordinator-0.5.556 → code_coordinator-0.5.558}/scripts/azure-workers/verify-github-token.sh +0 -0
  404. {code_coordinator-0.5.556 → code_coordinator-0.5.558}/scripts/check_gh_argv_containment.py +0 -0
  405. {code_coordinator-0.5.556 → code_coordinator-0.5.558}/scripts/codegen.py +0 -0
  406. {code_coordinator-0.5.556 → code_coordinator-0.5.558}/scripts/coord-test-runner.sh +0 -0
  407. {code_coordinator-0.5.556 → code_coordinator-0.5.558}/scripts/coord-tui-scaffold/.github/coord-ci-acceptance.yml +0 -0
  408. {code_coordinator-0.5.556 → code_coordinator-0.5.558}/scripts/coord-tui-scaffold/.github/workflows/cargo-test.yml +0 -0
  409. {code_coordinator-0.5.556 → code_coordinator-0.5.558}/scripts/coord-tui-scaffold/.github/workflows/codegen-drift.yml +0 -0
  410. {code_coordinator-0.5.556 → code_coordinator-0.5.558}/scripts/coord-tui-scaffold/CLAUDE.md +0 -0
  411. {code_coordinator-0.5.556 → code_coordinator-0.5.558}/scripts/coord-venv-rollback.sh +0 -0
  412. {code_coordinator-0.5.556 → code_coordinator-0.5.558}/scripts/drive-batch.sh +0 -0
  413. {code_coordinator-0.5.556 → code_coordinator-0.5.558}/scripts/extract-coord-tui.sh +0 -0
  414. {code_coordinator-0.5.556 → code_coordinator-0.5.558}/scripts/fleet_watchdog.py +0 -0
  415. {code_coordinator-0.5.556 → code_coordinator-0.5.558}/scripts/gen_board_fixture.py +0 -0
  416. {code_coordinator-0.5.556 → code_coordinator-0.5.558}/scripts/gen_mock_index.py +0 -0
  417. {code_coordinator-0.5.556 → code_coordinator-0.5.558}/scripts/lib/provision-core.sh +0 -0
  418. {code_coordinator-0.5.556 → code_coordinator-0.5.558}/scripts/next_release_tag.py +0 -0
  419. {code_coordinator-0.5.556 → code_coordinator-0.5.558}/scripts/provision-machine.sh +0 -0
  420. {code_coordinator-0.5.556 → code_coordinator-0.5.558}/scripts/run_tests_in_populated_home.sh +0 -0
  421. {code_coordinator-0.5.556 → code_coordinator-0.5.558}/scripts/run_tests_without_gh.sh +0 -0
  422. {code_coordinator-0.5.556 → code_coordinator-0.5.558}/scripts/setup-macmini.sh +0 -0
  423. {code_coordinator-0.5.556 → code_coordinator-0.5.558}/scripts/smoke_437_interactive.py +0 -0
  424. {code_coordinator-0.5.556 → code_coordinator-0.5.558}/scripts/verify-provision-noble.sh +0 -0
  425. {code_coordinator-0.5.556 → code_coordinator-0.5.558}/scripts/verify_878_review_capture.py +0 -0
  426. {code_coordinator-0.5.556 → code_coordinator-0.5.558}/scripts/verify_release_published.py +0 -0
  427. {code_coordinator-0.5.556 → code_coordinator-0.5.558}/scripts/verify_release_wheel.py +0 -0
  428. {code_coordinator-0.5.556 → code_coordinator-0.5.558}/setup.cfg +0 -0
  429. {code_coordinator-0.5.556 → code_coordinator-0.5.558}/tests/SMOKE_SET.md +0 -0
  430. {code_coordinator-0.5.556 → code_coordinator-0.5.558}/tests/__init__.py +0 -0
  431. {code_coordinator-0.5.556 → code_coordinator-0.5.558}/tests/acceptance/ms-37/conftest.py +0 -0
  432. {code_coordinator-0.5.556 → code_coordinator-0.5.558}/tests/acceptance/ms-37/contract.md +0 -0
  433. {code_coordinator-0.5.556 → code_coordinator-0.5.558}/tests/acceptance/ms-37/manifest.yml +0 -0
  434. {code_coordinator-0.5.556 → code_coordinator-0.5.558}/tests/acceptance/ms-37/test_usage_cli_1115.py +0 -0
  435. {code_coordinator-0.5.556 → code_coordinator-0.5.558}/tests/acceptance/ms-37/test_usage_core_1118.py +0 -0
  436. {code_coordinator-0.5.556 → code_coordinator-0.5.558}/tests/acceptance/ms-51/contract.md +0 -0
  437. {code_coordinator-0.5.556 → code_coordinator-0.5.558}/tests/acceptance/ms-51/home-active-extended.spec.ts +0 -0
  438. {code_coordinator-0.5.556 → code_coordinator-0.5.558}/tests/acceptance/ms-51/home-active.spec.ts +0 -0
  439. {code_coordinator-0.5.556 → code_coordinator-0.5.558}/tests/acceptance/ms-51/manifest.yml +0 -0
  440. {code_coordinator-0.5.556 → code_coordinator-0.5.558}/tests/acceptance/ms-51/mocks/home-active.html +0 -0
  441. {code_coordinator-0.5.556 → code_coordinator-0.5.558}/tests/acceptance/ms-51/tsconfig.json +0 -0
  442. {code_coordinator-0.5.556 → code_coordinator-0.5.558}/tests/acceptance/ms-example/mocks/home-active.html +0 -0
  443. {code_coordinator-0.5.556 → code_coordinator-0.5.558}/tests/backends.py +0 -0
  444. {code_coordinator-0.5.556 → code_coordinator-0.5.558}/tests/conftest.py +0 -0
  445. {code_coordinator-0.5.556 → code_coordinator-0.5.558}/tests/fixtures/board-pipeline-basic.json +0 -0
  446. {code_coordinator-0.5.556 → code_coordinator-0.5.558}/tests/fixtures/board-pipeline-terminal-gates.json +0 -0
  447. {code_coordinator-0.5.556 → code_coordinator-0.5.558}/tests/fixtures/opencode_run_failure_sample.jsonl +0 -0
  448. {code_coordinator-0.5.556 → code_coordinator-0.5.558}/tests/fixtures/opencode_run_length_sample.jsonl +0 -0
  449. {code_coordinator-0.5.556 → code_coordinator-0.5.558}/tests/fixtures/opencode_run_sample.jsonl +0 -0
  450. {code_coordinator-0.5.556 → code_coordinator-0.5.558}/tests/fixtures/playwright/all_pass.json +0 -0
  451. {code_coordinator-0.5.556 → code_coordinator-0.5.558}/tests/fixtures/playwright/global_setup_crash.json +0 -0
  452. {code_coordinator-0.5.556 → code_coordinator-0.5.558}/tests/fixtures/playwright/mixed_fail.json +0 -0
  453. {code_coordinator-0.5.556 → code_coordinator-0.5.558}/tests/fixtures/playwright/retry_then_pass.json +0 -0
  454. {code_coordinator-0.5.556 → code_coordinator-0.5.558}/tests/fixtures/playwright/retry_then_pass.junit.xml +0 -0
  455. {code_coordinator-0.5.556 → code_coordinator-0.5.558}/tests/fixtures/playwright/skip.json +0 -0
  456. {code_coordinator-0.5.556 → code_coordinator-0.5.558}/tests/fixtures/playwright/truncated.json +0 -0
  457. {code_coordinator-0.5.556 → code_coordinator-0.5.558}/tests/fixtures/test_report/cargo_compile_error.txt +0 -0
  458. {code_coordinator-0.5.556 → code_coordinator-0.5.558}/tests/fixtures/test_report/cargo_multi_target_failures.txt +0 -0
  459. {code_coordinator-0.5.556 → code_coordinator-0.5.558}/tests/fixtures/test_report/cargo_no_parseable_failures.txt +0 -0
  460. {code_coordinator-0.5.556 → code_coordinator-0.5.558}/tests/fixtures/test_report/pytest_collection_error.txt +0 -0
  461. {code_coordinator-0.5.556 → code_coordinator-0.5.558}/tests/fixtures/test_report/pytest_error_log_record.txt +0 -0
  462. {code_coordinator-0.5.556 → code_coordinator-0.5.558}/tests/fixtures/test_report/pytest_error_string_in_body.txt +0 -0
  463. {code_coordinator-0.5.556 → code_coordinator-0.5.558}/tests/fixtures/test_report/pytest_internal_error.txt +0 -0
  464. {code_coordinator-0.5.556 → code_coordinator-0.5.558}/tests/fixtures/test_report/pytest_mixed_failures.txt +0 -0
  465. {code_coordinator-0.5.556 → code_coordinator-0.5.558}/tests/fixtures/test_report/pytest_no_parseable_failures.txt +0 -0
  466. {code_coordinator-0.5.556 → code_coordinator-0.5.558}/tests/test_acceptance.py +0 -0
  467. {code_coordinator-0.5.556 → code_coordinator-0.5.558}/tests/test_acceptance_drivers.py +0 -0
  468. {code_coordinator-0.5.556 → code_coordinator-0.5.558}/tests/test_agent.py +0 -0
  469. {code_coordinator-0.5.556 → code_coordinator-0.5.558}/tests/test_agent_api_error.py +0 -0
  470. {code_coordinator-0.5.556 → code_coordinator-0.5.558}/tests/test_agent_app.py +0 -0
  471. {code_coordinator-0.5.556 → code_coordinator-0.5.558}/tests/test_agent_branch_base.py +0 -0
  472. {code_coordinator-0.5.556 → code_coordinator-0.5.558}/tests/test_agent_branch_capture.py +0 -0
  473. {code_coordinator-0.5.556 → code_coordinator-0.5.558}/tests/test_agent_config_free_1712.py +0 -0
  474. {code_coordinator-0.5.556 → code_coordinator-0.5.558}/tests/test_agent_deploy_units_endpoint.py +0 -0
  475. {code_coordinator-0.5.556 → code_coordinator-0.5.558}/tests/test_agent_dirty_worktree.py +0 -0
  476. {code_coordinator-0.5.556 → code_coordinator-0.5.558}/tests/test_agent_drive_queue_reconcile_2373.py +0 -0
  477. {code_coordinator-0.5.556 → code_coordinator-0.5.558}/tests/test_agent_graph_self_heal.py +0 -0
  478. {code_coordinator-0.5.556 → code_coordinator-0.5.558}/tests/test_agent_health_h3.py +0 -0
  479. {code_coordinator-0.5.556 → code_coordinator-0.5.558}/tests/test_agent_idle_restart.py +0 -0
  480. {code_coordinator-0.5.556 → code_coordinator-0.5.558}/tests/test_agent_push_failure.py +0 -0
  481. {code_coordinator-0.5.556 → code_coordinator-0.5.558}/tests/test_agent_reap.py +0 -0
  482. {code_coordinator-0.5.556 → code_coordinator-0.5.558}/tests/test_agent_repos_and_pull.py +0 -0
  483. {code_coordinator-0.5.556 → code_coordinator-0.5.558}/tests/test_agent_restart_services_endpoint.py +0 -0
  484. {code_coordinator-0.5.556 → code_coordinator-0.5.558}/tests/test_agent_skills_self_heal.py +0 -0
  485. {code_coordinator-0.5.556 → code_coordinator-0.5.558}/tests/test_agent_startup_diagnostics.py +0 -0
  486. {code_coordinator-0.5.556 → code_coordinator-0.5.558}/tests/test_agent_update.py +0 -0
  487. {code_coordinator-0.5.556 → code_coordinator-0.5.558}/tests/test_agent_update_bluegreen.py +0 -0
  488. {code_coordinator-0.5.556 → code_coordinator-0.5.558}/tests/test_agent_usage_limit.py +0 -0
  489. {code_coordinator-0.5.556 → code_coordinator-0.5.558}/tests/test_agent_zero_commit.py +0 -0
  490. {code_coordinator-0.5.556 → code_coordinator-0.5.558}/tests/test_ambient_home_isolation.py +0 -0
  491. {code_coordinator-0.5.556 → code_coordinator-0.5.558}/tests/test_approve_capability_reroute_3241.py +0 -0
  492. {code_coordinator-0.5.556 → code_coordinator-0.5.558}/tests/test_approve_dependency_busy_2804.py +0 -0
  493. {code_coordinator-0.5.556 → code_coordinator-0.5.558}/tests/test_approve_reject_plan.py +0 -0
  494. {code_coordinator-0.5.556 → code_coordinator-0.5.558}/tests/test_approve_usage_gate.py +0 -0
  495. {code_coordinator-0.5.556 → code_coordinator-0.5.558}/tests/test_approved_work_2532.py +0 -0
  496. {code_coordinator-0.5.556 → code_coordinator-0.5.558}/tests/test_approved_work_2996.py +0 -0
  497. {code_coordinator-0.5.556 → code_coordinator-0.5.558}/tests/test_assignment_already_recorded_daemon.py +0 -0
  498. {code_coordinator-0.5.556 → code_coordinator-0.5.558}/tests/test_audit_log.py +0 -0
  499. {code_coordinator-0.5.556 → code_coordinator-0.5.558}/tests/test_audit_outcome.py +0 -0
  500. {code_coordinator-0.5.556 → code_coordinator-0.5.558}/tests/test_audit_query.py +0 -0
  501. {code_coordinator-0.5.556 → code_coordinator-0.5.558}/tests/test_auto_loop.py +0 -0
  502. {code_coordinator-0.5.556 → code_coordinator-0.5.558}/tests/test_auto_release_publish_2035.py +0 -0
  503. {code_coordinator-0.5.556 → code_coordinator-0.5.558}/tests/test_backend_selection.py +0 -0
  504. {code_coordinator-0.5.556 → code_coordinator-0.5.558}/tests/test_backup.py +0 -0
  505. {code_coordinator-0.5.556 → code_coordinator-0.5.558}/tests/test_base_checkout_restore.py +0 -0
  506. {code_coordinator-0.5.556 → code_coordinator-0.5.558}/tests/test_block_log.py +0 -0
  507. {code_coordinator-0.5.556 → code_coordinator-0.5.558}/tests/test_board_cap_762.py +0 -0
  508. {code_coordinator-0.5.556 → code_coordinator-0.5.558}/tests/test_board_fixture.py +0 -0
  509. {code_coordinator-0.5.556 → code_coordinator-0.5.558}/tests/test_board_read_path.py +0 -0
  510. {code_coordinator-0.5.556 → code_coordinator-0.5.558}/tests/test_board_schema.py +0 -0
  511. {code_coordinator-0.5.556 → code_coordinator-0.5.558}/tests/test_board_service.py +0 -0
  512. {code_coordinator-0.5.556 → code_coordinator-0.5.558}/tests/test_board_state.py +0 -0
  513. {code_coordinator-0.5.556 → code_coordinator-0.5.558}/tests/test_board_wire.py +0 -0
  514. {code_coordinator-0.5.556 → code_coordinator-0.5.558}/tests/test_brain.py +0 -0
  515. {code_coordinator-0.5.556 → code_coordinator-0.5.558}/tests/test_branch_model.py +0 -0
  516. {code_coordinator-0.5.556 → code_coordinator-0.5.558}/tests/test_bug_intake.py +0 -0
  517. {code_coordinator-0.5.556 → code_coordinator-0.5.558}/tests/test_build_worker_image_env_update.py +0 -0
  518. {code_coordinator-0.5.556 → code_coordinator-0.5.558}/tests/test_cargo_cache.py +0 -0
  519. {code_coordinator-0.5.556 → code_coordinator-0.5.558}/tests/test_check_gh_argv_containment.py +0 -0
  520. {code_coordinator-0.5.556 → code_coordinator-0.5.558}/tests/test_ci_acceptance_gate_1950.py +0 -0
  521. {code_coordinator-0.5.556 → code_coordinator-0.5.558}/tests/test_ci_fix.py +0 -0
  522. {code_coordinator-0.5.556 → code_coordinator-0.5.558}/tests/test_ci_github.py +0 -0
  523. {code_coordinator-0.5.556 → code_coordinator-0.5.558}/tests/test_ci_gitlab.py +0 -0
  524. {code_coordinator-0.5.556 → code_coordinator-0.5.558}/tests/test_ci_parity_2091.py +0 -0
  525. {code_coordinator-0.5.556 → code_coordinator-0.5.558}/tests/test_ci_store.py +0 -0
  526. {code_coordinator-0.5.556 → code_coordinator-0.5.558}/tests/test_claim.py +0 -0
  527. {code_coordinator-0.5.556 → code_coordinator-0.5.558}/tests/test_claude_md_budget.py +0 -0
  528. {code_coordinator-0.5.556 → code_coordinator-0.5.558}/tests/test_claude_setup_token.py +0 -0
  529. {code_coordinator-0.5.556 → code_coordinator-0.5.558}/tests/test_cli_acceptance.py +0 -0
  530. {code_coordinator-0.5.556 → code_coordinator-0.5.558}/tests/test_cli_assign.py +0 -0
  531. {code_coordinator-0.5.556 → code_coordinator-0.5.558}/tests/test_cli_assign_interactive_oracle_gate.py +0 -0
  532. {code_coordinator-0.5.556 → code_coordinator-0.5.558}/tests/test_cli_assign_interactive_remote.py +0 -0
  533. {code_coordinator-0.5.556 → code_coordinator-0.5.558}/tests/test_cli_assign_provider.py +0 -0
  534. {code_coordinator-0.5.556 → code_coordinator-0.5.558}/tests/test_cli_assign_repo_drift_2219.py +0 -0
  535. {code_coordinator-0.5.556 → code_coordinator-0.5.558}/tests/test_cli_audit.py +0 -0
  536. {code_coordinator-0.5.556 → code_coordinator-0.5.558}/tests/test_cli_chat_continue.py +0 -0
  537. {code_coordinator-0.5.556 → code_coordinator-0.5.558}/tests/test_cli_ci.py +0 -0
  538. {code_coordinator-0.5.556 → code_coordinator-0.5.558}/tests/test_cli_codegen.py +0 -0
  539. {code_coordinator-0.5.556 → code_coordinator-0.5.558}/tests/test_cli_decide.py +0 -0
  540. {code_coordinator-0.5.556 → code_coordinator-0.5.558}/tests/test_cli_diagnose_capability_rules.py +0 -0
  541. {code_coordinator-0.5.556 → code_coordinator-0.5.558}/tests/test_cli_diagnose_config_provenance.py +0 -0
  542. {code_coordinator-0.5.556 → code_coordinator-0.5.558}/tests/test_cli_diagnose_forge_availability.py +0 -0
  543. {code_coordinator-0.5.556 → code_coordinator-0.5.558}/tests/test_cli_diagnose_graph.py +0 -0
  544. {code_coordinator-0.5.556 → code_coordinator-0.5.558}/tests/test_cli_diagnose_self.py +0 -0
  545. {code_coordinator-0.5.556 → code_coordinator-0.5.558}/tests/test_cli_diagnose_test_coverage.py +0 -0
  546. {code_coordinator-0.5.556 → code_coordinator-0.5.558}/tests/test_cli_doctor.py +0 -0
  547. {code_coordinator-0.5.556 → code_coordinator-0.5.558}/tests/test_cli_doctor_config_free_1801.py +0 -0
  548. {code_coordinator-0.5.556 → code_coordinator-0.5.558}/tests/test_cli_doctor_config_mismatch_1712.py +0 -0
  549. {code_coordinator-0.5.556 → code_coordinator-0.5.558}/tests/test_cli_doctor_store_backend_3084.py +0 -0
  550. {code_coordinator-0.5.556 → code_coordinator-0.5.558}/tests/test_cli_drive.py +0 -0
  551. {code_coordinator-0.5.556 → code_coordinator-0.5.558}/tests/test_cli_drive_queue.py +0 -0
  552. {code_coordinator-0.5.556 → code_coordinator-0.5.558}/tests/test_cli_escalate.py +0 -0
  553. {code_coordinator-0.5.556 → code_coordinator-0.5.558}/tests/test_cli_fix_headless_review.py +0 -0
  554. {code_coordinator-0.5.556 → code_coordinator-0.5.558}/tests/test_cli_gate_a.py +0 -0
  555. {code_coordinator-0.5.556 → code_coordinator-0.5.558}/tests/test_cli_install_drift.py +0 -0
  556. {code_coordinator-0.5.556 → code_coordinator-0.5.558}/tests/test_cli_install_skills.py +0 -0
  557. {code_coordinator-0.5.556 → code_coordinator-0.5.558}/tests/test_cli_issue_comment.py +0 -0
  558. {code_coordinator-0.5.556 → code_coordinator-0.5.558}/tests/test_cli_issue_create_label.py +0 -0
  559. {code_coordinator-0.5.556 → code_coordinator-0.5.558}/tests/test_cli_issue_reopen.py +0 -0
  560. {code_coordinator-0.5.556 → code_coordinator-0.5.558}/tests/test_cli_issue_view_list.py +0 -0
  561. {code_coordinator-0.5.556 → code_coordinator-0.5.558}/tests/test_cli_issues.py +0 -0
  562. {code_coordinator-0.5.556 → code_coordinator-0.5.558}/tests/test_cli_merge.py +0 -0
  563. {code_coordinator-0.5.556 → code_coordinator-0.5.558}/tests/test_cli_milestone_assign.py +0 -0
  564. {code_coordinator-0.5.556 → code_coordinator-0.5.558}/tests/test_cli_milestone_capture.py +0 -0
  565. {code_coordinator-0.5.556 → code_coordinator-0.5.558}/tests/test_cli_milestone_chat_add_child.py +0 -0
  566. {code_coordinator-0.5.556 → code_coordinator-0.5.558}/tests/test_cli_milestone_dispatch.py +0 -0
  567. {code_coordinator-0.5.556 → code_coordinator-0.5.558}/tests/test_cli_milestone_gate_b.py +0 -0
  568. {code_coordinator-0.5.556 → code_coordinator-0.5.558}/tests/test_cli_milestone_gate_c.py +0 -0
  569. {code_coordinator-0.5.556 → code_coordinator-0.5.558}/tests/test_cli_milestone_order.py +0 -0
  570. {code_coordinator-0.5.556 → code_coordinator-0.5.558}/tests/test_cli_milestone_remove_and_issue_close.py +0 -0
  571. {code_coordinator-0.5.556 → code_coordinator-0.5.558}/tests/test_cli_milestone_ship.py +0 -0
  572. {code_coordinator-0.5.556 → code_coordinator-0.5.558}/tests/test_cli_network.py +0 -0
  573. {code_coordinator-0.5.556 → code_coordinator-0.5.558}/tests/test_cli_new_issue_chat.py +0 -0
  574. {code_coordinator-0.5.556 → code_coordinator-0.5.558}/tests/test_cli_plans.py +0 -0
  575. {code_coordinator-0.5.556 → code_coordinator-0.5.558}/tests/test_cli_portal.py +0 -0
  576. {code_coordinator-0.5.556 → code_coordinator-0.5.558}/tests/test_cli_pr.py +0 -0
  577. {code_coordinator-0.5.556 → code_coordinator-0.5.558}/tests/test_cli_pull_artifact.py +0 -0
  578. {code_coordinator-0.5.556 → code_coordinator-0.5.558}/tests/test_cli_queue.py +0 -0
  579. {code_coordinator-0.5.556 → code_coordinator-0.5.558}/tests/test_cli_reattach_sessions.py +0 -0
  580. {code_coordinator-0.5.556 → code_coordinator-0.5.558}/tests/test_cli_refine_board.py +0 -0
  581. {code_coordinator-0.5.556 → code_coordinator-0.5.558}/tests/test_cli_release_preflight.py +0 -0
  582. {code_coordinator-0.5.556 → code_coordinator-0.5.558}/tests/test_cli_release_propagate.py +0 -0
  583. {code_coordinator-0.5.556 → code_coordinator-0.5.558}/tests/test_cli_release_window.py +0 -0
  584. {code_coordinator-0.5.556 → code_coordinator-0.5.558}/tests/test_cli_repo_2220.py +0 -0
  585. {code_coordinator-0.5.556 → code_coordinator-0.5.558}/tests/test_cli_review_test_author_tracking_epic_2639.py +0 -0
  586. {code_coordinator-0.5.556 → code_coordinator-0.5.558}/tests/test_cli_scorecard.py +0 -0
  587. {code_coordinator-0.5.556 → code_coordinator-0.5.558}/tests/test_cli_serve_store_backend_3084.py +0 -0
  588. {code_coordinator-0.5.556 → code_coordinator-0.5.558}/tests/test_cli_set_review_findings.py +0 -0
  589. {code_coordinator-0.5.556 → code_coordinator-0.5.558}/tests/test_cli_status_advisory_terminal.py +0 -0
  590. {code_coordinator-0.5.556 → code_coordinator-0.5.558}/tests/test_cli_status_contested_tag.py +0 -0
  591. {code_coordinator-0.5.556 → code_coordinator-0.5.558}/tests/test_cli_status_invariant_alarms.py +0 -0
  592. {code_coordinator-0.5.556 → code_coordinator-0.5.558}/tests/test_cli_status_machine_fault.py +0 -0
  593. {code_coordinator-0.5.556 → code_coordinator-0.5.558}/tests/test_cli_status_merge_queue.py +0 -0
  594. {code_coordinator-0.5.556 → code_coordinator-0.5.558}/tests/test_cli_status_provider.py +0 -0
  595. {code_coordinator-0.5.556 → code_coordinator-0.5.558}/tests/test_cli_status_retried_3340.py +0 -0
  596. {code_coordinator-0.5.556 → code_coordinator-0.5.558}/tests/test_cli_status_review_finalizing.py +0 -0
  597. {code_coordinator-0.5.556 → code_coordinator-0.5.558}/tests/test_cli_status_supervisor_3366.py +0 -0
  598. {code_coordinator-0.5.556 → code_coordinator-0.5.558}/tests/test_cli_status_test_failed_tag.py +0 -0
  599. {code_coordinator-0.5.556 → code_coordinator-0.5.558}/tests/test_cli_status_usage_limit.py +0 -0
  600. {code_coordinator-0.5.556 → code_coordinator-0.5.558}/tests/test_cli_sync_comments_873.py +0 -0
  601. {code_coordinator-0.5.556 → code_coordinator-0.5.558}/tests/test_cli_test_plan.py +0 -0
  602. {code_coordinator-0.5.556 → code_coordinator-0.5.558}/tests/test_cli_track.py +0 -0
  603. {code_coordinator-0.5.556 → code_coordinator-0.5.558}/tests/test_cli_tui_update.py +0 -0
  604. {code_coordinator-0.5.556 → code_coordinator-0.5.558}/tests/test_cli_wait.py +0 -0
  605. {code_coordinator-0.5.556 → code_coordinator-0.5.558}/tests/test_client.py +0 -0
  606. {code_coordinator-0.5.556 → code_coordinator-0.5.558}/tests/test_client_base_install.py +0 -0
  607. {code_coordinator-0.5.556 → code_coordinator-0.5.558}/tests/test_client_config_cache_atomic_3052.py +0 -0
  608. {code_coordinator-0.5.556 → code_coordinator-0.5.558}/tests/test_client_resource_migration_1946.py +0 -0
  609. {code_coordinator-0.5.556 → code_coordinator-0.5.558}/tests/test_commands_common.py +0 -0
  610. {code_coordinator-0.5.556 → code_coordinator-0.5.558}/tests/test_comments.py +0 -0
  611. {code_coordinator-0.5.556 → code_coordinator-0.5.558}/tests/test_completion_summary.py +0 -0
  612. {code_coordinator-0.5.556 → code_coordinator-0.5.558}/tests/test_config.py +0 -0
  613. {code_coordinator-0.5.556 → code_coordinator-0.5.558}/tests/test_config_acceptance.py +0 -0
  614. {code_coordinator-0.5.556 → code_coordinator-0.5.558}/tests/test_config_audit.py +0 -0
  615. {code_coordinator-0.5.556 → code_coordinator-0.5.558}/tests/test_config_drift_check.py +0 -0
  616. {code_coordinator-0.5.556 → code_coordinator-0.5.558}/tests/test_config_effective.py +0 -0
  617. {code_coordinator-0.5.556 → code_coordinator-0.5.558}/tests/test_config_pricing.py +0 -0
  618. {code_coordinator-0.5.556 → code_coordinator-0.5.558}/tests/test_config_snapshot_noncanonical_2208.py +0 -0
  619. {code_coordinator-0.5.556 → code_coordinator-0.5.558}/tests/test_config_usage_gate.py +0 -0
  620. {code_coordinator-0.5.556 → code_coordinator-0.5.558}/tests/test_confirm_test.py +0 -0
  621. {code_coordinator-0.5.556 → code_coordinator-0.5.558}/tests/test_conflict_fix.py +0 -0
  622. {code_coordinator-0.5.556 → code_coordinator-0.5.558}/tests/test_conflict_fix_semantic.py +0 -0
  623. {code_coordinator-0.5.556 → code_coordinator-0.5.558}/tests/test_coord_log_daemon_fallback_2547.py +0 -0
  624. {code_coordinator-0.5.556 → code_coordinator-0.5.558}/tests/test_coord_test.py +0 -0
  625. {code_coordinator-0.5.556 → code_coordinator-0.5.558}/tests/test_coord_test_runner_acceptance_toolchain_2936.py +0 -0
  626. {code_coordinator-0.5.556 → code_coordinator-0.5.558}/tests/test_coord_test_runner_baseline.py +0 -0
  627. {code_coordinator-0.5.556 → code_coordinator-0.5.558}/tests/test_coord_test_runner_populated_home.py +0 -0
  628. {code_coordinator-0.5.556 → code_coordinator-0.5.558}/tests/test_coord_test_runner_routing.py +0 -0
  629. {code_coordinator-0.5.556 → code_coordinator-0.5.558}/tests/test_coord_test_runner_toolchain.py +0 -0
  630. {code_coordinator-0.5.556 → code_coordinator-0.5.558}/tests/test_coord_uat.py +0 -0
  631. {code_coordinator-0.5.556 → code_coordinator-0.5.558}/tests/test_coord_web_sse_restart_live.py +0 -0
  632. {code_coordinator-0.5.556 → code_coordinator-0.5.558}/tests/test_coordinator_machine.py +0 -0
  633. {code_coordinator-0.5.556 → code_coordinator-0.5.558}/tests/test_cross_platform_imports.py +0 -0
  634. {code_coordinator-0.5.556 → code_coordinator-0.5.558}/tests/test_dao.py +0 -0
  635. {code_coordinator-0.5.556 → code_coordinator-0.5.558}/tests/test_dashboard.py +0 -0
  636. {code_coordinator-0.5.556 → code_coordinator-0.5.558}/tests/test_dashboard_api.py +0 -0
  637. {code_coordinator-0.5.556 → code_coordinator-0.5.558}/tests/test_dashboard_fixture.py +0 -0
  638. {code_coordinator-0.5.556 → code_coordinator-0.5.558}/tests/test_dashboard_server.py +0 -0
  639. {code_coordinator-0.5.556 → code_coordinator-0.5.558}/tests/test_dashboard_terminal.py +0 -0
  640. {code_coordinator-0.5.556 → code_coordinator-0.5.558}/tests/test_dashboard_terminal_live.py +0 -0
  641. {code_coordinator-0.5.556 → code_coordinator-0.5.558}/tests/test_db.py +0 -0
  642. {code_coordinator-0.5.556 → code_coordinator-0.5.558}/tests/test_dead_end.py +0 -0
  643. {code_coordinator-0.5.556 → code_coordinator-0.5.558}/tests/test_decomposition_chat.py +0 -0
  644. {code_coordinator-0.5.556 → code_coordinator-0.5.558}/tests/test_deploy_coord_db_backup.py +0 -0
  645. {code_coordinator-0.5.556 → code_coordinator-0.5.558}/tests/test_deploy_coord_web_dist.py +0 -0
  646. {code_coordinator-0.5.556 → code_coordinator-0.5.558}/tests/test_deploy_coord_web_rollback.py +0 -0
  647. {code_coordinator-0.5.556 → code_coordinator-0.5.558}/tests/test_deploy_db_backup_unit.py +0 -0
  648. {code_coordinator-0.5.556 → code_coordinator-0.5.558}/tests/test_deploy_drive_queue_unit.py +0 -0
  649. {code_coordinator-0.5.556 → code_coordinator-0.5.558}/tests/test_deploy_failure_notify_unit.py +0 -0
  650. {code_coordinator-0.5.556 → code_coordinator-0.5.558}/tests/test_deploy_manifest.py +0 -0
  651. {code_coordinator-0.5.556 → code_coordinator-0.5.558}/tests/test_deploy_notify_unit.py +0 -0
  652. {code_coordinator-0.5.556 → code_coordinator-0.5.558}/tests/test_deploy_units_lane.py +0 -0
  653. {code_coordinator-0.5.556 → code_coordinator-0.5.558}/tests/test_deploy_web_unit.py +0 -0
  654. {code_coordinator-0.5.556 → code_coordinator-0.5.558}/tests/test_deprecation_telemetry.py +0 -0
  655. {code_coordinator-0.5.556 → code_coordinator-0.5.558}/tests/test_deps.py +0 -0
  656. {code_coordinator-0.5.556 → code_coordinator-0.5.558}/tests/test_diagnose.py +0 -0
  657. {code_coordinator-0.5.556 → code_coordinator-0.5.558}/tests/test_dispatch.py +0 -0
  658. {code_coordinator-0.5.556 → code_coordinator-0.5.558}/tests/test_dispatch_liveness.py +0 -0
  659. {code_coordinator-0.5.556 → code_coordinator-0.5.558}/tests/test_dispatch_target_validation.py +0 -0
  660. {code_coordinator-0.5.556 → code_coordinator-0.5.558}/tests/test_dispatch_workers.py +0 -0
  661. {code_coordinator-0.5.556 → code_coordinator-0.5.558}/tests/test_dist_name.py +0 -0
  662. {code_coordinator-0.5.556 → code_coordinator-0.5.558}/tests/test_done_housekeeping.py +0 -0
  663. {code_coordinator-0.5.556 → code_coordinator-0.5.558}/tests/test_dr_azure_scripts.py +0 -0
  664. {code_coordinator-0.5.556 → code_coordinator-0.5.558}/tests/test_dr_promote.py +0 -0
  665. {code_coordinator-0.5.556 → code_coordinator-0.5.558}/tests/test_dr_verify.py +0 -0
  666. {code_coordinator-0.5.556 → code_coordinator-0.5.558}/tests/test_drive.py +0 -0
  667. {code_coordinator-0.5.556 → code_coordinator-0.5.558}/tests/test_drive_machine_fault.py +0 -0
  668. {code_coordinator-0.5.556 → code_coordinator-0.5.558}/tests/test_drive_queue.py +0 -0
  669. {code_coordinator-0.5.556 → code_coordinator-0.5.558}/tests/test_drive_queue_blocked_rendering.py +0 -0
  670. {code_coordinator-0.5.556 → code_coordinator-0.5.558}/tests/test_drive_queue_launch_argv.py +0 -0
  671. {code_coordinator-0.5.556 → code_coordinator-0.5.558}/tests/test_drive_queue_max_parallel_config.py +0 -0
  672. {code_coordinator-0.5.556 → code_coordinator-0.5.558}/tests/test_drive_queue_max_parallel_per_repo_config.py +0 -0
  673. {code_coordinator-0.5.556 → code_coordinator-0.5.558}/tests/test_drive_queue_roll_pending.py +0 -0
  674. {code_coordinator-0.5.556 → code_coordinator-0.5.558}/tests/test_drive_queue_self_cordon_escalation.py +0 -0
  675. {code_coordinator-0.5.556 → code_coordinator-0.5.558}/tests/test_drive_sessions_snapshot.py +0 -0
  676. {code_coordinator-0.5.556 → code_coordinator-0.5.558}/tests/test_drive_state.py +0 -0
  677. {code_coordinator-0.5.556 → code_coordinator-0.5.558}/tests/test_drive_tmux.py +0 -0
  678. {code_coordinator-0.5.556 → code_coordinator-0.5.558}/tests/test_epic_up_capability_detection.py +0 -0
  679. {code_coordinator-0.5.556 → code_coordinator-0.5.558}/tests/test_epic_up_down_symlinked_config_1887.py +0 -0
  680. {code_coordinator-0.5.556 → code_coordinator-0.5.558}/tests/test_epic_up_image_provenance.py +0 -0
  681. {code_coordinator-0.5.556 → code_coordinator-0.5.558}/tests/test_errors.py +0 -0
  682. {code_coordinator-0.5.556 → code_coordinator-0.5.558}/tests/test_events.py +0 -0
  683. {code_coordinator-0.5.556 → code_coordinator-0.5.558}/tests/test_failure_class.py +0 -0
  684. {code_coordinator-0.5.556 → code_coordinator-0.5.558}/tests/test_failure_classifier.py +0 -0
  685. {code_coordinator-0.5.556 → code_coordinator-0.5.558}/tests/test_filelock.py +0 -0
  686. {code_coordinator-0.5.556 → code_coordinator-0.5.558}/tests/test_finalize_interactive_exit_test_verdict.py +0 -0
  687. {code_coordinator-0.5.556 → code_coordinator-0.5.558}/tests/test_fix_escalation_classifier.py +0 -0
  688. {code_coordinator-0.5.556 → code_coordinator-0.5.558}/tests/test_fix_of_force_override.py +0 -0
  689. {code_coordinator-0.5.556 → code_coordinator-0.5.558}/tests/test_fleet_config_health.py +0 -0
  690. {code_coordinator-0.5.556 → code_coordinator-0.5.558}/tests/test_fleet_health_probes.py +0 -0
  691. {code_coordinator-0.5.556 → code_coordinator-0.5.558}/tests/test_fleet_health_snapshot.py +0 -0
  692. {code_coordinator-0.5.556 → code_coordinator-0.5.558}/tests/test_fleet_watchdog.py +0 -0
  693. {code_coordinator-0.5.556 → code_coordinator-0.5.558}/tests/test_forge_availability.py +0 -0
  694. {code_coordinator-0.5.556 → code_coordinator-0.5.558}/tests/test_freshness.py +0 -0
  695. {code_coordinator-0.5.556 → code_coordinator-0.5.558}/tests/test_gate_a.py +0 -0
  696. {code_coordinator-0.5.556 → code_coordinator-0.5.558}/tests/test_gate_b.py +0 -0
  697. {code_coordinator-0.5.556 → code_coordinator-0.5.558}/tests/test_gate_snapshot_staleness.py +0 -0
  698. {code_coordinator-0.5.556 → code_coordinator-0.5.558}/tests/test_gates.py +0 -0
  699. {code_coordinator-0.5.556 → code_coordinator-0.5.558}/tests/test_gather_fleet_tmux_sessions.py +0 -0
  700. {code_coordinator-0.5.556 → code_coordinator-0.5.558}/tests/test_gen_mock_index.py +0 -0
  701. {code_coordinator-0.5.556 → code_coordinator-0.5.558}/tests/test_generated_rust_fixture.py +0 -0
  702. {code_coordinator-0.5.556 → code_coordinator-0.5.558}/tests/test_generated_rust_requests.py +0 -0
  703. {code_coordinator-0.5.556 → code_coordinator-0.5.558}/tests/test_generated_types_fixture.py +0 -0
  704. {code_coordinator-0.5.556 → code_coordinator-0.5.558}/tests/test_github_ops.py +0 -0
  705. {code_coordinator-0.5.556 → code_coordinator-0.5.558}/tests/test_github_throttle.py +0 -0
  706. {code_coordinator-0.5.556 → code_coordinator-0.5.558}/tests/test_goal.py +0 -0
  707. {code_coordinator-0.5.556 → code_coordinator-0.5.558}/tests/test_graph_health.py +0 -0
  708. {code_coordinator-0.5.556 → code_coordinator-0.5.558}/tests/test_graph_selfheal_absent_2237.py +0 -0
  709. {code_coordinator-0.5.556 → code_coordinator-0.5.558}/tests/test_gtk_native_driver.py +0 -0
  710. {code_coordinator-0.5.556 → code_coordinator-0.5.558}/tests/test_handoff.py +0 -0
  711. {code_coordinator-0.5.556 → code_coordinator-0.5.558}/tests/test_health_checks.py +0 -0
  712. {code_coordinator-0.5.556 → code_coordinator-0.5.558}/tests/test_health_cli.py +0 -0
  713. {code_coordinator-0.5.556 → code_coordinator-0.5.558}/tests/test_health_cli_graph.py +0 -0
  714. {code_coordinator-0.5.556 → code_coordinator-0.5.558}/tests/test_health_config.py +0 -0
  715. {code_coordinator-0.5.556 → code_coordinator-0.5.558}/tests/test_health_context.py +0 -0
  716. {code_coordinator-0.5.556 → code_coordinator-0.5.558}/tests/test_health_coord_tui_ci_pin.py +0 -0
  717. {code_coordinator-0.5.556 → code_coordinator-0.5.558}/tests/test_health_coord_web_ci_pin.py +0 -0
  718. {code_coordinator-0.5.556 → code_coordinator-0.5.558}/tests/test_health_deploy_lane_facts.py +0 -0
  719. {code_coordinator-0.5.556 → code_coordinator-0.5.558}/tests/test_health_fix.py +0 -0
  720. {code_coordinator-0.5.556 → code_coordinator-0.5.558}/tests/test_health_incident_regression.py +0 -0
  721. {code_coordinator-0.5.556 → code_coordinator-0.5.558}/tests/test_health_issues_sync_staleness.py +0 -0
  722. {code_coordinator-0.5.556 → code_coordinator-0.5.558}/tests/test_health_pr_churn.py +0 -0
  723. {code_coordinator-0.5.556 → code_coordinator-0.5.558}/tests/test_health_pypi.py +0 -0
  724. {code_coordinator-0.5.556 → code_coordinator-0.5.558}/tests/test_health_registry.py +0 -0
  725. {code_coordinator-0.5.556 → code_coordinator-0.5.558}/tests/test_health_release_cordon_probe.py +0 -0
  726. {code_coordinator-0.5.556 → code_coordinator-0.5.558}/tests/test_health_timer_active.py +0 -0
  727. {code_coordinator-0.5.556 → code_coordinator-0.5.558}/tests/test_health_toolchain.py +0 -0
  728. {code_coordinator-0.5.556 → code_coordinator-0.5.558}/tests/test_health_unit_drift.py +0 -0
  729. {code_coordinator-0.5.556 → code_coordinator-0.5.558}/tests/test_health_unit_enablement.py +0 -0
  730. {code_coordinator-0.5.556 → code_coordinator-0.5.558}/tests/test_health_wedged_drive_queue.py +0 -0
  731. {code_coordinator-0.5.556 → code_coordinator-0.5.558}/tests/test_hooks.py +0 -0
  732. {code_coordinator-0.5.556 → code_coordinator-0.5.558}/tests/test_housekeeping.py +0 -0
  733. {code_coordinator-0.5.556 → code_coordinator-0.5.558}/tests/test_human_attended_437.py +0 -0
  734. {code_coordinator-0.5.556 → code_coordinator-0.5.558}/tests/test_init.py +0 -0
  735. {code_coordinator-0.5.556 → code_coordinator-0.5.558}/tests/test_install_agent_capabilities_3515.py +0 -0
  736. {code_coordinator-0.5.556 → code_coordinator-0.5.558}/tests/test_install_agent_venv_2911.py +0 -0
  737. {code_coordinator-0.5.556 → code_coordinator-0.5.558}/tests/test_install_agent_wsl_bridge_3515.py +0 -0
  738. {code_coordinator-0.5.556 → code_coordinator-0.5.558}/tests/test_integration.py +0 -0
  739. {code_coordinator-0.5.556 → code_coordinator-0.5.558}/tests/test_interactive.py +0 -0
  740. {code_coordinator-0.5.556 → code_coordinator-0.5.558}/tests/test_interactive_briefing_echo.py +0 -0
  741. {code_coordinator-0.5.556 → code_coordinator-0.5.558}/tests/test_interactive_pane_log_2541.py +0 -0
  742. {code_coordinator-0.5.556 → code_coordinator-0.5.558}/tests/test_interactive_prefill_state.py +0 -0
  743. {code_coordinator-0.5.556 → code_coordinator-0.5.558}/tests/test_interactive_session_relaunch.py +0 -0
  744. {code_coordinator-0.5.556 → code_coordinator-0.5.558}/tests/test_interactive_test_verdict_backstop.py +0 -0
  745. {code_coordinator-0.5.556 → code_coordinator-0.5.558}/tests/test_interactive_token_attribution.py +0 -0
  746. {code_coordinator-0.5.556 → code_coordinator-0.5.558}/tests/test_interactive_worktree.py +0 -0
  747. {code_coordinator-0.5.556 → code_coordinator-0.5.558}/tests/test_invariant_alarms.py +0 -0
  748. {code_coordinator-0.5.556 → code_coordinator-0.5.558}/tests/test_issue_store_seam.py +0 -0
  749. {code_coordinator-0.5.556 → code_coordinator-0.5.558}/tests/test_issues_sync_status.py +0 -0
  750. {code_coordinator-0.5.556 → code_coordinator-0.5.558}/tests/test_liveness_auditor.py +0 -0
  751. {code_coordinator-0.5.556 → code_coordinator-0.5.558}/tests/test_liveness_notify.py +0 -0
  752. {code_coordinator-0.5.556 → code_coordinator-0.5.558}/tests/test_lock_contention_ratchet.py +0 -0
  753. {code_coordinator-0.5.556 → code_coordinator-0.5.558}/tests/test_mac_native_driver.py +0 -0
  754. {code_coordinator-0.5.556 → code_coordinator-0.5.558}/tests/test_machine_fault.py +0 -0
  755. {code_coordinator-0.5.556 → code_coordinator-0.5.558}/tests/test_machine_metrics.py +0 -0
  756. {code_coordinator-0.5.556 → code_coordinator-0.5.558}/tests/test_machine_onboard.py +0 -0
  757. {code_coordinator-0.5.556 → code_coordinator-0.5.558}/tests/test_machine_pause.py +0 -0
  758. {code_coordinator-0.5.556 → code_coordinator-0.5.558}/tests/test_machine_stats.py +0 -0
  759. {code_coordinator-0.5.556 → code_coordinator-0.5.558}/tests/test_merge_queue.py +0 -0
  760. {code_coordinator-0.5.556 → code_coordinator-0.5.558}/tests/test_merge_verify.py +0 -0
  761. {code_coordinator-0.5.556 → code_coordinator-0.5.558}/tests/test_milestone_chat.py +0 -0
  762. {code_coordinator-0.5.556 → code_coordinator-0.5.558}/tests/test_milestone_dispatch.py +0 -0
  763. {code_coordinator-0.5.556 → code_coordinator-0.5.558}/tests/test_milestone_gate.py +0 -0
  764. {code_coordinator-0.5.556 → code_coordinator-0.5.558}/tests/test_milestone_order.py +0 -0
  765. {code_coordinator-0.5.556 → code_coordinator-0.5.558}/tests/test_milestone_seam.py +0 -0
  766. {code_coordinator-0.5.556 → code_coordinator-0.5.558}/tests/test_mock_author.py +0 -0
  767. {code_coordinator-0.5.556 → code_coordinator-0.5.558}/tests/test_model_tiering.py +0 -0
  768. {code_coordinator-0.5.556 → code_coordinator-0.5.558}/tests/test_models.py +0 -0
  769. {code_coordinator-0.5.556 → code_coordinator-0.5.558}/tests/test_models_config_labels.py +0 -0
  770. {code_coordinator-0.5.556 → code_coordinator-0.5.558}/tests/test_needs_attention.py +0 -0
  771. {code_coordinator-0.5.556 → code_coordinator-0.5.558}/tests/test_network.py +0 -0
  772. {code_coordinator-0.5.556 → code_coordinator-0.5.558}/tests/test_new_issue_chat.py +0 -0
  773. {code_coordinator-0.5.556 → code_coordinator-0.5.558}/tests/test_next_release_tag.py +0 -0
  774. {code_coordinator-0.5.556 → code_coordinator-0.5.558}/tests/test_node_shim.py +0 -0
  775. {code_coordinator-0.5.556 → code_coordinator-0.5.558}/tests/test_notifier_baseline.py +0 -0
  776. {code_coordinator-0.5.556 → code_coordinator-0.5.558}/tests/test_notifier_cli.py +0 -0
  777. {code_coordinator-0.5.556 → code_coordinator-0.5.558}/tests/test_notifier_collect.py +0 -0
  778. {code_coordinator-0.5.556 → code_coordinator-0.5.558}/tests/test_notifier_config.py +0 -0
  779. {code_coordinator-0.5.556 → code_coordinator-0.5.558}/tests/test_notifier_drive_seam.py +0 -0
  780. {code_coordinator-0.5.556 → code_coordinator-0.5.558}/tests/test_notifier_isolation.py +0 -0
  781. {code_coordinator-0.5.556 → code_coordinator-0.5.558}/tests/test_notifier_predicate.py +0 -0
  782. {code_coordinator-0.5.556 → code_coordinator-0.5.558}/tests/test_notifier_quiet_hours.py +0 -0
  783. {code_coordinator-0.5.556 → code_coordinator-0.5.558}/tests/test_notifier_service.py +0 -0
  784. {code_coordinator-0.5.556 → code_coordinator-0.5.558}/tests/test_notify.py +0 -0
  785. {code_coordinator-0.5.556 → code_coordinator-0.5.558}/tests/test_notify_drain.py +0 -0
  786. {code_coordinator-0.5.556 → code_coordinator-0.5.558}/tests/test_openapi.py +0 -0
  787. {code_coordinator-0.5.556 → code_coordinator-0.5.558}/tests/test_operational_defaults.py +0 -0
  788. {code_coordinator-0.5.556 → code_coordinator-0.5.558}/tests/test_overlap_fence.py +0 -0
  789. {code_coordinator-0.5.556 → code_coordinator-0.5.558}/tests/test_overlap_predict.py +0 -0
  790. {code_coordinator-0.5.556 → code_coordinator-0.5.558}/tests/test_packaged_deploy_units.py +0 -0
  791. {code_coordinator-0.5.556 → code_coordinator-0.5.558}/tests/test_parentage.py +0 -0
  792. {code_coordinator-0.5.556 → code_coordinator-0.5.558}/tests/test_paste_landed.py +0 -0
  793. {code_coordinator-0.5.556 → code_coordinator-0.5.558}/tests/test_phantom_heal_venv_independence_2570.py +0 -0
  794. {code_coordinator-0.5.556 → code_coordinator-0.5.558}/tests/test_pipeline.py +0 -0
  795. {code_coordinator-0.5.556 → code_coordinator-0.5.558}/tests/test_plan_followup_approve_plan_command.py +0 -0
  796. {code_coordinator-0.5.556 → code_coordinator-0.5.558}/tests/test_plan_followup_pr_command.py +0 -0
  797. {code_coordinator-0.5.556 → code_coordinator-0.5.558}/tests/test_plan_followup_review_command.py +0 -0
  798. {code_coordinator-0.5.556 → code_coordinator-0.5.558}/tests/test_plan_only.py +0 -0
  799. {code_coordinator-0.5.556 → code_coordinator-0.5.558}/tests/test_plan_parser.py +0 -0
  800. {code_coordinator-0.5.556 → code_coordinator-0.5.558}/tests/test_platform_paths.py +0 -0
  801. {code_coordinator-0.5.556 → code_coordinator-0.5.558}/tests/test_portal_bridge.py +0 -0
  802. {code_coordinator-0.5.556 → code_coordinator-0.5.558}/tests/test_portal_config.py +0 -0
  803. {code_coordinator-0.5.556 → code_coordinator-0.5.558}/tests/test_portal_store.py +0 -0
  804. {code_coordinator-0.5.556 → code_coordinator-0.5.558}/tests/test_portal_sync.py +0 -0
  805. {code_coordinator-0.5.556 → code_coordinator-0.5.558}/tests/test_pr_body_lint.py +0 -0
  806. {code_coordinator-0.5.556 → code_coordinator-0.5.558}/tests/test_prereqs.py +0 -0
  807. {code_coordinator-0.5.556 → code_coordinator-0.5.558}/tests/test_production_db_guard.py +0 -0
  808. {code_coordinator-0.5.556 → code_coordinator-0.5.558}/tests/test_progress.py +0 -0
  809. {code_coordinator-0.5.556 → code_coordinator-0.5.558}/tests/test_provider_seam.py +0 -0
  810. {code_coordinator-0.5.556 → code_coordinator-0.5.558}/tests/test_providers.py +0 -0
  811. {code_coordinator-0.5.556 → code_coordinator-0.5.558}/tests/test_providers_config_labels.py +0 -0
  812. {code_coordinator-0.5.556 → code_coordinator-0.5.558}/tests/test_providers_pty.py +0 -0
  813. {code_coordinator-0.5.556 → code_coordinator-0.5.558}/tests/test_provision_core.py +0 -0
  814. {code_coordinator-0.5.556 → code_coordinator-0.5.558}/tests/test_provision_machine.py +0 -0
  815. {code_coordinator-0.5.556 → code_coordinator-0.5.558}/tests/test_py_rust_mirror_inventory.py +0 -0
  816. {code_coordinator-0.5.556 → code_coordinator-0.5.558}/tests/test_quiet_hours.py +0 -0
  817. {code_coordinator-0.5.556 → code_coordinator-0.5.558}/tests/test_quiet_hours_store_2146.py +0 -0
  818. {code_coordinator-0.5.556 → code_coordinator-0.5.558}/tests/test_reap_merged_sessions.py +0 -0
  819. {code_coordinator-0.5.556 → code_coordinator-0.5.558}/tests/test_reap_stale_interactive_tick.py +0 -0
  820. {code_coordinator-0.5.556 → code_coordinator-0.5.558}/tests/test_reconcile.py +0 -0
  821. {code_coordinator-0.5.556 → code_coordinator-0.5.558}/tests/test_reconcile_branch.py +0 -0
  822. {code_coordinator-0.5.556 → code_coordinator-0.5.558}/tests/test_reconcile_completions.py +0 -0
  823. {code_coordinator-0.5.556 → code_coordinator-0.5.558}/tests/test_reconcile_late_agent_reports_2547.py +0 -0
  824. {code_coordinator-0.5.556 → code_coordinator-0.5.558}/tests/test_reconcile_merges.py +0 -0
  825. {code_coordinator-0.5.556 → code_coordinator-0.5.558}/tests/test_reconcile_no_agent_record.py +0 -0
  826. {code_coordinator-0.5.556 → code_coordinator-0.5.558}/tests/test_reconcile_tick.py +0 -0
  827. {code_coordinator-0.5.556 → code_coordinator-0.5.558}/tests/test_reconcile_usage_limit_done.py +0 -0
  828. {code_coordinator-0.5.556 → code_coordinator-0.5.558}/tests/test_refine_chat.py +0 -0
  829. {code_coordinator-0.5.556 → code_coordinator-0.5.558}/tests/test_release_cordon_2101.py +0 -0
  830. {code_coordinator-0.5.556 → code_coordinator-0.5.558}/tests/test_release_cordon_daemon_leads_2176.py +0 -0
  831. {code_coordinator-0.5.556 → code_coordinator-0.5.558}/tests/test_release_cordon_deadlock_2240.py +0 -0
  832. {code_coordinator-0.5.556 → code_coordinator-0.5.558}/tests/test_release_cordon_drain_stall_3336.py +0 -0
  833. {code_coordinator-0.5.556 → code_coordinator-0.5.558}/tests/test_release_cordon_stuck_2490.py +0 -0
  834. {code_coordinator-0.5.556 → code_coordinator-0.5.558}/tests/test_release_propagate.py +0 -0
  835. {code_coordinator-0.5.556 → code_coordinator-0.5.558}/tests/test_release_propagate_threshold.py +0 -0
  836. {code_coordinator-0.5.556 → code_coordinator-0.5.558}/tests/test_release_roll_between_legs_2854.py +0 -0
  837. {code_coordinator-0.5.556 → code_coordinator-0.5.558}/tests/test_release_roll_window_handoff.py +0 -0
  838. {code_coordinator-0.5.556 → code_coordinator-0.5.558}/tests/test_release_unified_1242.py +0 -0
  839. {code_coordinator-0.5.556 → code_coordinator-0.5.558}/tests/test_release_verify.py +0 -0
  840. {code_coordinator-0.5.556 → code_coordinator-0.5.558}/tests/test_release_window.py +0 -0
  841. {code_coordinator-0.5.556 → code_coordinator-0.5.558}/tests/test_remote_auto_prune.py +0 -0
  842. {code_coordinator-0.5.556 → code_coordinator-0.5.558}/tests/test_remote_interactive_reaper.py +0 -0
  843. {code_coordinator-0.5.556 → code_coordinator-0.5.558}/tests/test_repo_add.py +0 -0
  844. {code_coordinator-0.5.556 → code_coordinator-0.5.558}/tests/test_repo_dormancy.py +0 -0
  845. {code_coordinator-0.5.556 → code_coordinator-0.5.558}/tests/test_repo_edit_2220.py +0 -0
  846. {code_coordinator-0.5.556 → code_coordinator-0.5.558}/tests/test_repo_graph_fleet_2237.py +0 -0
  847. {code_coordinator-0.5.556 → code_coordinator-0.5.558}/tests/test_repo_max_parallel_3423.py +0 -0
  848. {code_coordinator-0.5.556 → code_coordinator-0.5.558}/tests/test_repo_onboard_2220.py +0 -0
  849. {code_coordinator-0.5.556 → code_coordinator-0.5.558}/tests/test_report_result_push.py +0 -0
  850. {code_coordinator-0.5.556 → code_coordinator-0.5.558}/tests/test_reports.py +0 -0
  851. {code_coordinator-0.5.556 → code_coordinator-0.5.558}/tests/test_restart_cmd.py +0 -0
  852. {code_coordinator-0.5.556 → code_coordinator-0.5.558}/tests/test_retry.py +0 -0
  853. {code_coordinator-0.5.556 → code_coordinator-0.5.558}/tests/test_retry_advisory_1606.py +0 -0
  854. {code_coordinator-0.5.556 → code_coordinator-0.5.558}/tests/test_retry_escalation_classify_3360.py +0 -0
  855. {code_coordinator-0.5.556 → code_coordinator-0.5.558}/tests/test_retry_type_1636.py +0 -0
  856. {code_coordinator-0.5.556 → code_coordinator-0.5.558}/tests/test_revalidate.py +0 -0
  857. {code_coordinator-0.5.556 → code_coordinator-0.5.558}/tests/test_review.py +0 -0
  858. {code_coordinator-0.5.556 → code_coordinator-0.5.558}/tests/test_review_end_review_without_verdict.py +0 -0
  859. {code_coordinator-0.5.556 → code_coordinator-0.5.558}/tests/test_review_parse_failure_diagnostic.py +0 -0
  860. {code_coordinator-0.5.556 → code_coordinator-0.5.558}/tests/test_review_reaffirm.py +0 -0
  861. {code_coordinator-0.5.556 → code_coordinator-0.5.558}/tests/test_review_state.py +0 -0
  862. {code_coordinator-0.5.556 → code_coordinator-0.5.558}/tests/test_review_verdict_backstop.py +0 -0
  863. {code_coordinator-0.5.556 → code_coordinator-0.5.558}/tests/test_review_verdict_override_audit.py +0 -0
  864. {code_coordinator-0.5.556 → code_coordinator-0.5.558}/tests/test_review_verdict_relay.py +0 -0
  865. {code_coordinator-0.5.556 → code_coordinator-0.5.558}/tests/test_review_zero_commits.py +0 -0
  866. {code_coordinator-0.5.556 → code_coordinator-0.5.558}/tests/test_scoped_review_wiring.py +0 -0
  867. {code_coordinator-0.5.556 → code_coordinator-0.5.558}/tests/test_scorecard.py +0 -0
  868. {code_coordinator-0.5.556 → code_coordinator-0.5.558}/tests/test_self_health.py +0 -0
  869. {code_coordinator-0.5.556 → code_coordinator-0.5.558}/tests/test_serve.py +0 -0
  870. {code_coordinator-0.5.556 → code_coordinator-0.5.558}/tests/test_serve_app.py +0 -0
  871. {code_coordinator-0.5.556 → code_coordinator-0.5.558}/tests/test_serve_app_board_trim.py +0 -0
  872. {code_coordinator-0.5.556 → code_coordinator-0.5.558}/tests/test_serve_rest_routes.py +0 -0
  873. {code_coordinator-0.5.556 → code_coordinator-0.5.558}/tests/test_session.py +0 -0
  874. {code_coordinator-0.5.556 → code_coordinator-0.5.558}/tests/test_slice_issue_attribution.py +0 -0
  875. {code_coordinator-0.5.556 → code_coordinator-0.5.558}/tests/test_smoke.py +0 -0
  876. {code_coordinator-0.5.556 → code_coordinator-0.5.558}/tests/test_smoke_fanout_manifest_3333.py +0 -0
  877. {code_coordinator-0.5.556 → code_coordinator-0.5.558}/tests/test_smoke_live_checkout_restore.py +0 -0
  878. {code_coordinator-0.5.556 → code_coordinator-0.5.558}/tests/test_smoke_workflow.py +0 -0
  879. {code_coordinator-0.5.556 → code_coordinator-0.5.558}/tests/test_spend_ceiling.py +0 -0
  880. {code_coordinator-0.5.556 → code_coordinator-0.5.558}/tests/test_spend_ceiling_coordinator.py +0 -0
  881. {code_coordinator-0.5.556 → code_coordinator-0.5.558}/tests/test_split.py +0 -0
  882. {code_coordinator-0.5.556 → code_coordinator-0.5.558}/tests/test_split_work.py +0 -0
  883. {code_coordinator-0.5.556 → code_coordinator-0.5.558}/tests/test_sql_dialect.py +0 -0
  884. {code_coordinator-0.5.556 → code_coordinator-0.5.558}/tests/test_sqlite_connect_ratchet.py +0 -0
  885. {code_coordinator-0.5.556 → code_coordinator-0.5.558}/tests/test_stage_projection.py +0 -0
  886. {code_coordinator-0.5.556 → code_coordinator-0.5.558}/tests/test_stale_busy_reviewer_697.py +0 -0
  887. {code_coordinator-0.5.556 → code_coordinator-0.5.558}/tests/test_stalled_pipeline.py +0 -0
  888. {code_coordinator-0.5.556 → code_coordinator-0.5.558}/tests/test_state.py +0 -0
  889. {code_coordinator-0.5.556 → code_coordinator-0.5.558}/tests/test_state_review_findings_daemon.py +0 -0
  890. {code_coordinator-0.5.556 → code_coordinator-0.5.558}/tests/test_status_fleet_footer.py +0 -0
  891. {code_coordinator-0.5.556 → code_coordinator-0.5.558}/tests/test_stop_1567.py +0 -0
  892. {code_coordinator-0.5.556 → code_coordinator-0.5.558}/tests/test_store_contract.py +0 -0
  893. {code_coordinator-0.5.556 → code_coordinator-0.5.558}/tests/test_store_migrate.py +0 -0
  894. {code_coordinator-0.5.556 → code_coordinator-0.5.558}/tests/test_stuck.py +0 -0
  895. {code_coordinator-0.5.556 → code_coordinator-0.5.558}/tests/test_stuck_test_state_watchdog_2803.py +0 -0
  896. {code_coordinator-0.5.556 → code_coordinator-0.5.558}/tests/test_terminal_command.py +0 -0
  897. {code_coordinator-0.5.556 → code_coordinator-0.5.558}/tests/test_test_author.py +0 -0
  898. {code_coordinator-0.5.556 → code_coordinator-0.5.558}/tests/test_test_chat.py +0 -0
  899. {code_coordinator-0.5.556 → code_coordinator-0.5.558}/tests/test_test_orchestrator.py +0 -0
  900. {code_coordinator-0.5.556 → code_coordinator-0.5.558}/tests/test_test_report.py +0 -0
  901. {code_coordinator-0.5.556 → code_coordinator-0.5.558}/tests/test_test_verdict_parsing.py +0 -0
  902. {code_coordinator-0.5.556 → code_coordinator-0.5.558}/tests/test_test_verdict_transcript_floor.py +0 -0
  903. {code_coordinator-0.5.556 → code_coordinator-0.5.558}/tests/test_text_io_encoding_audit.py +0 -0
  904. {code_coordinator-0.5.556 → code_coordinator-0.5.558}/tests/test_thin_client_board_audit.py +0 -0
  905. {code_coordinator-0.5.556 → code_coordinator-0.5.558}/tests/test_thin_client_config_load_1080.py +0 -0
  906. {code_coordinator-0.5.556 → code_coordinator-0.5.558}/tests/test_thin_client_daemon_routing_906.py +0 -0
  907. {code_coordinator-0.5.556 → code_coordinator-0.5.558}/tests/test_throwaway_vm.py +0 -0
  908. {code_coordinator-0.5.556 → code_coordinator-0.5.558}/tests/test_tmux_host.py +0 -0
  909. {code_coordinator-0.5.556 → code_coordinator-0.5.558}/tests/test_tmux_session.py +0 -0
  910. {code_coordinator-0.5.556 → code_coordinator-0.5.558}/tests/test_transcript_floor.py +0 -0
  911. {code_coordinator-0.5.556 → code_coordinator-0.5.558}/tests/test_tui_pty_driver.py +0 -0
  912. {code_coordinator-0.5.556 → code_coordinator-0.5.558}/tests/test_uat_checks.py +0 -0
  913. {code_coordinator-0.5.556 → code_coordinator-0.5.558}/tests/test_usage.py +0 -0
  914. {code_coordinator-0.5.556 → code_coordinator-0.5.558}/tests/test_usage_limits.py +0 -0
  915. {code_coordinator-0.5.556 → code_coordinator-0.5.558}/tests/test_usage_rollup.py +0 -0
  916. {code_coordinator-0.5.556 → code_coordinator-0.5.558}/tests/test_venv_live_install_2121.py +0 -0
  917. {code_coordinator-0.5.556 → code_coordinator-0.5.558}/tests/test_version_single_source.py +0 -0
  918. {code_coordinator-0.5.556 → code_coordinator-0.5.558}/tests/test_watch.py +0 -0
  919. {code_coordinator-0.5.556 → code_coordinator-0.5.558}/tests/test_win_native_driver.py +0 -0
  920. {code_coordinator-0.5.556 → code_coordinator-0.5.558}/tests/test_windows_job_is_a_real_gate_2000.py +0 -0
  921. {code_coordinator-0.5.556 → code_coordinator-0.5.558}/tests/test_worker_env_venv_isolation.py +0 -0
  922. {code_coordinator-0.5.556 → code_coordinator-0.5.558}/tests/test_worker_events.py +0 -0
  923. {code_coordinator-0.5.556 → code_coordinator-0.5.558}/tests/test_worker_image_pin_sync.py +0 -0
  924. {code_coordinator-0.5.556 → code_coordinator-0.5.558}/tests/test_worker_safety.py +0 -0
  925. {code_coordinator-0.5.556 → code_coordinator-0.5.558}/tests/test_worker_test_scoping.py +0 -0
  926. {code_coordinator-0.5.556 → code_coordinator-0.5.558}/tests/test_worktree.py +0 -0
  927. {code_coordinator-0.5.556 → code_coordinator-0.5.558}/tests/test_worktree_rmtree_chokepoint.py +0 -0
  928. {code_coordinator-0.5.556 → code_coordinator-0.5.558}/tests/test_write_parity.py +0 -0
  929. {code_coordinator-0.5.556 → code_coordinator-0.5.558}/tests/write_parity.py +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: code-coordinator
3
- Version: 0.5.556
3
+ Version: 0.5.558
4
4
  Summary: Coordinate Claude Code workers across multiple machines and repos.
5
5
  Author-email: John Donaghy <johnfdonaghy@gmail.com>
6
6
  License-Expression: LicenseRef-FSL-1.1-MIT
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: code-coordinator
3
- Version: 0.5.556
3
+ Version: 0.5.558
4
4
  Summary: Coordinate Claude Code workers across multiple machines and repos.
5
5
  Author-email: John Donaghy <johnfdonaghy@gmail.com>
6
6
  License-Expression: LicenseRef-FSL-1.1-MIT
@@ -1,7 +1,7 @@
1
1
  {
2
- "tag": "0.5.556",
2
+ "tag": "0.5.558",
3
3
  "distance": 0,
4
- "node": "gde6caedc9afc7f0f9a375055f1468dc8f6f1b27b",
4
+ "node": "gf42568c48e4156fbf7db345924a59a460c00e3e3",
5
5
  "dirty": false,
6
6
  "branch": "HEAD",
7
7
  "node_date": "2026-10-02"
@@ -147,57 +147,196 @@ class Finding:
147
147
  #: this finding — folded into the issue's Evidence section, not a
148
148
  #: separate upload step (#3487 doesn't specify an artifact store).
149
149
  captures: tuple[str, ...] = ()
150
+ #: #3517: ``True`` when the lane worker's JSON entry for this finding was
151
+ #: missing one or more required fields and a value below had to be
152
+ #: defaulted/derived rather than actually reported. A protocol slip
153
+ #: (the worker naming a field differently, or skipping it) must NEVER
154
+ #: silently collapse a real finding into "no finding" — see
155
+ #: :data:`_REQUIRED_FINDING_FIELDS` and :func:`_finding_from_entry`. Kept
156
+ #: ``False`` for a well-formed entry.
157
+ incomplete: bool = False
158
+ #: Which required field names (see :data:`_REQUIRED_FINDING_FIELDS`) were
159
+ #: missing/blank in the raw JSON entry this finding was built from —
160
+ #: empty whenever :attr:`incomplete` is ``False``.
161
+ missing_fields: tuple[str, ...] = ()
150
162
 
151
163
 
152
- def parse_findings_block(text: str, *, platform: str, repo: str) -> list[Finding]:
164
+ @dataclass(frozen=True)
165
+ class FindingsParseResult:
166
+ """What :func:`parse_findings_block` extracted from one lane worker's
167
+ final message (#3517).
168
+
169
+ ``findings`` is never silently emptied by a per-entry defect — a JSON
170
+ entry missing a required field is still turned into a :class:`Finding`
171
+ (see :attr:`Finding.incomplete`). ``protocol_error`` is the DISTINCT
172
+ failure mode this type exists to make unmistakable: a non-empty string
173
+ means the lane's report itself could not be trusted at all — the
174
+ ```` ```bugbash-findings ```` fence held invalid JSON or something other
175
+ than a list, or there was no fence AND no explicit statement that the
176
+ round found nothing. ``findings`` is always ``()`` when
177
+ ``protocol_error`` is set. Callers (:func:`coord.bugbash.run_bugbash` via
178
+ :data:`ExploreOutcome.protocol_error`) must never read an empty
179
+ ``findings`` tuple alone as "zero findings" without also checking this
180
+ field — that conflation is exactly bug #3517.
181
+ """
182
+
183
+ findings: tuple[Finding, ...] = ()
184
+ protocol_error: str = ""
185
+
186
+
187
+ #: The findings-entry fields a lane worker's briefing (see
188
+ #: :func:`build_exploration_briefing`) asks for by name. ``evidence`` is
189
+ #: handled specially by :func:`_finding_from_entry` (derived from ``captures``
190
+ #: / ``actual`` rather than merely defaulted to a placeholder) since it is
191
+ #: the one field #3517's real-world miss actually dropped.
192
+ _REQUIRED_FINDING_FIELDS: tuple[str, ...] = ("title", "expected", "actual", "repro", "evidence")
193
+
194
+ #: Placeholder text used for a missing field with no better derivation —
195
+ #: visibly a placeholder (never mistaken for a real report) rather than an
196
+ #: empty string, which would render as a blank issue-body section.
197
+ _MISSING_FIELD_PLACEHOLDER = "(not reported by lane worker)"
198
+
199
+ #: Phrases that count as an explicit "this round found nothing" statement
200
+ #: when a lane worker's final message carries no ```` ```bugbash-findings ````
201
+ #: fence at all (#3517). Deliberately narrow and literal (no fuzzy/NLP
202
+ #: matching) — a missing fence defaults to a PROTOCOL ERROR, never silently
203
+ #: to a clean pass, so the bar for accepting "no fence" as clean is an
204
+ #: unambiguous statement, not a guess.
205
+ _CLEAN_PASS_PHRASES: tuple[str, ...] = (
206
+ "no findings", "zero findings", "0 findings", "found nothing",
207
+ "nothing to report", "no bugs found", "no issues found",
208
+ "found no issues", "found no bugs", "clean round", "clean pass",
209
+ )
210
+
211
+
212
+ def _is_explicit_clean_statement(text: str) -> bool:
213
+ """``True`` when *text* contains one of :data:`_CLEAN_PASS_PHRASES`,
214
+ case-insensitively — the ONLY thing that lets a fence-less message in
215
+ :func:`parse_findings_block` read as a genuine clean pass rather than a
216
+ protocol error (#3517)."""
217
+ lowered = text.lower()
218
+ return any(phrase in lowered for phrase in _CLEAN_PASS_PHRASES)
219
+
220
+
221
+ def _finding_from_entry(entry: dict, *, platform: str, repo: str) -> Finding:
222
+ """Turn one raw JSON object from a ```` ```bugbash-findings ```` block
223
+ into a :class:`Finding` — NEVER dropping it for a missing required field
224
+ (#3517). Each missing/blank field in :data:`_REQUIRED_FINDING_FIELDS` is
225
+ replaced with the best available value and recorded in
226
+ :attr:`Finding.missing_fields`:
227
+
228
+ - ``evidence`` is derived from ``captures`` (what the worker DID attach)
229
+ when present, else from ``actual`` (the behaviour it already
230
+ described), else a visible placeholder — this is exactly the field the
231
+ live #3517 finding omitted, so it gets the most effort to recover.
232
+ - every other field falls back to :data:`_MISSING_FIELD_PLACEHOLDER`,
233
+ which is distinguishable from a real report at a glance.
234
+ """
235
+ missing: list[str] = []
236
+
237
+ def _field(key: str) -> str:
238
+ value = str(entry.get(key, "")).strip()
239
+ if not value:
240
+ missing.append(key)
241
+ return _MISSING_FIELD_PLACEHOLDER
242
+ return value
243
+
244
+ title = _field("title")
245
+ expected = _field("expected")
246
+ actual_raw = str(entry.get("actual", "")).strip()
247
+ actual = actual_raw or _MISSING_FIELD_PLACEHOLDER
248
+ if not actual_raw:
249
+ missing.append("actual")
250
+ repro = _field("repro")
251
+
252
+ captures_raw = entry.get("captures") or []
253
+ captures = tuple(str(c) for c in captures_raw) if isinstance(captures_raw, list) else ()
254
+
255
+ evidence = str(entry.get("evidence", "")).strip()
256
+ if not evidence:
257
+ missing.append("evidence")
258
+ if captures:
259
+ evidence = "Derived from captures (evidence field was missing): " + ", ".join(captures)
260
+ elif actual_raw:
261
+ evidence = "Derived from `actual` (evidence field was missing): " + actual_raw
262
+ else:
263
+ evidence = _MISSING_FIELD_PLACEHOLDER
264
+
265
+ return Finding(
266
+ title=title,
267
+ platform=platform,
268
+ repo=repo,
269
+ suspected_repo=str(entry.get("suspected_repo", repo)).strip() or repo,
270
+ expected=expected,
271
+ actual=actual,
272
+ repro=repro,
273
+ evidence=evidence,
274
+ captures=captures,
275
+ incomplete=bool(missing),
276
+ missing_fields=tuple(missing),
277
+ )
278
+
279
+
280
+ def parse_findings_block(text: str, *, platform: str, repo: str) -> FindingsParseResult:
153
281
  """Extract the ```` ```bugbash-findings ```` fenced JSON block from a lane
154
- worker's final message and turn it into :class:`Finding` objects.
155
-
156
- Tolerant of no block at all (a clean round — returns ``[]``) and of a
157
- block that fails to parse as a JSON list of objects (also ``[]``: a
158
- malformed report is not a reportable finding, mirroring
159
- :func:`coord.bug_intake.parse_bug_report`'s "partial isn't actionable"
160
- stance). Each object must carry ``title``/``expected``/``actual``/
161
- ``repro``/``evidence``; ``suspected_repo`` defaults to *repo* and
162
- ``captures`` defaults to ``[]`` when omitted.
282
+ worker's final message and turn it into :class:`FindingsParseResult`
283
+ (#3517).
284
+
285
+ Three distinct outcomes, none of which collapse into each other:
286
+
287
+ - **No fence, and an explicit clean statement** (one of
288
+ :data:`_CLEAN_PASS_PHRASES`) — a genuine clean round: returns
289
+ ``FindingsParseResult()`` (empty findings, no protocol error).
290
+ - **No fence, and no explicit clean statement** — the worker's protocol
291
+ slip, not a clean pass: returns a non-empty ``protocol_error``. A
292
+ lane worker that simply forgot to fence its findings must never read
293
+ identically to one that affirmatively found nothing.
294
+ - **A fence present, but its contents fail to parse as a JSON list**
295
+ (invalid JSON, or valid JSON that isn't a list) — also a
296
+ ``protocol_error``, never silently ``[]`` (that was bug #3517: a
297
+ malformed block and a clean pass rendered identically).
298
+
299
+ Otherwise, every object in the parsed list becomes a :class:`Finding`
300
+ via :func:`_finding_from_entry` — missing required fields are defaulted/
301
+ derived and flagged :attr:`Finding.incomplete`, never dropped. An item in
302
+ the list that isn't a JSON object at all is skipped (the fence itself
303
+ still parsed as a valid JSON list, so this is not elevated to a protocol
304
+ error).
163
305
  """
164
306
  pattern = re.compile(
165
307
  rf"```{re.escape(FINDINGS_FENCE)}\s*\n(.*?)```", re.DOTALL,
166
308
  )
167
309
  match = pattern.search(text)
168
310
  if match is None:
169
- return []
311
+ if _is_explicit_clean_statement(text):
312
+ return FindingsParseResult()
313
+ return FindingsParseResult(
314
+ protocol_error=(
315
+ f"no ```{FINDINGS_FENCE}``` fence found in the lane worker's "
316
+ "final message, and it did not explicitly state a clean "
317
+ "(zero-findings) pass"
318
+ ),
319
+ )
170
320
  try:
171
321
  raw = json.loads(match.group(1))
172
- except (ValueError, TypeError):
173
- return []
322
+ except (ValueError, TypeError) as e:
323
+ return FindingsParseResult(
324
+ protocol_error=f"```{FINDINGS_FENCE}``` fence did not contain valid JSON: {e}",
325
+ )
174
326
  if not isinstance(raw, list):
175
- return []
176
-
177
- findings: list[Finding] = []
178
- for entry in raw:
179
- if not isinstance(entry, dict):
180
- continue
181
- required = ("title", "expected", "actual", "repro", "evidence")
182
- if any(not str(entry.get(k, "")).strip() for k in required):
183
- continue
184
- captures = entry.get("captures") or []
185
- if not isinstance(captures, list):
186
- captures = []
187
- findings.append(
188
- Finding(
189
- title=str(entry["title"]).strip(),
190
- platform=platform,
191
- repo=repo,
192
- suspected_repo=str(entry.get("suspected_repo", repo)).strip() or repo,
193
- expected=str(entry["expected"]).strip(),
194
- actual=str(entry["actual"]).strip(),
195
- repro=str(entry["repro"]).strip(),
196
- evidence=str(entry["evidence"]).strip(),
197
- captures=tuple(str(c) for c in captures),
198
- )
327
+ return FindingsParseResult(
328
+ protocol_error=(
329
+ f"```{FINDINGS_FENCE}``` fence must contain a JSON list, "
330
+ f"got {type(raw).__name__}"
331
+ ),
199
332
  )
200
- return findings
333
+
334
+ findings = tuple(
335
+ _finding_from_entry(entry, platform=platform, repo=repo)
336
+ for entry in raw
337
+ if isinstance(entry, dict)
338
+ )
339
+ return FindingsParseResult(findings=findings)
201
340
 
202
341
 
203
342
  # ── dedupe ───────────────────────────────────────────────────────────────
@@ -458,13 +597,31 @@ class ExploreOutcome:
458
597
  The production explorer,
459
598
  :func:`coord.commands.bugbash._dispatch_and_await_lane`, does not yet
460
599
  set this flag (tracked as a KNOWN GAP in that module's docstring) —
461
- today this is exercised only at the engine/unit-test level."""
600
+ today this is exercised only at the engine/unit-test level.
601
+
602
+ ``protocol_error`` is a FOURTH, separate outcome (#3517): the lane
603
+ worker DID run to completion (``ok=True``, unlike a dispatch/poll/log
604
+ failure) and its own driver observed no locked/absent session (unlike
605
+ ``unavailable``) — but its final message, run through
606
+ :func:`parse_findings_block`, came back as a :class:`FindingsParseResult`
607
+ with a non-empty ``protocol_error``: no parseable
608
+ ```` ```bugbash-findings ```` block, and
609
+ no explicit statement that the round found nothing. This must never be
610
+ mistaken for ``findings=(), ok=True`` ("ran the checklist, found
611
+ nothing") — that conflation is exactly how bug #3517's real finding (a
612
+ valid block, but one entry missing ``evidence``) got dropped to "zero
613
+ findings" and let a real bug pass the #3488 release gate.
614
+ :func:`run_bugbash` records a non-empty ``protocol_error`` in
615
+ :attr:`RoundReport.protocol_error_lanes` and that round can never
616
+ terminate ``"zero_findings"`` while any lane set it (see
617
+ :attr:`BugbashReport.any_protocol_errors`)."""
462
618
 
463
619
  findings: tuple[Finding, ...] = ()
464
620
  cost: float = 0.0
465
621
  notes: str = ""
466
622
  ok: bool = True
467
623
  unavailable: bool = False
624
+ protocol_error: str = ""
468
625
 
469
626
 
470
627
  #: ``(lane, round_num) -> ExploreOutcome`` — "go run this lane's
@@ -509,6 +666,16 @@ def _evidence_with_acceptance(finding: Finding, dedupe: DedupeResult) -> str:
509
666
  parts = [finding.evidence.strip()] if finding.evidence.strip() else []
510
667
  if finding.captures:
511
668
  parts.append("Captures: " + ", ".join(finding.captures))
669
+ if finding.incomplete:
670
+ # #3517: a finding filed from a lane report missing one or more
671
+ # required fields must say so on the issue itself, not just in the
672
+ # CLI's round output — a human triaging it needs to know some of
673
+ # what's below was defaulted/derived, not actually reported.
674
+ parts.append(
675
+ "INCOMPLETE REPORT: the lane worker's findings entry was missing "
676
+ f"required field(s): {', '.join(finding.missing_fields)}. Values "
677
+ "above were defaulted/derived rather than reported."
678
+ )
512
679
  if dedupe.verdict is DedupeVerdict.REGRESSION and dedupe.matched_number is not None:
513
680
  parts.append(
514
681
  f"Regression: reopens the symptom from closed issue "
@@ -671,6 +838,18 @@ class RoundReport:
671
838
  #: tracked separately rather than folded into either bucket. No
672
839
  #: findings are ever filed from a lane recorded here this round.
673
840
  unavailable_lanes: dict[str, str] = field(default_factory=dict)
841
+ #: ``{platform: detail}`` for every lane explored this round whose
842
+ #: :attr:`ExploreOutcome.protocol_error` was non-empty (#3517) — the lane
843
+ #: worker completed (``ok=True``), its driver reported no locked/absent
844
+ #: session, but its final message could not be trusted as a findings
845
+ #: report at all: no parseable ```` ```bugbash-findings ```` block, and no
846
+ #: explicit "found nothing" statement either. Distinct from BOTH
847
+ #: ``lane_failures`` (we never even got an answer) and
848
+ #: ``unavailable_lanes`` (the driver's own precheck blocked the run) —
849
+ #: here the worker ran and answered, but the answer violates the
850
+ #: reporting contract, so it must never be read as "zero findings
851
+ #: observed" (that silent collapse is exactly bug #3517).
852
+ protocol_error_lanes: dict[str, str] = field(default_factory=dict)
674
853
 
675
854
  @property
676
855
  def explored_lanes(self) -> set[str]:
@@ -746,6 +925,15 @@ class BugbashReport:
746
925
  time and needs attention, not a bug report."""
747
926
  return any(r.unavailable_lanes for r in self.rounds)
748
927
 
928
+ @property
929
+ def any_protocol_errors(self) -> bool:
930
+ """``True`` if ANY round recorded a lane protocol error (#3517) —
931
+ surfaced regardless of whether it happened to be the terminating
932
+ round, so an operator glancing at an otherwise-clean run still sees
933
+ that one lane's report could not be trusted and needs a human to
934
+ look at its transcript, not a silent "zero findings" credit."""
935
+ return any(r.protocol_error_lanes for r in self.rounds)
936
+
749
937
 
750
938
  def run_bugbash(
751
939
  config: BugbashConfig,
@@ -772,22 +960,32 @@ def run_bugbash(
772
960
  - ``"zero_findings"`` — this round's non-duplicate finding count is 0,
773
961
  AND at least one explored lane actually completed its checklist
774
962
  (neither ``RoundReport.all_explored_lanes_failed`` nor
775
- ``RoundReport.all_explored_lanes_unavailable_or_failed`` is ``True``)
776
- — a genuine observed clean pass.
963
+ ``RoundReport.all_explored_lanes_unavailable_or_failed`` is ``True``),
964
+ AND no lane reported a protocol error (``RoundReport
965
+ .protocol_error_lanes`` is empty) — a genuine observed clean pass.
777
966
  - ``"lane_failure"`` — this round's non-duplicate finding count is ALSO
778
967
  0, but every lane explored this round came back ``ok=False``
779
968
  (dispatch/poll/log failure) — #2096: a fleet-wide dispatch outage
780
969
  must never be reported identically to a clean bugbash pass. Check
781
970
  ``BugbashReport.rounds[-1].lane_failures`` for what actually broke.
971
+ - ``"protocol_error"`` — this round's non-duplicate finding count is ALSO
972
+ 0, not every lane failed to dispatch/poll/log, but at least one lane
973
+ that DID complete reported a :attr:`ExploreOutcome.protocol_error`
974
+ (#3517: a malformed or missing ```` ```bugbash-findings ```` block, or a
975
+ fence-less message with no explicit "found nothing" statement). This
976
+ takes priority over ``"lanes_unavailable"`` below — a lane that
977
+ answered badly is a stronger "do not trust this round" signal than one
978
+ that was simply locked out. Check ``BugbashReport.rounds[-1]
979
+ .protocol_error_lanes`` for which lane and why.
782
980
  - ``"lanes_unavailable"`` — this round's non-duplicate finding count is
783
- ALSO 0, no lane came back a dispatch/poll/log failure, but every lane
784
- explored this round reported its GUI session/display unavailable
785
- (#3510: locked or absent, e.g. a locked dell64) — a different reason
786
- from ``"lane_failure"`` (the explorer DID run and DID get a verified
787
- answer, it's just "the host is locked", not "I don't know"), and
788
- still not a clean pass either, since nothing was actually exercised
789
- against the app. Check ``BugbashReport.rounds[-1].unavailable_lanes``
790
- for which host needs unlocking.
981
+ ALSO 0, no lane came back a dispatch/poll/log failure or a protocol
982
+ error, but every lane explored this round reported its GUI session/
983
+ display unavailable (#3510: locked or absent, e.g. a locked dell64) —
984
+ a different reason from ``"lane_failure"`` (the explorer DID run and
985
+ DID get a verified answer, it's just "the host is locked", not "I
986
+ don't know"), and still not a clean pass either, since nothing was
987
+ actually exercised against the app. Check ``BugbashReport
988
+ .rounds[-1].unavailable_lanes`` for which host needs unlocking.
791
989
  - ``"cost_cap"`` — cumulative cost has reached ``cost_cap_total``.
792
990
  - ``"round_cap"`` — ``config.max_rounds`` rounds ran without either of
793
991
  the above firing.
@@ -826,6 +1024,13 @@ def run_bugbash(
826
1024
  # every lane failed this way can never render identically to
827
1025
  # a round that actually looked and found nothing.
828
1026
  report.lane_failures[lane.platform] = outcome.notes or "explorer reported failure"
1027
+ elif outcome.protocol_error:
1028
+ # #3517: the lane DID complete, but its final message could
1029
+ # not be trusted as a findings report at all — a malformed/
1030
+ # missing block, never silently read as "zero findings
1031
+ # observed" (that conflation is exactly what let a real
1032
+ # finding disappear and pass the #3488 release gate).
1033
+ report.protocol_error_lanes[lane.platform] = outcome.protocol_error
829
1034
 
830
1035
  open_issues = open_issues_fetcher(config.repo)
831
1036
  closed_issues = closed_issues_fetcher(config.repo)
@@ -876,17 +1081,23 @@ def run_bugbash(
876
1081
  rounds.append(report)
877
1082
 
878
1083
  if report.new_count == 0:
879
- # #2096: "zero findings" is only a genuine clean-pass verdict
880
- # when at least one lane was actually verified to have RUN THE
881
- # CHECKLIST this round. A round where every explored lane failed
882
- # to dispatch/poll/fetch its log gets "lane_failure"; a round
883
- # where every explored lane instead reported its session/display
884
- # unavailable (#3510 — locked or absent, never a dispatch
885
- # failure) gets its own distinct "lanes_unavailable" reason, in
886
- # that priority order since a round can't be "all failed" AND
887
- # "all unavailable" (each lane only sets one of the two).
1084
+ # #2096/#3517: "zero findings" is only a genuine clean-pass
1085
+ # verdict when at least one lane was actually verified to have
1086
+ # RUN THE CHECKLIST this round AND every lane that did complete
1087
+ # produced a trustworthy report. A round where every explored
1088
+ # lane failed to dispatch/poll/fetch its log gets "lane_failure";
1089
+ # a round where some lane completed but its report couldn't be
1090
+ # trusted at all (a malformed/missing findings block — #3517)
1091
+ # gets "protocol_error" instead, ahead of "lanes_unavailable"
1092
+ # below since a bad answer is a stronger "don't trust this round"
1093
+ # signal than a lane simply being locked out; a round where every
1094
+ # explored lane instead reported its session/display unavailable
1095
+ # (#3510 — locked or absent, never a dispatch failure) gets its
1096
+ # own distinct "lanes_unavailable" reason last.
888
1097
  if report.all_explored_lanes_failed:
889
1098
  reason = "lane_failure"
1099
+ elif report.protocol_error_lanes:
1100
+ reason = "protocol_error"
890
1101
  elif report.all_explored_lanes_unavailable_or_failed:
891
1102
  reason = "lanes_unavailable"
892
1103
  else:
@@ -166,18 +166,41 @@ def _dispatch_and_await_lane(
166
166
  # (`coord.worker_events._assistant_text`), rather than re-deriving the
167
167
  # stream-json content-block shape here — `coord log --raw` and this
168
168
  # poller must never disagree about what a session's transcript said.
169
- from coord.worker_events import _assistant_text, iter_events_from_text
169
+ # Likewise for cost: `update_summary`/`WorkerSummary` is the SAME
170
+ # accumulator `coord log`/`parse_log` use to total a session's real
171
+ # `total_cost_usd` off its `result` event (#3517) — not a second,
172
+ # independently-drifting cost readout, and never the flat per-round
173
+ # placeholder this explorer used to hand back regardless of what the
174
+ # worker actually spent.
175
+ from coord.worker_events import (
176
+ WorkerSummary,
177
+ _assistant_text,
178
+ iter_events_from_text,
179
+ update_summary,
180
+ )
170
181
 
171
182
  last_assistant_text = ""
183
+ summary = WorkerSummary()
172
184
  for event in iter_events_from_text(log_resp.text):
185
+ update_summary(summary, event)
173
186
  if event.type != "assistant":
174
187
  continue
175
188
  text = _assistant_text(event)
176
189
  if text.strip():
177
190
  last_assistant_text = text
178
191
 
179
- findings = parse_findings_block(last_assistant_text, platform=lane.platform, repo=repo_name)
180
- return ExploreOutcome(findings=tuple(findings), cost=1.0, notes="status=completed")
192
+ parsed = parse_findings_block(last_assistant_text, platform=lane.platform, repo=repo_name)
193
+ if parsed.protocol_error:
194
+ # #3517: the worker completed, but its report can't be trusted as a
195
+ # findings block at all — this must come back DISTINCT from
196
+ # "findings=(), ok=True" (a genuine clean pass), never silently as
197
+ # zero findings.
198
+ return ExploreOutcome(
199
+ cost=summary.total_cost_usd,
200
+ notes=f"protocol error: {parsed.protocol_error}",
201
+ protocol_error=parsed.protocol_error,
202
+ )
203
+ return ExploreOutcome(findings=parsed.findings, cost=summary.total_cost_usd, notes="status=completed")
181
204
 
182
205
 
183
206
  def _fetch_recently_closed_issues(slug: str, *, limit: int = 200) -> list[dict]:
@@ -210,13 +233,20 @@ def _print_round(report: BugbashReport) -> None:
210
233
  # line that reads identically to a genuinely clean round.
211
234
  for platform, note in r.lane_failures.items():
212
235
  click.secho(f" lane FAILED ({platform}): {note}", fg="red")
236
+ # #3517: a lane's protocol slip (malformed/missing findings block)
237
+ # must be just as visible — never let it hide behind a quiet
238
+ # "0 finding(s)" line that reads identically to a genuinely clean
239
+ # round.
240
+ for platform, note in r.protocol_error_lanes.items():
241
+ click.secho(f" lane PROTOCOL ERROR ({platform}): {note}", fg="red")
213
242
  for f in r.filings:
243
+ incomplete = " [INCOMPLETE REPORT]" if f.finding.incomplete else ""
214
244
  if f.filed:
215
- click.echo(f" filed+queued: #{f.issue_number} — {f.finding.title}")
245
+ click.echo(f" filed+queued: #{f.issue_number} — {f.finding.title}{incomplete}")
216
246
  elif f.verdict.value == "duplicate":
217
- click.echo(f" duplicate of #{f.issue_number}: {f.finding.title}")
247
+ click.echo(f" duplicate of #{f.issue_number}: {f.finding.title}{incomplete}")
218
248
  elif f.preview_title is not None:
219
- click.echo(f" would file ({f.verdict.value}): {f.preview_title}")
249
+ click.echo(f" would file ({f.verdict.value}): {f.preview_title}{incomplete}")
220
250
 
221
251
 
222
252
  @click.command(
@@ -331,14 +361,30 @@ def bugbash_cmd(
331
361
  fg="red", err=True,
332
362
  )
333
363
  sys.exit(1)
334
- elif report.any_lane_failures:
364
+ elif report.termination_reason == "protocol_error":
365
+ # #3517: a lane completed but its report could not be trusted as a
366
+ # findings block at all — this must exit nonzero exactly like
367
+ # "lane_failure" does, or a script doing
368
+ # `coord bugbash REPO --yes && next_step` would proceed on a round
369
+ # it never actually got a trustworthy answer from.
370
+ click.secho(
371
+ "error: a lane in the terminating round reported a protocol "
372
+ "error (malformed or missing findings block) — this is NOT a "
373
+ "verified zero-findings pass; see the lane PROTOCOL ERROR "
374
+ "lines above.",
375
+ fg="red", err=True,
376
+ )
377
+ sys.exit(1)
378
+ elif report.any_lane_failures or report.any_protocol_errors:
335
379
  # A partial failure along the way: some lane(s) never got a
336
- # verified answer even though the run as a whole terminated
337
- # normally — worth a nonzero-severity note, but not fatal, since
338
- # other lanes DID produce a real observation this run.
380
+ # verified answer, or answered with an untrustworthy report, even
381
+ # though the run as a whole terminated normally — worth a
382
+ # nonzero-severity note, but not fatal, since other lanes DID
383
+ # produce a real observation this run.
339
384
  click.secho(
340
385
  "warning: one or more rounds had a lane that failed to "
341
- "dispatch/poll/fetch — see the lane FAILED lines above; "
342
- "treat this run's coverage as partial.",
386
+ "dispatch/poll/fetch, or reported a protocol error — see the "
387
+ "lane FAILED / lane PROTOCOL ERROR lines above; treat this "
388
+ "run's coverage as partial.",
343
389
  fg="yellow", err=True,
344
390
  )
@@ -25,7 +25,11 @@ resolving SHA ancestry via git) lives in ``coord.commands.release``.
25
25
  - A ``coord bugbash`` run that terminated via its own ``"lane_failure"``
26
26
  reason (:mod:`coord.bugbash`'s own #2096 guard: every explored lane failed
27
27
  to dispatch/poll/log) is NOT treated as a clean pass here either — see
28
- :attr:`BugbashRunRecord.verified`.
28
+ :attr:`BugbashRunRecord.verified`. Neither is one that terminated
29
+ ``"protocol_error"`` (#3517: a lane completed, but its final report was a
30
+ malformed or missing findings block — never a parseable, trustworthy
31
+ "zero findings" answer) — see :func:`bugbash_run_record_from_report`, the
32
+ one place that maps both termination reasons onto ``verified=False``.
29
33
  - An operator override never erases the underlying failing steps — see
30
34
  :meth:`ReleaseGateVerdict.failing_steps` vs. :meth:`ReleaseGateVerdict.
31
35
  effective_passed`. The override is audited evidence layered ON TOP of the
@@ -47,7 +51,7 @@ from __future__ import annotations
47
51
 
48
52
  import time as _time
49
53
  from dataclasses import dataclass, replace
50
- from typing import Callable, Sequence
54
+ from typing import Any, Callable, Sequence
51
55
 
52
56
  # ── observed inputs ─────────────────────────────────────────────────────────
53
57
 
@@ -91,11 +95,22 @@ class BugbashRunRecord:
91
95
  reduced to what the release gate needs to grade it.
92
96
 
93
97
  ``verified`` mirrors :meth:`coord.bugbash.BugbashReport.rounds`'s own
94
- #2096 distinction: ``False`` means the terminating round's
95
- ``termination_reason`` was ``"lane_failure"`` — every lane explored that
96
- round failed to dispatch/poll/fetch its log, so "zero new findings" was
97
- never actually OBSERVED, it is just the absence of a dispatch that could
98
- have found one. A run like that must never read as a clean pass.
98
+ #2096/#3517 distinction: ``False`` means the terminating round's
99
+ ``termination_reason`` was EITHER ``"lane_failure"`` (every lane explored
100
+ that round failed to dispatch/poll/fetch its log) OR ``"protocol_error"``
101
+ (#3517: a lane completed, but its final report was a malformed or
102
+ missing ```` ```bugbash-findings ```` block — never a parseable, trustworthy
103
+ "zero findings" answer). In both cases "zero new findings" was never
104
+ actually OBSERVED — in the first case nothing answered at all, in the
105
+ second something answered but the answer can't be trusted — so a run
106
+ terminated either way must never read as a clean pass here. ``detail``
107
+ is expected to say which of the two happened (surfaced verbatim in the
108
+ gate step's own ``detail``, see :func:`_bugbash_step`), but this type
109
+ intentionally does NOT split them into two booleans: the release gate
110
+ only ever needs the single yes/no "was this genuinely observed clean"
111
+ answer, and a caller building this from a real
112
+ :class:`coord.bugbash.BugbashReport` sets ``verified=False`` for either
113
+ ``termination_reason`` the exact same way (one question, one answer).
99
114
  """
100
115
 
101
116
  sha: str
@@ -111,6 +126,53 @@ class BugbashRunRecord:
111
126
  return self.verified and self.new_findings == 0
112
127
 
113
128
 
129
+ #: `coord.bugbash.BugbashReport` termination reasons that mean "this round's
130
+ #: zero-new-findings count was never actually OBSERVED" (#2096/#3517) — see
131
+ #: :func:`bugbash_run_record_from_report`, the ONE place that maps a real
132
+ #: bugbash run onto :attr:`BugbashRunRecord.verified`.
133
+ _UNVERIFIED_TERMINATION_REASONS = frozenset({"lane_failure", "protocol_error"})
134
+
135
+
136
+ def bugbash_run_record_from_report(report: Any, *, sha: str, ran_at: float = 0.0) -> BugbashRunRecord:
137
+ """The ONE place that turns a real ``coord bugbash`` run
138
+ (:class:`coord.bugbash.BugbashReport`) into this module's own
139
+ :class:`BugbashRunRecord` (#2096/#3517 "one question, one answer") — so
140
+ a caller wiring the production bugbash-journal store (the
141
+ ``--from-json`` KNOWN GAP noted in ``coord.commands.release``) reads the
142
+ SAME verdict this module's own tests exercise here, rather than
143
+ reimplementing — and risking silently disagreeing with — what counts as
144
+ a verified clean pass.
145
+
146
+ Duck-typed on *report* (``termination_reason`` plus each round's
147
+ ``new_count``) rather than importing :class:`coord.bugbash.BugbashReport`
148
+ directly — this module stays dependency-free per its own module
149
+ docstring, and ``coord.bugbash`` has no reason to import
150
+ ``coord.release_gate`` back.
151
+
152
+ ``new_findings`` is the sum of every round's ``new_count`` — the
153
+ non-duplicate (new/regression) findings actually OBSERVED, independent
154
+ of whether each one went on to be filed. Using *filed* count instead
155
+ would let a run where the operator declined the confirm-gate prompt
156
+ (#3487) read as "zero new findings" even though something genuinely new
157
+ was found — a gate that can be satisfied just by declining to file is a
158
+ gate that can't fail (#2096).
159
+
160
+ ``verified`` is ``False`` exactly when ``report.termination_reason`` is
161
+ in :data:`_UNVERIFIED_TERMINATION_REASONS` (``"lane_failure"`` or
162
+ ``"protocol_error"``, #3517) — every other termination reason
163
+ (``"zero_findings"``, ``"cost_cap"``, ``"round_cap"``) reflects a round
164
+ that was genuinely observed, even one that hit a cost/round cap while
165
+ still finding new things.
166
+ """
167
+ new_findings = sum(getattr(r, "new_count", 0) for r in getattr(report, "rounds", ()))
168
+ reason = getattr(report, "termination_reason", "")
169
+ verified = reason not in _UNVERIFIED_TERMINATION_REASONS
170
+ detail = "" if verified else f"terminated {reason!r} — not a verified clean pass"
171
+ return BugbashRunRecord(
172
+ sha=sha, new_findings=new_findings, verified=verified, ran_at=ran_at, detail=detail,
173
+ )
174
+
175
+
114
176
  # ── the comparator a caller supplies for "at or after" ─────────────────────
115
177
 
116
178
  #: ``(candidate_sha, release_sha) -> bool`` — "did *candidate_sha* happen at