code-coordinator 0.5.322__tar.gz → 0.5.324__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 (822) hide show
  1. {code_coordinator-0.5.322 → code_coordinator-0.5.324}/PKG-INFO +1 -1
  2. {code_coordinator-0.5.322 → code_coordinator-0.5.324}/code_coordinator.egg-info/PKG-INFO +1 -1
  3. {code_coordinator-0.5.322 → code_coordinator-0.5.324}/code_coordinator.egg-info/SOURCES.txt +1 -0
  4. {code_coordinator-0.5.322 → code_coordinator-0.5.324}/code_coordinator.egg-info/scm_file_list.json +1 -0
  5. {code_coordinator-0.5.322 → code_coordinator-0.5.324}/code_coordinator.egg-info/scm_version.json +2 -2
  6. {code_coordinator-0.5.322 → code_coordinator-0.5.324}/coord/agent.py +4 -3
  7. {code_coordinator-0.5.322 → code_coordinator-0.5.324}/coord/approved_work.py +41 -0
  8. {code_coordinator-0.5.322 → code_coordinator-0.5.324}/coord/client.py +30 -0
  9. {code_coordinator-0.5.322 → code_coordinator-0.5.324}/coord/commands/portal.py +214 -34
  10. {code_coordinator-0.5.322 → code_coordinator-0.5.324}/coord/decomposition_chat.py +69 -4
  11. {code_coordinator-0.5.322 → code_coordinator-0.5.324}/coord/portal_store.py +29 -4
  12. {code_coordinator-0.5.322 → code_coordinator-0.5.324}/coord/portal_sync.py +132 -26
  13. {code_coordinator-0.5.322 → code_coordinator-0.5.324}/coord/serve_app.py +262 -0
  14. code_coordinator-0.5.324/tests/test_approved_work_2996.py +163 -0
  15. {code_coordinator-0.5.322 → code_coordinator-0.5.324}/tests/test_cli_portal.py +425 -2
  16. {code_coordinator-0.5.322 → code_coordinator-0.5.324}/tests/test_portal_store.py +191 -0
  17. {code_coordinator-0.5.322 → code_coordinator-0.5.324}/tests/test_sqlite_connect_ratchet.py +14 -2
  18. {code_coordinator-0.5.322 → code_coordinator-0.5.324}/.claude/commands/board.md +0 -0
  19. {code_coordinator-0.5.322 → code_coordinator-0.5.324}/.claude/commands/complete-session.md +0 -0
  20. {code_coordinator-0.5.322 → code_coordinator-0.5.324}/.claude/commands/coordinator.md +0 -0
  21. {code_coordinator-0.5.322 → code_coordinator-0.5.324}/.githooks/_lib.sh +0 -0
  22. {code_coordinator-0.5.322 → code_coordinator-0.5.324}/.githooks/post-checkout +0 -0
  23. {code_coordinator-0.5.322 → code_coordinator-0.5.324}/.githooks/post-commit +0 -0
  24. {code_coordinator-0.5.322 → code_coordinator-0.5.324}/.githooks/post-merge +0 -0
  25. {code_coordinator-0.5.322 → code_coordinator-0.5.324}/.github/ISSUE_TEMPLATE/bug_report.md +0 -0
  26. {code_coordinator-0.5.322 → code_coordinator-0.5.324}/.github/coord-ci-acceptance.yml +0 -0
  27. {code_coordinator-0.5.322 → code_coordinator-0.5.324}/.github/workflows/auto-release.yml +0 -0
  28. {code_coordinator-0.5.322 → code_coordinator-0.5.324}/.github/workflows/publish.yml +0 -0
  29. {code_coordinator-0.5.322 → code_coordinator-0.5.324}/.github/workflows/test.yml +0 -0
  30. {code_coordinator-0.5.322 → code_coordinator-0.5.324}/.gitignore +0 -0
  31. {code_coordinator-0.5.322 → code_coordinator-0.5.324}/CLAUDE.md +0 -0
  32. {code_coordinator-0.5.322 → code_coordinator-0.5.324}/GOAL.md +0 -0
  33. {code_coordinator-0.5.322 → code_coordinator-0.5.324}/LICENSE +0 -0
  34. {code_coordinator-0.5.322 → code_coordinator-0.5.324}/MANIFEST.in +0 -0
  35. {code_coordinator-0.5.322 → code_coordinator-0.5.324}/README.md +0 -0
  36. {code_coordinator-0.5.322 → code_coordinator-0.5.324}/code_coordinator.egg-info/dependency_links.txt +0 -0
  37. {code_coordinator-0.5.322 → code_coordinator-0.5.324}/code_coordinator.egg-info/entry_points.txt +0 -0
  38. {code_coordinator-0.5.322 → code_coordinator-0.5.324}/code_coordinator.egg-info/requires.txt +0 -0
  39. {code_coordinator-0.5.322 → code_coordinator-0.5.324}/code_coordinator.egg-info/top_level.txt +0 -0
  40. {code_coordinator-0.5.322 → code_coordinator-0.5.324}/coord/__init__.py +0 -0
  41. {code_coordinator-0.5.322 → code_coordinator-0.5.324}/coord/_board_mapping.py +0 -0
  42. {code_coordinator-0.5.322 → code_coordinator-0.5.324}/coord/acceptance.py +0 -0
  43. {code_coordinator-0.5.322 → code_coordinator-0.5.324}/coord/acceptance_drivers.py +0 -0
  44. {code_coordinator-0.5.322 → code_coordinator-0.5.324}/coord/agent_app.py +0 -0
  45. {code_coordinator-0.5.322 → code_coordinator-0.5.324}/coord/agent_update.py +0 -0
  46. {code_coordinator-0.5.322 → code_coordinator-0.5.324}/coord/agents/opencode/.gitignore +0 -0
  47. {code_coordinator-0.5.322 → code_coordinator-0.5.324}/coord/agents/opencode/agents/work.md +0 -0
  48. {code_coordinator-0.5.322 → code_coordinator-0.5.324}/coord/agents/opencode/routing.jsonc +0 -0
  49. {code_coordinator-0.5.322 → code_coordinator-0.5.324}/coord/audit.py +0 -0
  50. {code_coordinator-0.5.322 → code_coordinator-0.5.324}/coord/auto_loop.py +0 -0
  51. {code_coordinator-0.5.322 → code_coordinator-0.5.324}/coord/block_log.py +0 -0
  52. {code_coordinator-0.5.322 → code_coordinator-0.5.324}/coord/board_schema.py +0 -0
  53. {code_coordinator-0.5.322 → code_coordinator-0.5.324}/coord/board_service.py +0 -0
  54. {code_coordinator-0.5.322 → code_coordinator-0.5.324}/coord/board_wire.py +0 -0
  55. {code_coordinator-0.5.322 → code_coordinator-0.5.324}/coord/brain.py +0 -0
  56. {code_coordinator-0.5.322 → code_coordinator-0.5.324}/coord/branch_model.py +0 -0
  57. {code_coordinator-0.5.322 → code_coordinator-0.5.324}/coord/bug_intake.py +0 -0
  58. {code_coordinator-0.5.322 → code_coordinator-0.5.324}/coord/cargo_cache.py +0 -0
  59. {code_coordinator-0.5.322 → code_coordinator-0.5.324}/coord/ci_fix.py +0 -0
  60. {code_coordinator-0.5.322 → code_coordinator-0.5.324}/coord/ci_github.py +0 -0
  61. {code_coordinator-0.5.322 → code_coordinator-0.5.324}/coord/ci_gitlab.py +0 -0
  62. {code_coordinator-0.5.322 → code_coordinator-0.5.324}/coord/ci_store.py +0 -0
  63. {code_coordinator-0.5.322 → code_coordinator-0.5.324}/coord/claim.py +0 -0
  64. {code_coordinator-0.5.322 → code_coordinator-0.5.324}/coord/cli.py +0 -0
  65. {code_coordinator-0.5.322 → code_coordinator-0.5.324}/coord/commands/__init__.py +0 -0
  66. {code_coordinator-0.5.322 → code_coordinator-0.5.324}/coord/commands/_common.py +0 -0
  67. {code_coordinator-0.5.322 → code_coordinator-0.5.324}/coord/commands/acceptance.py +0 -0
  68. {code_coordinator-0.5.322 → code_coordinator-0.5.324}/coord/commands/agent_ops.py +0 -0
  69. {code_coordinator-0.5.322 → code_coordinator-0.5.324}/coord/commands/audit.py +0 -0
  70. {code_coordinator-0.5.322 → code_coordinator-0.5.324}/coord/commands/chat.py +0 -0
  71. {code_coordinator-0.5.322 → code_coordinator-0.5.324}/coord/commands/dispatch.py +0 -0
  72. {code_coordinator-0.5.322 → code_coordinator-0.5.324}/coord/commands/dispatch_workers.py +0 -0
  73. {code_coordinator-0.5.322 → code_coordinator-0.5.324}/coord/commands/drive.py +0 -0
  74. {code_coordinator-0.5.322 → code_coordinator-0.5.324}/coord/commands/drive_queue.py +0 -0
  75. {code_coordinator-0.5.322 → code_coordinator-0.5.324}/coord/commands/gate_a.py +0 -0
  76. {code_coordinator-0.5.322 → code_coordinator-0.5.324}/coord/commands/gates.py +0 -0
  77. {code_coordinator-0.5.322 → code_coordinator-0.5.324}/coord/commands/issues.py +0 -0
  78. {code_coordinator-0.5.322 → code_coordinator-0.5.324}/coord/commands/lifecycle.py +0 -0
  79. {code_coordinator-0.5.322 → code_coordinator-0.5.324}/coord/commands/machine.py +0 -0
  80. {code_coordinator-0.5.322 → code_coordinator-0.5.324}/coord/commands/merge.py +0 -0
  81. {code_coordinator-0.5.322 → code_coordinator-0.5.324}/coord/commands/milestone.py +0 -0
  82. {code_coordinator-0.5.322 → code_coordinator-0.5.324}/coord/commands/plan_followup.py +0 -0
  83. {code_coordinator-0.5.322 → code_coordinator-0.5.324}/coord/commands/plans.py +0 -0
  84. {code_coordinator-0.5.322 → code_coordinator-0.5.324}/coord/commands/pr.py +0 -0
  85. {code_coordinator-0.5.322 → code_coordinator-0.5.324}/coord/commands/release.py +0 -0
  86. {code_coordinator-0.5.322 → code_coordinator-0.5.324}/coord/commands/repo.py +0 -0
  87. {code_coordinator-0.5.322 → code_coordinator-0.5.324}/coord/commands/report.py +0 -0
  88. {code_coordinator-0.5.322 → code_coordinator-0.5.324}/coord/commands/review.py +0 -0
  89. {code_coordinator-0.5.322 → code_coordinator-0.5.324}/coord/commands/scorecard.py +0 -0
  90. {code_coordinator-0.5.322 → code_coordinator-0.5.324}/coord/commands/sessions.py +0 -0
  91. {code_coordinator-0.5.322 → code_coordinator-0.5.324}/coord/commands/setup.py +0 -0
  92. {code_coordinator-0.5.322 → code_coordinator-0.5.324}/coord/commands/status.py +0 -0
  93. {code_coordinator-0.5.322 → code_coordinator-0.5.324}/coord/commands/store_migrate.py +0 -0
  94. {code_coordinator-0.5.322 → code_coordinator-0.5.324}/coord/commands/terminal.py +0 -0
  95. {code_coordinator-0.5.322 → code_coordinator-0.5.324}/coord/commands/test_gate.py +0 -0
  96. {code_coordinator-0.5.322 → code_coordinator-0.5.324}/coord/commands/tui.py +0 -0
  97. {code_coordinator-0.5.322 → code_coordinator-0.5.324}/coord/comments.py +0 -0
  98. {code_coordinator-0.5.322 → code_coordinator-0.5.324}/coord/config.py +0 -0
  99. {code_coordinator-0.5.322 → code_coordinator-0.5.324}/coord/config_reload.py +0 -0
  100. {code_coordinator-0.5.322 → code_coordinator-0.5.324}/coord/confirm_test.py +0 -0
  101. {code_coordinator-0.5.322 → code_coordinator-0.5.324}/coord/conflict_fix.py +0 -0
  102. {code_coordinator-0.5.322 → code_coordinator-0.5.324}/coord/dao.py +0 -0
  103. {code_coordinator-0.5.322 → code_coordinator-0.5.324}/coord/dashboard/__init__.py +0 -0
  104. {code_coordinator-0.5.322 → code_coordinator-0.5.324}/coord/dashboard/fixture.py +0 -0
  105. {code_coordinator-0.5.322 → code_coordinator-0.5.324}/coord/dashboard/index.html +0 -0
  106. {code_coordinator-0.5.322 → code_coordinator-0.5.324}/coord/dashboard/server.py +0 -0
  107. {code_coordinator-0.5.322 → code_coordinator-0.5.324}/coord/dashboard/terminal.py +0 -0
  108. {code_coordinator-0.5.322 → code_coordinator-0.5.324}/coord/db.py +0 -0
  109. {code_coordinator-0.5.322 → code_coordinator-0.5.324}/coord/dead_end.py +0 -0
  110. {code_coordinator-0.5.322 → code_coordinator-0.5.324}/coord/deploy/README.md +0 -0
  111. {code_coordinator-0.5.322 → code_coordinator-0.5.324}/coord/deploy/coord-agent.service +0 -0
  112. {code_coordinator-0.5.322 → code_coordinator-0.5.324}/coord/deploy/coord-db-backup.service +0 -0
  113. {code_coordinator-0.5.322 → code_coordinator-0.5.324}/coord/deploy/coord-db-backup.sh +0 -0
  114. {code_coordinator-0.5.322 → code_coordinator-0.5.324}/coord/deploy/coord-db-backup.timer +0 -0
  115. {code_coordinator-0.5.322 → code_coordinator-0.5.324}/coord/deploy/coord-drive-queue.service +0 -0
  116. {code_coordinator-0.5.322 → code_coordinator-0.5.324}/coord/deploy/coord-drive-queue.timer +0 -0
  117. {code_coordinator-0.5.322 → code_coordinator-0.5.324}/coord/deploy/coord-failure-notify.service +0 -0
  118. {code_coordinator-0.5.322 → code_coordinator-0.5.324}/coord/deploy/coord-fleet-watchdog.service +0 -0
  119. {code_coordinator-0.5.322 → code_coordinator-0.5.324}/coord/deploy/coord-fleet-watchdog.timer +0 -0
  120. {code_coordinator-0.5.322 → code_coordinator-0.5.324}/coord/deploy/coord-notify.service +0 -0
  121. {code_coordinator-0.5.322 → code_coordinator-0.5.324}/coord/deploy/coord-notify.timer +0 -0
  122. {code_coordinator-0.5.322 → code_coordinator-0.5.324}/coord/deploy/coord-release-propagate.service +0 -0
  123. {code_coordinator-0.5.322 → code_coordinator-0.5.324}/coord/deploy/coord-release-propagate.timer +0 -0
  124. {code_coordinator-0.5.322 → code_coordinator-0.5.324}/coord/deploy/coord-release-window.service +0 -0
  125. {code_coordinator-0.5.322 → code_coordinator-0.5.324}/coord/deploy/coord-release-window.timer +0 -0
  126. {code_coordinator-0.5.322 → code_coordinator-0.5.324}/coord/deploy/coord-serve.service +0 -0
  127. {code_coordinator-0.5.322 → code_coordinator-0.5.324}/coord/deploy/coord-web-dist-build.service +0 -0
  128. {code_coordinator-0.5.322 → code_coordinator-0.5.324}/coord/deploy/coord-web-dist-build.timer +0 -0
  129. {code_coordinator-0.5.322 → code_coordinator-0.5.324}/coord/deploy/coord-web.service +0 -0
  130. {code_coordinator-0.5.322 → code_coordinator-0.5.324}/coord/deploy_manifest.py +0 -0
  131. {code_coordinator-0.5.322 → code_coordinator-0.5.324}/coord/deploy_units.py +0 -0
  132. {code_coordinator-0.5.322 → code_coordinator-0.5.324}/coord/deprecation_telemetry.py +0 -0
  133. {code_coordinator-0.5.322 → code_coordinator-0.5.324}/coord/deps.py +0 -0
  134. {code_coordinator-0.5.322 → code_coordinator-0.5.324}/coord/diagnose.py +0 -0
  135. {code_coordinator-0.5.322 → code_coordinator-0.5.324}/coord/dispatch.py +0 -0
  136. {code_coordinator-0.5.322 → code_coordinator-0.5.324}/coord/dist_name.py +0 -0
  137. {code_coordinator-0.5.322 → code_coordinator-0.5.324}/coord/drive.py +0 -0
  138. {code_coordinator-0.5.322 → code_coordinator-0.5.324}/coord/drive_queue.py +0 -0
  139. {code_coordinator-0.5.322 → code_coordinator-0.5.324}/coord/drive_state.py +0 -0
  140. {code_coordinator-0.5.322 → code_coordinator-0.5.324}/coord/events.py +0 -0
  141. {code_coordinator-0.5.322 → code_coordinator-0.5.324}/coord/failure_class.py +0 -0
  142. {code_coordinator-0.5.322 → code_coordinator-0.5.324}/coord/filelock.py +0 -0
  143. {code_coordinator-0.5.322 → code_coordinator-0.5.324}/coord/fleet_config_health.py +0 -0
  144. {code_coordinator-0.5.322 → code_coordinator-0.5.324}/coord/forge_availability.py +0 -0
  145. {code_coordinator-0.5.322 → code_coordinator-0.5.324}/coord/freshness.py +0 -0
  146. {code_coordinator-0.5.322 → code_coordinator-0.5.324}/coord/gate_a.py +0 -0
  147. {code_coordinator-0.5.322 → code_coordinator-0.5.324}/coord/gate_b.py +0 -0
  148. {code_coordinator-0.5.322 → code_coordinator-0.5.324}/coord/gate_snapshot.py +0 -0
  149. {code_coordinator-0.5.322 → code_coordinator-0.5.324}/coord/gates.py +0 -0
  150. {code_coordinator-0.5.322 → code_coordinator-0.5.324}/coord/github_ops.py +0 -0
  151. {code_coordinator-0.5.322 → code_coordinator-0.5.324}/coord/github_throttle.py +0 -0
  152. {code_coordinator-0.5.322 → code_coordinator-0.5.324}/coord/goal.py +0 -0
  153. {code_coordinator-0.5.322 → code_coordinator-0.5.324}/coord/graph_health.py +0 -0
  154. {code_coordinator-0.5.322 → code_coordinator-0.5.324}/coord/health/__init__.py +0 -0
  155. {code_coordinator-0.5.322 → code_coordinator-0.5.324}/coord/health/aggregate.py +0 -0
  156. {code_coordinator-0.5.322 → code_coordinator-0.5.324}/coord/health/checks/__init__.py +0 -0
  157. {code_coordinator-0.5.322 → code_coordinator-0.5.324}/coord/health/checks/_ci_pin.py +0 -0
  158. {code_coordinator-0.5.322 → code_coordinator-0.5.324}/coord/health/checks/agent_install.py +0 -0
  159. {code_coordinator-0.5.322 → code_coordinator-0.5.324}/coord/health/checks/cargo_targets.py +0 -0
  160. {code_coordinator-0.5.322 → code_coordinator-0.5.324}/coord/health/checks/claude_binary.py +0 -0
  161. {code_coordinator-0.5.322 → code_coordinator-0.5.324}/coord/health/checks/coord_tui_ci_pin.py +0 -0
  162. {code_coordinator-0.5.322 → code_coordinator-0.5.324}/coord/health/checks/coord_web_ci_pin.py +0 -0
  163. {code_coordinator-0.5.322 → code_coordinator-0.5.324}/coord/health/checks/deploy_lane_facts.py +0 -0
  164. {code_coordinator-0.5.322 → code_coordinator-0.5.324}/coord/health/checks/disk.py +0 -0
  165. {code_coordinator-0.5.322 → code_coordinator-0.5.324}/coord/health/checks/fleet_board.py +0 -0
  166. {code_coordinator-0.5.322 → code_coordinator-0.5.324}/coord/health/checks/fleet_deploy_lanes.py +0 -0
  167. {code_coordinator-0.5.322 → code_coordinator-0.5.324}/coord/health/checks/fleet_phantom.py +0 -0
  168. {code_coordinator-0.5.322 → code_coordinator-0.5.324}/coord/health/checks/fleet_unit_drift.py +0 -0
  169. {code_coordinator-0.5.322 → code_coordinator-0.5.324}/coord/health/checks/graph.py +0 -0
  170. {code_coordinator-0.5.322 → code_coordinator-0.5.324}/coord/health/checks/graphify_cli.py +0 -0
  171. {code_coordinator-0.5.322 → code_coordinator-0.5.324}/coord/health/checks/index_lock.py +0 -0
  172. {code_coordinator-0.5.322 → code_coordinator-0.5.324}/coord/health/checks/issues_sync_staleness.py +0 -0
  173. {code_coordinator-0.5.322 → code_coordinator-0.5.324}/coord/health/checks/plan_usage.py +0 -0
  174. {code_coordinator-0.5.322 → code_coordinator-0.5.324}/coord/health/checks/release_cordon.py +0 -0
  175. {code_coordinator-0.5.322 → code_coordinator-0.5.324}/coord/health/checks/repo_state.py +0 -0
  176. {code_coordinator-0.5.322 → code_coordinator-0.5.324}/coord/health/checks/spawned_coord.py +0 -0
  177. {code_coordinator-0.5.322 → code_coordinator-0.5.324}/coord/health/checks/stalled_pipeline.py +0 -0
  178. {code_coordinator-0.5.322 → code_coordinator-0.5.324}/coord/health/checks/timer_active.py +0 -0
  179. {code_coordinator-0.5.322 → code_coordinator-0.5.324}/coord/health/checks/toolchain.py +0 -0
  180. {code_coordinator-0.5.322 → code_coordinator-0.5.324}/coord/health/checks/unit_drift.py +0 -0
  181. {code_coordinator-0.5.322 → code_coordinator-0.5.324}/coord/health/checks/unit_enablement.py +0 -0
  182. {code_coordinator-0.5.322 → code_coordinator-0.5.324}/coord/health/checks/wedged_drive_queue.py +0 -0
  183. {code_coordinator-0.5.322 → code_coordinator-0.5.324}/coord/health/checks/worktrees.py +0 -0
  184. {code_coordinator-0.5.322 → code_coordinator-0.5.324}/coord/health/cli.py +0 -0
  185. {code_coordinator-0.5.322 → code_coordinator-0.5.324}/coord/health/context.py +0 -0
  186. {code_coordinator-0.5.322 → code_coordinator-0.5.324}/coord/health/fleet_snapshot.py +0 -0
  187. {code_coordinator-0.5.322 → code_coordinator-0.5.324}/coord/health/models.py +0 -0
  188. {code_coordinator-0.5.322 → code_coordinator-0.5.324}/coord/health/pypi.py +0 -0
  189. {code_coordinator-0.5.322 → code_coordinator-0.5.324}/coord/health/registry.py +0 -0
  190. {code_coordinator-0.5.322 → code_coordinator-0.5.324}/coord/health/render.py +0 -0
  191. {code_coordinator-0.5.322 → code_coordinator-0.5.324}/coord/health/units.py +0 -0
  192. {code_coordinator-0.5.322 → code_coordinator-0.5.324}/coord/hooks.py +0 -0
  193. {code_coordinator-0.5.322 → code_coordinator-0.5.324}/coord/housekeeping.py +0 -0
  194. {code_coordinator-0.5.322 → code_coordinator-0.5.324}/coord/interactive.py +0 -0
  195. {code_coordinator-0.5.322 → code_coordinator-0.5.324}/coord/issue_store.py +0 -0
  196. {code_coordinator-0.5.322 → code_coordinator-0.5.324}/coord/issues_sync_status.py +0 -0
  197. {code_coordinator-0.5.322 → code_coordinator-0.5.324}/coord/liveness_auditor.py +0 -0
  198. {code_coordinator-0.5.322 → code_coordinator-0.5.324}/coord/machine_onboard.py +0 -0
  199. {code_coordinator-0.5.322 → code_coordinator-0.5.324}/coord/machine_pause.py +0 -0
  200. {code_coordinator-0.5.322 → code_coordinator-0.5.324}/coord/merge_queue.py +0 -0
  201. {code_coordinator-0.5.322 → code_coordinator-0.5.324}/coord/milestone_chat.py +0 -0
  202. {code_coordinator-0.5.322 → code_coordinator-0.5.324}/coord/milestone_dispatch.py +0 -0
  203. {code_coordinator-0.5.322 → code_coordinator-0.5.324}/coord/milestone_gate.py +0 -0
  204. {code_coordinator-0.5.322 → code_coordinator-0.5.324}/coord/milestone_order.py +0 -0
  205. {code_coordinator-0.5.322 → code_coordinator-0.5.324}/coord/mock_author.py +0 -0
  206. {code_coordinator-0.5.322 → code_coordinator-0.5.324}/coord/models.py +0 -0
  207. {code_coordinator-0.5.322 → code_coordinator-0.5.324}/coord/network.py +0 -0
  208. {code_coordinator-0.5.322 → code_coordinator-0.5.324}/coord/new_issue_chat.py +0 -0
  209. {code_coordinator-0.5.322 → code_coordinator-0.5.324}/coord/notifier/__init__.py +0 -0
  210. {code_coordinator-0.5.322 → code_coordinator-0.5.324}/coord/notifier/baseline.py +0 -0
  211. {code_coordinator-0.5.322 → code_coordinator-0.5.324}/coord/notifier/cli.py +0 -0
  212. {code_coordinator-0.5.322 → code_coordinator-0.5.324}/coord/notifier/collect.py +0 -0
  213. {code_coordinator-0.5.322 → code_coordinator-0.5.324}/coord/notifier/digest.py +0 -0
  214. {code_coordinator-0.5.322 → code_coordinator-0.5.324}/coord/notifier/models.py +0 -0
  215. {code_coordinator-0.5.322 → code_coordinator-0.5.324}/coord/notifier/predicate.py +0 -0
  216. {code_coordinator-0.5.322 → code_coordinator-0.5.324}/coord/notifier/service.py +0 -0
  217. {code_coordinator-0.5.322 → code_coordinator-0.5.324}/coord/notifier/store.py +0 -0
  218. {code_coordinator-0.5.322 → code_coordinator-0.5.324}/coord/notifier/transport.py +0 -0
  219. {code_coordinator-0.5.322 → code_coordinator-0.5.324}/coord/notify.py +0 -0
  220. {code_coordinator-0.5.322 → code_coordinator-0.5.324}/coord/openapi.py +0 -0
  221. {code_coordinator-0.5.322 → code_coordinator-0.5.324}/coord/overlap_fence.py +0 -0
  222. {code_coordinator-0.5.322 → code_coordinator-0.5.324}/coord/overlap_predict.py +0 -0
  223. {code_coordinator-0.5.322 → code_coordinator-0.5.324}/coord/parentage.py +0 -0
  224. {code_coordinator-0.5.322 → code_coordinator-0.5.324}/coord/parentage_github.py +0 -0
  225. {code_coordinator-0.5.322 → code_coordinator-0.5.324}/coord/pipeline.py +0 -0
  226. {code_coordinator-0.5.322 → code_coordinator-0.5.324}/coord/plan_parser.py +0 -0
  227. {code_coordinator-0.5.322 → code_coordinator-0.5.324}/coord/plans.py +0 -0
  228. {code_coordinator-0.5.322 → code_coordinator-0.5.324}/coord/platform_paths.py +0 -0
  229. {code_coordinator-0.5.322 → code_coordinator-0.5.324}/coord/portal_bridge.py +0 -0
  230. {code_coordinator-0.5.322 → code_coordinator-0.5.324}/coord/pr_body_lint.py +0 -0
  231. {code_coordinator-0.5.322 → code_coordinator-0.5.324}/coord/prereqs.py +0 -0
  232. {code_coordinator-0.5.322 → code_coordinator-0.5.324}/coord/progress.py +0 -0
  233. {code_coordinator-0.5.322 → code_coordinator-0.5.324}/coord/providers/__init__.py +0 -0
  234. {code_coordinator-0.5.322 → code_coordinator-0.5.324}/coord/providers/base.py +0 -0
  235. {code_coordinator-0.5.322 → code_coordinator-0.5.324}/coord/providers/claude.py +0 -0
  236. {code_coordinator-0.5.322 → code_coordinator-0.5.324}/coord/providers/claude_pty.py +0 -0
  237. {code_coordinator-0.5.322 → code_coordinator-0.5.324}/coord/providers/opencode.py +0 -0
  238. {code_coordinator-0.5.322 → code_coordinator-0.5.324}/coord/queue_diagnose.py +0 -0
  239. {code_coordinator-0.5.322 → code_coordinator-0.5.324}/coord/reconcile.py +0 -0
  240. {code_coordinator-0.5.322 → code_coordinator-0.5.324}/coord/reconcile_tick.py +0 -0
  241. {code_coordinator-0.5.322 → code_coordinator-0.5.324}/coord/refine_chat.py +0 -0
  242. {code_coordinator-0.5.322 → code_coordinator-0.5.324}/coord/release_cordon.py +0 -0
  243. {code_coordinator-0.5.322 → code_coordinator-0.5.324}/coord/release_propagate.py +0 -0
  244. {code_coordinator-0.5.322 → code_coordinator-0.5.324}/coord/release_verify.py +0 -0
  245. {code_coordinator-0.5.322 → code_coordinator-0.5.324}/coord/release_window.py +0 -0
  246. {code_coordinator-0.5.322 → code_coordinator-0.5.324}/coord/repo_dormancy.py +0 -0
  247. {code_coordinator-0.5.322 → code_coordinator-0.5.324}/coord/repo_edit.py +0 -0
  248. {code_coordinator-0.5.322 → code_coordinator-0.5.324}/coord/repo_onboard.py +0 -0
  249. {code_coordinator-0.5.322 → code_coordinator-0.5.324}/coord/reports.py +0 -0
  250. {code_coordinator-0.5.322 → code_coordinator-0.5.324}/coord/rest_schema.py +0 -0
  251. {code_coordinator-0.5.322 → code_coordinator-0.5.324}/coord/revalidate.py +0 -0
  252. {code_coordinator-0.5.322 → code_coordinator-0.5.324}/coord/review.py +0 -0
  253. {code_coordinator-0.5.322 → code_coordinator-0.5.324}/coord/scorecard.py +0 -0
  254. {code_coordinator-0.5.322 → code_coordinator-0.5.324}/coord/self_health.py +0 -0
  255. {code_coordinator-0.5.322 → code_coordinator-0.5.324}/coord/skills/coord-dispatch-verbs/SKILL.md +0 -0
  256. {code_coordinator-0.5.322 → code_coordinator-0.5.324}/coord/skills/drive-queue-preflight/SKILL.md +0 -0
  257. {code_coordinator-0.5.322 → code_coordinator-0.5.324}/coord/skills/fleet-restart-safety/SKILL.md +0 -0
  258. {code_coordinator-0.5.322 → code_coordinator-0.5.324}/coord/skills/merge-stuck-triage/SKILL.md +0 -0
  259. {code_coordinator-0.5.322 → code_coordinator-0.5.324}/coord/skills/pipeline-limbo-triage/SKILL.md +0 -0
  260. {code_coordinator-0.5.322 → code_coordinator-0.5.324}/coord/skills/portal-followup/SKILL.md +0 -0
  261. {code_coordinator-0.5.322 → code_coordinator-0.5.324}/coord/skills/release-now/SKILL.md +0 -0
  262. {code_coordinator-0.5.322 → code_coordinator-0.5.324}/coord/skills/review-verdict-recovery/SKILL.md +0 -0
  263. {code_coordinator-0.5.322 → code_coordinator-0.5.324}/coord/skills/tui-quadraui-workflow/SKILL.md +0 -0
  264. {code_coordinator-0.5.322 → code_coordinator-0.5.324}/coord/skills/update-issue/SKILL.md +0 -0
  265. {code_coordinator-0.5.322 → code_coordinator-0.5.324}/coord/smoke.py +0 -0
  266. {code_coordinator-0.5.322 → code_coordinator-0.5.324}/coord/spend_ceiling.py +0 -0
  267. {code_coordinator-0.5.322 → code_coordinator-0.5.324}/coord/split_work.py +0 -0
  268. {code_coordinator-0.5.322 → code_coordinator-0.5.324}/coord/sql.py +0 -0
  269. {code_coordinator-0.5.322 → code_coordinator-0.5.324}/coord/stage_projection.py +0 -0
  270. {code_coordinator-0.5.322 → code_coordinator-0.5.324}/coord/state.py +0 -0
  271. {code_coordinator-0.5.322 → code_coordinator-0.5.324}/coord/store_migrate.py +0 -0
  272. {code_coordinator-0.5.322 → code_coordinator-0.5.324}/coord/test_author.py +0 -0
  273. {code_coordinator-0.5.322 → code_coordinator-0.5.324}/coord/test_chat.py +0 -0
  274. {code_coordinator-0.5.322 → code_coordinator-0.5.324}/coord/test_orchestrator.py +0 -0
  275. {code_coordinator-0.5.322 → code_coordinator-0.5.324}/coord/test_report.py +0 -0
  276. {code_coordinator-0.5.322 → code_coordinator-0.5.324}/coord/tui_release.py +0 -0
  277. {code_coordinator-0.5.322 → code_coordinator-0.5.324}/coord/usage.py +0 -0
  278. {code_coordinator-0.5.322 → code_coordinator-0.5.324}/coord/usage_limits.py +0 -0
  279. {code_coordinator-0.5.322 → code_coordinator-0.5.324}/coord/usage_rollup.py +0 -0
  280. {code_coordinator-0.5.322 → code_coordinator-0.5.324}/coord/worker_events.py +0 -0
  281. {code_coordinator-0.5.322 → code_coordinator-0.5.324}/coordinator.example.yml +0 -0
  282. {code_coordinator-0.5.322 → code_coordinator-0.5.324}/deploy/coord-agent.service +0 -0
  283. {code_coordinator-0.5.322 → code_coordinator-0.5.324}/deploy/coord-db-backup.service +0 -0
  284. {code_coordinator-0.5.322 → code_coordinator-0.5.324}/deploy/coord-db-backup.sh +0 -0
  285. {code_coordinator-0.5.322 → code_coordinator-0.5.324}/deploy/coord-db-backup.timer +0 -0
  286. {code_coordinator-0.5.322 → code_coordinator-0.5.324}/deploy/coord-drive-queue.service +0 -0
  287. {code_coordinator-0.5.322 → code_coordinator-0.5.324}/deploy/coord-drive-queue.timer +0 -0
  288. {code_coordinator-0.5.322 → code_coordinator-0.5.324}/deploy/coord-failure-notify.service +0 -0
  289. {code_coordinator-0.5.322 → code_coordinator-0.5.324}/deploy/coord-failure-notify.sh +0 -0
  290. {code_coordinator-0.5.322 → code_coordinator-0.5.324}/deploy/coord-fleet-watchdog.service +0 -0
  291. {code_coordinator-0.5.322 → code_coordinator-0.5.324}/deploy/coord-fleet-watchdog.timer +0 -0
  292. {code_coordinator-0.5.322 → code_coordinator-0.5.324}/deploy/coord-notify.service +0 -0
  293. {code_coordinator-0.5.322 → code_coordinator-0.5.324}/deploy/coord-notify.timer +0 -0
  294. {code_coordinator-0.5.322 → code_coordinator-0.5.324}/deploy/coord-release-propagate.service +0 -0
  295. {code_coordinator-0.5.322 → code_coordinator-0.5.324}/deploy/coord-release-propagate.timer +0 -0
  296. {code_coordinator-0.5.322 → code_coordinator-0.5.324}/deploy/coord-release-window.service +0 -0
  297. {code_coordinator-0.5.322 → code_coordinator-0.5.324}/deploy/coord-release-window.timer +0 -0
  298. {code_coordinator-0.5.322 → code_coordinator-0.5.324}/deploy/coord-serve.service +0 -0
  299. {code_coordinator-0.5.322 → code_coordinator-0.5.324}/deploy/coord-web-dist-build.service +0 -0
  300. {code_coordinator-0.5.322 → code_coordinator-0.5.324}/deploy/coord-web-dist-build.sh +0 -0
  301. {code_coordinator-0.5.322 → code_coordinator-0.5.324}/deploy/coord-web-dist-build.timer +0 -0
  302. {code_coordinator-0.5.322 → code_coordinator-0.5.324}/deploy/coord-web-rollback.sh +0 -0
  303. {code_coordinator-0.5.322 → code_coordinator-0.5.324}/deploy/coord-web.service +0 -0
  304. {code_coordinator-0.5.322 → code_coordinator-0.5.324}/deploy/node-shim.sh +0 -0
  305. {code_coordinator-0.5.322 → code_coordinator-0.5.324}/docs/ADR_COORD_TUI_CI.md +0 -0
  306. {code_coordinator-0.5.322 → code_coordinator-0.5.324}/docs/ADR_COORD_WEB_ACCEPTANCE_SUITE.md +0 -0
  307. {code_coordinator-0.5.322 → code_coordinator-0.5.324}/docs/ADR_COORD_WEB_CI.md +0 -0
  308. {code_coordinator-0.5.322 → code_coordinator-0.5.324}/docs/ADR_COORD_WEB_DIST.md +0 -0
  309. {code_coordinator-0.5.322 → code_coordinator-0.5.324}/docs/ADR_PY_RUST_MIRRORS.md +0 -0
  310. {code_coordinator-0.5.322 → code_coordinator-0.5.324}/docs/AGENT_OPERATIONS.md +0 -0
  311. {code_coordinator-0.5.322 → code_coordinator-0.5.324}/docs/ARCHITECTURE.md +0 -0
  312. {code_coordinator-0.5.322 → code_coordinator-0.5.324}/docs/ARCH_SECURITY_GATES.md +0 -0
  313. {code_coordinator-0.5.322 → code_coordinator-0.5.324}/docs/COCKPIT.md +0 -0
  314. {code_coordinator-0.5.322 → code_coordinator-0.5.324}/docs/CONTROL_CENTER.md +0 -0
  315. {code_coordinator-0.5.322 → code_coordinator-0.5.324}/docs/COST_DISCIPLINE.md +0 -0
  316. {code_coordinator-0.5.322 → code_coordinator-0.5.324}/docs/CROSS_PLATFORM.md +0 -0
  317. {code_coordinator-0.5.322 → code_coordinator-0.5.324}/docs/CUSTOMER_FACING_APPS.md +0 -0
  318. {code_coordinator-0.5.322 → code_coordinator-0.5.324}/docs/CUSTOMER_PORTAL.md +0 -0
  319. {code_coordinator-0.5.322 → code_coordinator-0.5.324}/docs/DRIVE_QUEUE.md +0 -0
  320. {code_coordinator-0.5.322 → code_coordinator-0.5.324}/docs/EPHEMERAL_WORKERS.md +0 -0
  321. {code_coordinator-0.5.322 → code_coordinator-0.5.324}/docs/FORGE_MIGRATION.md +0 -0
  322. {code_coordinator-0.5.322 → code_coordinator-0.5.324}/docs/GRAPHIFY_SETUP.md +0 -0
  323. {code_coordinator-0.5.322 → code_coordinator-0.5.324}/docs/ISSUE_GUIDANCE.md +0 -0
  324. {code_coordinator-0.5.322 → code_coordinator-0.5.324}/docs/MAC_MINI.md +0 -0
  325. {code_coordinator-0.5.322 → code_coordinator-0.5.324}/docs/MERGE_AUTO_DRAIN_TRUST_BAR.md +0 -0
  326. {code_coordinator-0.5.322 → code_coordinator-0.5.324}/docs/NOTIFIER.md +0 -0
  327. {code_coordinator-0.5.322 → code_coordinator-0.5.324}/docs/OPENCODE_VERIFICATION.md +0 -0
  328. {code_coordinator-0.5.322 → code_coordinator-0.5.324}/docs/OPERATING_GOTCHAS.md +0 -0
  329. {code_coordinator-0.5.322 → code_coordinator-0.5.324}/docs/OPERATOR_GUIDES.md +0 -0
  330. {code_coordinator-0.5.322 → code_coordinator-0.5.324}/docs/ORACLE_LOOP.md +0 -0
  331. {code_coordinator-0.5.322 → code_coordinator-0.5.324}/docs/PHONE_WEBAPP.md +0 -0
  332. {code_coordinator-0.5.322 → code_coordinator-0.5.324}/docs/PIPELINE_V2.md +0 -0
  333. {code_coordinator-0.5.322 → code_coordinator-0.5.324}/docs/PLATFORM_EVOLUTION.md +0 -0
  334. {code_coordinator-0.5.322 → code_coordinator-0.5.324}/docs/SECOND_BACKEND.md +0 -0
  335. {code_coordinator-0.5.322 → code_coordinator-0.5.324}/docs/STORE_SERVICE.md +0 -0
  336. {code_coordinator-0.5.322 → code_coordinator-0.5.324}/docs/TEST_FIRST_BUG_LANE.md +0 -0
  337. {code_coordinator-0.5.322 → code_coordinator-0.5.324}/docs/WEB_CONTROL_CENTER.md +0 -0
  338. {code_coordinator-0.5.322 → code_coordinator-0.5.324}/docs/WSL_WINDOWS_WORKER.md +0 -0
  339. {code_coordinator-0.5.322 → code_coordinator-0.5.324}/docs/mocks/web/README.md +0 -0
  340. {code_coordinator-0.5.322 → code_coordinator-0.5.324}/docs/mocks/web/_tokens.css +0 -0
  341. {code_coordinator-0.5.322 → code_coordinator-0.5.324}/docs/mocks/web/issue-detail.html +0 -0
  342. {code_coordinator-0.5.322 → code_coordinator-0.5.324}/docs/mocks/web/pipeline-narrow.html +0 -0
  343. {code_coordinator-0.5.322 → code_coordinator-0.5.324}/docs/mocks/web/pipeline-wide.html +0 -0
  344. {code_coordinator-0.5.322 → code_coordinator-0.5.324}/graphify-out/.gitignore +0 -0
  345. {code_coordinator-0.5.322 → code_coordinator-0.5.324}/install-agent.sh +0 -0
  346. {code_coordinator-0.5.322 → code_coordinator-0.5.324}/pyproject.toml +0 -0
  347. {code_coordinator-0.5.322 → code_coordinator-0.5.324}/scripts/audit_review_verdict_overrides.py +0 -0
  348. {code_coordinator-0.5.322 → code_coordinator-0.5.324}/scripts/azure-workers/bootstrap-shared.sh +0 -0
  349. {code_coordinator-0.5.322 → code_coordinator-0.5.324}/scripts/azure-workers/build-worker-image.sh +0 -0
  350. {code_coordinator-0.5.322 → code_coordinator-0.5.324}/scripts/azure-workers/coordinator-machine.py +0 -0
  351. {code_coordinator-0.5.322 → code_coordinator-0.5.324}/scripts/azure-workers/epic-down.sh +0 -0
  352. {code_coordinator-0.5.322 → code_coordinator-0.5.324}/scripts/azure-workers/epic-up.sh +0 -0
  353. {code_coordinator-0.5.322 → code_coordinator-0.5.324}/scripts/azure-workers/preflight.sh +0 -0
  354. {code_coordinator-0.5.322 → code_coordinator-0.5.324}/scripts/azure-workers/provision-worker.sh +0 -0
  355. {code_coordinator-0.5.322 → code_coordinator-0.5.324}/scripts/azure-workers/scrub-and-generalize.sh +0 -0
  356. {code_coordinator-0.5.322 → code_coordinator-0.5.324}/scripts/azure-workers/tailnet-acl.hujson +0 -0
  357. {code_coordinator-0.5.322 → code_coordinator-0.5.324}/scripts/azure-workers/verify-github-token.sh +0 -0
  358. {code_coordinator-0.5.322 → code_coordinator-0.5.324}/scripts/check_gh_argv_containment.py +0 -0
  359. {code_coordinator-0.5.322 → code_coordinator-0.5.324}/scripts/codegen.py +0 -0
  360. {code_coordinator-0.5.322 → code_coordinator-0.5.324}/scripts/coord-test-runner.sh +0 -0
  361. {code_coordinator-0.5.322 → code_coordinator-0.5.324}/scripts/coord-tui-scaffold/.github/coord-ci-acceptance.yml +0 -0
  362. {code_coordinator-0.5.322 → code_coordinator-0.5.324}/scripts/coord-tui-scaffold/.github/workflows/cargo-test.yml +0 -0
  363. {code_coordinator-0.5.322 → code_coordinator-0.5.324}/scripts/coord-tui-scaffold/.github/workflows/codegen-drift.yml +0 -0
  364. {code_coordinator-0.5.322 → code_coordinator-0.5.324}/scripts/coord-tui-scaffold/CLAUDE.md +0 -0
  365. {code_coordinator-0.5.322 → code_coordinator-0.5.324}/scripts/coord-venv-rollback.sh +0 -0
  366. {code_coordinator-0.5.322 → code_coordinator-0.5.324}/scripts/drive-batch.sh +0 -0
  367. {code_coordinator-0.5.322 → code_coordinator-0.5.324}/scripts/extract-coord-tui.sh +0 -0
  368. {code_coordinator-0.5.322 → code_coordinator-0.5.324}/scripts/fleet_watchdog.py +0 -0
  369. {code_coordinator-0.5.322 → code_coordinator-0.5.324}/scripts/gen_board_fixture.py +0 -0
  370. {code_coordinator-0.5.322 → code_coordinator-0.5.324}/scripts/gen_mock_index.py +0 -0
  371. {code_coordinator-0.5.322 → code_coordinator-0.5.324}/scripts/next_release_tag.py +0 -0
  372. {code_coordinator-0.5.322 → code_coordinator-0.5.324}/scripts/run_tests_in_populated_home.sh +0 -0
  373. {code_coordinator-0.5.322 → code_coordinator-0.5.324}/scripts/run_tests_without_gh.sh +0 -0
  374. {code_coordinator-0.5.322 → code_coordinator-0.5.324}/scripts/smoke_437_interactive.py +0 -0
  375. {code_coordinator-0.5.322 → code_coordinator-0.5.324}/scripts/verify_878_review_capture.py +0 -0
  376. {code_coordinator-0.5.322 → code_coordinator-0.5.324}/scripts/verify_release_published.py +0 -0
  377. {code_coordinator-0.5.322 → code_coordinator-0.5.324}/scripts/verify_release_wheel.py +0 -0
  378. {code_coordinator-0.5.322 → code_coordinator-0.5.324}/setup.cfg +0 -0
  379. {code_coordinator-0.5.322 → code_coordinator-0.5.324}/tests/SMOKE_SET.md +0 -0
  380. {code_coordinator-0.5.322 → code_coordinator-0.5.324}/tests/__init__.py +0 -0
  381. {code_coordinator-0.5.322 → code_coordinator-0.5.324}/tests/acceptance/ms-37/conftest.py +0 -0
  382. {code_coordinator-0.5.322 → code_coordinator-0.5.324}/tests/acceptance/ms-37/contract.md +0 -0
  383. {code_coordinator-0.5.322 → code_coordinator-0.5.324}/tests/acceptance/ms-37/manifest.yml +0 -0
  384. {code_coordinator-0.5.322 → code_coordinator-0.5.324}/tests/acceptance/ms-37/test_usage_cli_1115.py +0 -0
  385. {code_coordinator-0.5.322 → code_coordinator-0.5.324}/tests/acceptance/ms-37/test_usage_core_1118.py +0 -0
  386. {code_coordinator-0.5.322 → code_coordinator-0.5.324}/tests/acceptance/ms-51/contract.md +0 -0
  387. {code_coordinator-0.5.322 → code_coordinator-0.5.324}/tests/acceptance/ms-51/home-active-extended.spec.ts +0 -0
  388. {code_coordinator-0.5.322 → code_coordinator-0.5.324}/tests/acceptance/ms-51/home-active.spec.ts +0 -0
  389. {code_coordinator-0.5.322 → code_coordinator-0.5.324}/tests/acceptance/ms-51/manifest.yml +0 -0
  390. {code_coordinator-0.5.322 → code_coordinator-0.5.324}/tests/acceptance/ms-51/mocks/home-active.html +0 -0
  391. {code_coordinator-0.5.322 → code_coordinator-0.5.324}/tests/acceptance/ms-51/tsconfig.json +0 -0
  392. {code_coordinator-0.5.322 → code_coordinator-0.5.324}/tests/acceptance/ms-example/mocks/home-active.html +0 -0
  393. {code_coordinator-0.5.322 → code_coordinator-0.5.324}/tests/backends.py +0 -0
  394. {code_coordinator-0.5.322 → code_coordinator-0.5.324}/tests/conftest.py +0 -0
  395. {code_coordinator-0.5.322 → code_coordinator-0.5.324}/tests/fixtures/board-pipeline-basic.json +0 -0
  396. {code_coordinator-0.5.322 → code_coordinator-0.5.324}/tests/fixtures/board-pipeline-terminal-gates.json +0 -0
  397. {code_coordinator-0.5.322 → code_coordinator-0.5.324}/tests/fixtures/opencode_run_failure_sample.jsonl +0 -0
  398. {code_coordinator-0.5.322 → code_coordinator-0.5.324}/tests/fixtures/opencode_run_length_sample.jsonl +0 -0
  399. {code_coordinator-0.5.322 → code_coordinator-0.5.324}/tests/fixtures/opencode_run_sample.jsonl +0 -0
  400. {code_coordinator-0.5.322 → code_coordinator-0.5.324}/tests/fixtures/playwright/all_pass.json +0 -0
  401. {code_coordinator-0.5.322 → code_coordinator-0.5.324}/tests/fixtures/playwright/global_setup_crash.json +0 -0
  402. {code_coordinator-0.5.322 → code_coordinator-0.5.324}/tests/fixtures/playwright/mixed_fail.json +0 -0
  403. {code_coordinator-0.5.322 → code_coordinator-0.5.324}/tests/fixtures/playwright/retry_then_pass.json +0 -0
  404. {code_coordinator-0.5.322 → code_coordinator-0.5.324}/tests/fixtures/playwright/retry_then_pass.junit.xml +0 -0
  405. {code_coordinator-0.5.322 → code_coordinator-0.5.324}/tests/fixtures/playwright/skip.json +0 -0
  406. {code_coordinator-0.5.322 → code_coordinator-0.5.324}/tests/fixtures/playwright/truncated.json +0 -0
  407. {code_coordinator-0.5.322 → code_coordinator-0.5.324}/tests/fixtures/test_report/cargo_compile_error.txt +0 -0
  408. {code_coordinator-0.5.322 → code_coordinator-0.5.324}/tests/fixtures/test_report/cargo_multi_target_failures.txt +0 -0
  409. {code_coordinator-0.5.322 → code_coordinator-0.5.324}/tests/fixtures/test_report/cargo_no_parseable_failures.txt +0 -0
  410. {code_coordinator-0.5.322 → code_coordinator-0.5.324}/tests/fixtures/test_report/pytest_collection_error.txt +0 -0
  411. {code_coordinator-0.5.322 → code_coordinator-0.5.324}/tests/fixtures/test_report/pytest_error_string_in_body.txt +0 -0
  412. {code_coordinator-0.5.322 → code_coordinator-0.5.324}/tests/fixtures/test_report/pytest_internal_error.txt +0 -0
  413. {code_coordinator-0.5.322 → code_coordinator-0.5.324}/tests/fixtures/test_report/pytest_mixed_failures.txt +0 -0
  414. {code_coordinator-0.5.322 → code_coordinator-0.5.324}/tests/fixtures/test_report/pytest_no_parseable_failures.txt +0 -0
  415. {code_coordinator-0.5.322 → code_coordinator-0.5.324}/tests/test_acceptance.py +0 -0
  416. {code_coordinator-0.5.322 → code_coordinator-0.5.324}/tests/test_acceptance_drivers.py +0 -0
  417. {code_coordinator-0.5.322 → code_coordinator-0.5.324}/tests/test_agent.py +0 -0
  418. {code_coordinator-0.5.322 → code_coordinator-0.5.324}/tests/test_agent_api_error.py +0 -0
  419. {code_coordinator-0.5.322 → code_coordinator-0.5.324}/tests/test_agent_app.py +0 -0
  420. {code_coordinator-0.5.322 → code_coordinator-0.5.324}/tests/test_agent_branch_base.py +0 -0
  421. {code_coordinator-0.5.322 → code_coordinator-0.5.324}/tests/test_agent_branch_capture.py +0 -0
  422. {code_coordinator-0.5.322 → code_coordinator-0.5.324}/tests/test_agent_config_free_1712.py +0 -0
  423. {code_coordinator-0.5.322 → code_coordinator-0.5.324}/tests/test_agent_deploy_units_endpoint.py +0 -0
  424. {code_coordinator-0.5.322 → code_coordinator-0.5.324}/tests/test_agent_dirty_worktree.py +0 -0
  425. {code_coordinator-0.5.322 → code_coordinator-0.5.324}/tests/test_agent_drive_queue_reconcile_2373.py +0 -0
  426. {code_coordinator-0.5.322 → code_coordinator-0.5.324}/tests/test_agent_graph_self_heal.py +0 -0
  427. {code_coordinator-0.5.322 → code_coordinator-0.5.324}/tests/test_agent_health_h3.py +0 -0
  428. {code_coordinator-0.5.322 → code_coordinator-0.5.324}/tests/test_agent_idle_restart.py +0 -0
  429. {code_coordinator-0.5.322 → code_coordinator-0.5.324}/tests/test_agent_push_failure.py +0 -0
  430. {code_coordinator-0.5.322 → code_coordinator-0.5.324}/tests/test_agent_reap.py +0 -0
  431. {code_coordinator-0.5.322 → code_coordinator-0.5.324}/tests/test_agent_repos_and_pull.py +0 -0
  432. {code_coordinator-0.5.322 → code_coordinator-0.5.324}/tests/test_agent_restart_services_endpoint.py +0 -0
  433. {code_coordinator-0.5.322 → code_coordinator-0.5.324}/tests/test_agent_skills_self_heal.py +0 -0
  434. {code_coordinator-0.5.322 → code_coordinator-0.5.324}/tests/test_agent_startup_diagnostics.py +0 -0
  435. {code_coordinator-0.5.322 → code_coordinator-0.5.324}/tests/test_agent_update.py +0 -0
  436. {code_coordinator-0.5.322 → code_coordinator-0.5.324}/tests/test_agent_update_bluegreen.py +0 -0
  437. {code_coordinator-0.5.322 → code_coordinator-0.5.324}/tests/test_agent_usage_limit.py +0 -0
  438. {code_coordinator-0.5.322 → code_coordinator-0.5.324}/tests/test_agent_zero_commit.py +0 -0
  439. {code_coordinator-0.5.322 → code_coordinator-0.5.324}/tests/test_ambient_home_isolation.py +0 -0
  440. {code_coordinator-0.5.322 → code_coordinator-0.5.324}/tests/test_approve_dependency_busy_2804.py +0 -0
  441. {code_coordinator-0.5.322 → code_coordinator-0.5.324}/tests/test_approve_reject_plan.py +0 -0
  442. {code_coordinator-0.5.322 → code_coordinator-0.5.324}/tests/test_approve_usage_gate.py +0 -0
  443. {code_coordinator-0.5.322 → code_coordinator-0.5.324}/tests/test_approved_work_2532.py +0 -0
  444. {code_coordinator-0.5.322 → code_coordinator-0.5.324}/tests/test_assignment_already_recorded_daemon.py +0 -0
  445. {code_coordinator-0.5.322 → code_coordinator-0.5.324}/tests/test_audit_log.py +0 -0
  446. {code_coordinator-0.5.322 → code_coordinator-0.5.324}/tests/test_audit_outcome.py +0 -0
  447. {code_coordinator-0.5.322 → code_coordinator-0.5.324}/tests/test_audit_query.py +0 -0
  448. {code_coordinator-0.5.322 → code_coordinator-0.5.324}/tests/test_auto_loop.py +0 -0
  449. {code_coordinator-0.5.322 → code_coordinator-0.5.324}/tests/test_auto_release_publish_2035.py +0 -0
  450. {code_coordinator-0.5.322 → code_coordinator-0.5.324}/tests/test_backend_selection.py +0 -0
  451. {code_coordinator-0.5.322 → code_coordinator-0.5.324}/tests/test_base_checkout_restore.py +0 -0
  452. {code_coordinator-0.5.322 → code_coordinator-0.5.324}/tests/test_block_log.py +0 -0
  453. {code_coordinator-0.5.322 → code_coordinator-0.5.324}/tests/test_board_cap_762.py +0 -0
  454. {code_coordinator-0.5.322 → code_coordinator-0.5.324}/tests/test_board_fixture.py +0 -0
  455. {code_coordinator-0.5.322 → code_coordinator-0.5.324}/tests/test_board_read_path.py +0 -0
  456. {code_coordinator-0.5.322 → code_coordinator-0.5.324}/tests/test_board_schema.py +0 -0
  457. {code_coordinator-0.5.322 → code_coordinator-0.5.324}/tests/test_board_service.py +0 -0
  458. {code_coordinator-0.5.322 → code_coordinator-0.5.324}/tests/test_board_state.py +0 -0
  459. {code_coordinator-0.5.322 → code_coordinator-0.5.324}/tests/test_board_wire.py +0 -0
  460. {code_coordinator-0.5.322 → code_coordinator-0.5.324}/tests/test_brain.py +0 -0
  461. {code_coordinator-0.5.322 → code_coordinator-0.5.324}/tests/test_branch_model.py +0 -0
  462. {code_coordinator-0.5.322 → code_coordinator-0.5.324}/tests/test_bug_intake.py +0 -0
  463. {code_coordinator-0.5.322 → code_coordinator-0.5.324}/tests/test_build_worker_image_env_update.py +0 -0
  464. {code_coordinator-0.5.322 → code_coordinator-0.5.324}/tests/test_cargo_cache.py +0 -0
  465. {code_coordinator-0.5.322 → code_coordinator-0.5.324}/tests/test_check_gh_argv_containment.py +0 -0
  466. {code_coordinator-0.5.322 → code_coordinator-0.5.324}/tests/test_ci_acceptance_gate_1950.py +0 -0
  467. {code_coordinator-0.5.322 → code_coordinator-0.5.324}/tests/test_ci_fix.py +0 -0
  468. {code_coordinator-0.5.322 → code_coordinator-0.5.324}/tests/test_ci_gitlab.py +0 -0
  469. {code_coordinator-0.5.322 → code_coordinator-0.5.324}/tests/test_ci_parity_2091.py +0 -0
  470. {code_coordinator-0.5.322 → code_coordinator-0.5.324}/tests/test_ci_store.py +0 -0
  471. {code_coordinator-0.5.322 → code_coordinator-0.5.324}/tests/test_claim.py +0 -0
  472. {code_coordinator-0.5.322 → code_coordinator-0.5.324}/tests/test_claude_md_budget.py +0 -0
  473. {code_coordinator-0.5.322 → code_coordinator-0.5.324}/tests/test_cli_acceptance.py +0 -0
  474. {code_coordinator-0.5.322 → code_coordinator-0.5.324}/tests/test_cli_assign.py +0 -0
  475. {code_coordinator-0.5.322 → code_coordinator-0.5.324}/tests/test_cli_assign_interactive_oracle_gate.py +0 -0
  476. {code_coordinator-0.5.322 → code_coordinator-0.5.324}/tests/test_cli_assign_interactive_remote.py +0 -0
  477. {code_coordinator-0.5.322 → code_coordinator-0.5.324}/tests/test_cli_assign_provider.py +0 -0
  478. {code_coordinator-0.5.322 → code_coordinator-0.5.324}/tests/test_cli_assign_repo_drift_2219.py +0 -0
  479. {code_coordinator-0.5.322 → code_coordinator-0.5.324}/tests/test_cli_audit.py +0 -0
  480. {code_coordinator-0.5.322 → code_coordinator-0.5.324}/tests/test_cli_chat_continue.py +0 -0
  481. {code_coordinator-0.5.322 → code_coordinator-0.5.324}/tests/test_cli_decide.py +0 -0
  482. {code_coordinator-0.5.322 → code_coordinator-0.5.324}/tests/test_cli_diagnose_capability_rules.py +0 -0
  483. {code_coordinator-0.5.322 → code_coordinator-0.5.324}/tests/test_cli_diagnose_config_provenance.py +0 -0
  484. {code_coordinator-0.5.322 → code_coordinator-0.5.324}/tests/test_cli_diagnose_forge_availability.py +0 -0
  485. {code_coordinator-0.5.322 → code_coordinator-0.5.324}/tests/test_cli_diagnose_graph.py +0 -0
  486. {code_coordinator-0.5.322 → code_coordinator-0.5.324}/tests/test_cli_diagnose_self.py +0 -0
  487. {code_coordinator-0.5.322 → code_coordinator-0.5.324}/tests/test_cli_diagnose_test_coverage.py +0 -0
  488. {code_coordinator-0.5.322 → code_coordinator-0.5.324}/tests/test_cli_doctor.py +0 -0
  489. {code_coordinator-0.5.322 → code_coordinator-0.5.324}/tests/test_cli_doctor_config_free_1801.py +0 -0
  490. {code_coordinator-0.5.322 → code_coordinator-0.5.324}/tests/test_cli_doctor_config_mismatch_1712.py +0 -0
  491. {code_coordinator-0.5.322 → code_coordinator-0.5.324}/tests/test_cli_drive.py +0 -0
  492. {code_coordinator-0.5.322 → code_coordinator-0.5.324}/tests/test_cli_drive_queue.py +0 -0
  493. {code_coordinator-0.5.322 → code_coordinator-0.5.324}/tests/test_cli_escalate.py +0 -0
  494. {code_coordinator-0.5.322 → code_coordinator-0.5.324}/tests/test_cli_fix_headless_review.py +0 -0
  495. {code_coordinator-0.5.322 → code_coordinator-0.5.324}/tests/test_cli_gate_a.py +0 -0
  496. {code_coordinator-0.5.322 → code_coordinator-0.5.324}/tests/test_cli_install_drift.py +0 -0
  497. {code_coordinator-0.5.322 → code_coordinator-0.5.324}/tests/test_cli_install_skills.py +0 -0
  498. {code_coordinator-0.5.322 → code_coordinator-0.5.324}/tests/test_cli_issue_comment.py +0 -0
  499. {code_coordinator-0.5.322 → code_coordinator-0.5.324}/tests/test_cli_issue_create_label.py +0 -0
  500. {code_coordinator-0.5.322 → code_coordinator-0.5.324}/tests/test_cli_issue_reopen.py +0 -0
  501. {code_coordinator-0.5.322 → code_coordinator-0.5.324}/tests/test_cli_issue_view_list.py +0 -0
  502. {code_coordinator-0.5.322 → code_coordinator-0.5.324}/tests/test_cli_merge.py +0 -0
  503. {code_coordinator-0.5.322 → code_coordinator-0.5.324}/tests/test_cli_milestone_assign.py +0 -0
  504. {code_coordinator-0.5.322 → code_coordinator-0.5.324}/tests/test_cli_milestone_capture.py +0 -0
  505. {code_coordinator-0.5.322 → code_coordinator-0.5.324}/tests/test_cli_milestone_chat_add_child.py +0 -0
  506. {code_coordinator-0.5.322 → code_coordinator-0.5.324}/tests/test_cli_milestone_dispatch.py +0 -0
  507. {code_coordinator-0.5.322 → code_coordinator-0.5.324}/tests/test_cli_milestone_gate_b.py +0 -0
  508. {code_coordinator-0.5.322 → code_coordinator-0.5.324}/tests/test_cli_milestone_gate_c.py +0 -0
  509. {code_coordinator-0.5.322 → code_coordinator-0.5.324}/tests/test_cli_milestone_order.py +0 -0
  510. {code_coordinator-0.5.322 → code_coordinator-0.5.324}/tests/test_cli_milestone_remove_and_issue_close.py +0 -0
  511. {code_coordinator-0.5.322 → code_coordinator-0.5.324}/tests/test_cli_milestone_ship.py +0 -0
  512. {code_coordinator-0.5.322 → code_coordinator-0.5.324}/tests/test_cli_network.py +0 -0
  513. {code_coordinator-0.5.322 → code_coordinator-0.5.324}/tests/test_cli_new_issue_chat.py +0 -0
  514. {code_coordinator-0.5.322 → code_coordinator-0.5.324}/tests/test_cli_plans.py +0 -0
  515. {code_coordinator-0.5.322 → code_coordinator-0.5.324}/tests/test_cli_pr.py +0 -0
  516. {code_coordinator-0.5.322 → code_coordinator-0.5.324}/tests/test_cli_pull_artifact.py +0 -0
  517. {code_coordinator-0.5.322 → code_coordinator-0.5.324}/tests/test_cli_queue.py +0 -0
  518. {code_coordinator-0.5.322 → code_coordinator-0.5.324}/tests/test_cli_reattach_sessions.py +0 -0
  519. {code_coordinator-0.5.322 → code_coordinator-0.5.324}/tests/test_cli_refine_board.py +0 -0
  520. {code_coordinator-0.5.322 → code_coordinator-0.5.324}/tests/test_cli_release_preflight.py +0 -0
  521. {code_coordinator-0.5.322 → code_coordinator-0.5.324}/tests/test_cli_release_propagate.py +0 -0
  522. {code_coordinator-0.5.322 → code_coordinator-0.5.324}/tests/test_cli_release_window.py +0 -0
  523. {code_coordinator-0.5.322 → code_coordinator-0.5.324}/tests/test_cli_repo_2220.py +0 -0
  524. {code_coordinator-0.5.322 → code_coordinator-0.5.324}/tests/test_cli_review_test_author_tracking_epic_2639.py +0 -0
  525. {code_coordinator-0.5.322 → code_coordinator-0.5.324}/tests/test_cli_scorecard.py +0 -0
  526. {code_coordinator-0.5.322 → code_coordinator-0.5.324}/tests/test_cli_set_review_findings.py +0 -0
  527. {code_coordinator-0.5.322 → code_coordinator-0.5.324}/tests/test_cli_status_advisory_terminal.py +0 -0
  528. {code_coordinator-0.5.322 → code_coordinator-0.5.324}/tests/test_cli_status_contested_tag.py +0 -0
  529. {code_coordinator-0.5.322 → code_coordinator-0.5.324}/tests/test_cli_status_merge_queue.py +0 -0
  530. {code_coordinator-0.5.322 → code_coordinator-0.5.324}/tests/test_cli_status_provider.py +0 -0
  531. {code_coordinator-0.5.322 → code_coordinator-0.5.324}/tests/test_cli_status_review_finalizing.py +0 -0
  532. {code_coordinator-0.5.322 → code_coordinator-0.5.324}/tests/test_cli_status_test_failed_tag.py +0 -0
  533. {code_coordinator-0.5.322 → code_coordinator-0.5.324}/tests/test_cli_status_usage_limit.py +0 -0
  534. {code_coordinator-0.5.322 → code_coordinator-0.5.324}/tests/test_cli_sync_comments_873.py +0 -0
  535. {code_coordinator-0.5.322 → code_coordinator-0.5.324}/tests/test_cli_test_plan.py +0 -0
  536. {code_coordinator-0.5.322 → code_coordinator-0.5.324}/tests/test_cli_track.py +0 -0
  537. {code_coordinator-0.5.322 → code_coordinator-0.5.324}/tests/test_cli_tui_update.py +0 -0
  538. {code_coordinator-0.5.322 → code_coordinator-0.5.324}/tests/test_cli_wait.py +0 -0
  539. {code_coordinator-0.5.322 → code_coordinator-0.5.324}/tests/test_client_base_install.py +0 -0
  540. {code_coordinator-0.5.322 → code_coordinator-0.5.324}/tests/test_client_resource_migration_1946.py +0 -0
  541. {code_coordinator-0.5.322 → code_coordinator-0.5.324}/tests/test_commands_common.py +0 -0
  542. {code_coordinator-0.5.322 → code_coordinator-0.5.324}/tests/test_comments.py +0 -0
  543. {code_coordinator-0.5.322 → code_coordinator-0.5.324}/tests/test_completion_summary.py +0 -0
  544. {code_coordinator-0.5.322 → code_coordinator-0.5.324}/tests/test_config.py +0 -0
  545. {code_coordinator-0.5.322 → code_coordinator-0.5.324}/tests/test_config_acceptance.py +0 -0
  546. {code_coordinator-0.5.322 → code_coordinator-0.5.324}/tests/test_config_audit.py +0 -0
  547. {code_coordinator-0.5.322 → code_coordinator-0.5.324}/tests/test_config_pricing.py +0 -0
  548. {code_coordinator-0.5.322 → code_coordinator-0.5.324}/tests/test_config_snapshot_noncanonical_2208.py +0 -0
  549. {code_coordinator-0.5.322 → code_coordinator-0.5.324}/tests/test_config_usage_gate.py +0 -0
  550. {code_coordinator-0.5.322 → code_coordinator-0.5.324}/tests/test_confirm_test.py +0 -0
  551. {code_coordinator-0.5.322 → code_coordinator-0.5.324}/tests/test_conflict_fix.py +0 -0
  552. {code_coordinator-0.5.322 → code_coordinator-0.5.324}/tests/test_conflict_fix_semantic.py +0 -0
  553. {code_coordinator-0.5.322 → code_coordinator-0.5.324}/tests/test_coord_log_daemon_fallback_2547.py +0 -0
  554. {code_coordinator-0.5.322 → code_coordinator-0.5.324}/tests/test_coord_test.py +0 -0
  555. {code_coordinator-0.5.322 → code_coordinator-0.5.324}/tests/test_coord_test_runner_acceptance_toolchain_2936.py +0 -0
  556. {code_coordinator-0.5.322 → code_coordinator-0.5.324}/tests/test_coord_test_runner_baseline.py +0 -0
  557. {code_coordinator-0.5.322 → code_coordinator-0.5.324}/tests/test_coord_test_runner_populated_home.py +0 -0
  558. {code_coordinator-0.5.322 → code_coordinator-0.5.324}/tests/test_coord_test_runner_routing.py +0 -0
  559. {code_coordinator-0.5.322 → code_coordinator-0.5.324}/tests/test_coord_test_runner_toolchain.py +0 -0
  560. {code_coordinator-0.5.322 → code_coordinator-0.5.324}/tests/test_coord_uat.py +0 -0
  561. {code_coordinator-0.5.322 → code_coordinator-0.5.324}/tests/test_coord_web_sse_restart_live.py +0 -0
  562. {code_coordinator-0.5.322 → code_coordinator-0.5.324}/tests/test_coordinator_machine.py +0 -0
  563. {code_coordinator-0.5.322 → code_coordinator-0.5.324}/tests/test_cross_platform_imports.py +0 -0
  564. {code_coordinator-0.5.322 → code_coordinator-0.5.324}/tests/test_dao.py +0 -0
  565. {code_coordinator-0.5.322 → code_coordinator-0.5.324}/tests/test_dashboard.py +0 -0
  566. {code_coordinator-0.5.322 → code_coordinator-0.5.324}/tests/test_dashboard_api.py +0 -0
  567. {code_coordinator-0.5.322 → code_coordinator-0.5.324}/tests/test_dashboard_fixture.py +0 -0
  568. {code_coordinator-0.5.322 → code_coordinator-0.5.324}/tests/test_dashboard_terminal.py +0 -0
  569. {code_coordinator-0.5.322 → code_coordinator-0.5.324}/tests/test_dashboard_terminal_live.py +0 -0
  570. {code_coordinator-0.5.322 → code_coordinator-0.5.324}/tests/test_db.py +0 -0
  571. {code_coordinator-0.5.322 → code_coordinator-0.5.324}/tests/test_dead_end.py +0 -0
  572. {code_coordinator-0.5.322 → code_coordinator-0.5.324}/tests/test_decomposition_chat.py +0 -0
  573. {code_coordinator-0.5.322 → code_coordinator-0.5.324}/tests/test_deploy_coord_db_backup.py +0 -0
  574. {code_coordinator-0.5.322 → code_coordinator-0.5.324}/tests/test_deploy_coord_web_dist.py +0 -0
  575. {code_coordinator-0.5.322 → code_coordinator-0.5.324}/tests/test_deploy_coord_web_rollback.py +0 -0
  576. {code_coordinator-0.5.322 → code_coordinator-0.5.324}/tests/test_deploy_drive_queue_unit.py +0 -0
  577. {code_coordinator-0.5.322 → code_coordinator-0.5.324}/tests/test_deploy_failure_notify_unit.py +0 -0
  578. {code_coordinator-0.5.322 → code_coordinator-0.5.324}/tests/test_deploy_manifest.py +0 -0
  579. {code_coordinator-0.5.322 → code_coordinator-0.5.324}/tests/test_deploy_notify_unit.py +0 -0
  580. {code_coordinator-0.5.322 → code_coordinator-0.5.324}/tests/test_deploy_units_lane.py +0 -0
  581. {code_coordinator-0.5.322 → code_coordinator-0.5.324}/tests/test_deploy_web_unit.py +0 -0
  582. {code_coordinator-0.5.322 → code_coordinator-0.5.324}/tests/test_deprecation_telemetry.py +0 -0
  583. {code_coordinator-0.5.322 → code_coordinator-0.5.324}/tests/test_deps.py +0 -0
  584. {code_coordinator-0.5.322 → code_coordinator-0.5.324}/tests/test_diagnose.py +0 -0
  585. {code_coordinator-0.5.322 → code_coordinator-0.5.324}/tests/test_dispatch.py +0 -0
  586. {code_coordinator-0.5.322 → code_coordinator-0.5.324}/tests/test_dispatch_target_validation.py +0 -0
  587. {code_coordinator-0.5.322 → code_coordinator-0.5.324}/tests/test_dist_name.py +0 -0
  588. {code_coordinator-0.5.322 → code_coordinator-0.5.324}/tests/test_done_housekeeping.py +0 -0
  589. {code_coordinator-0.5.322 → code_coordinator-0.5.324}/tests/test_drive.py +0 -0
  590. {code_coordinator-0.5.322 → code_coordinator-0.5.324}/tests/test_drive_queue.py +0 -0
  591. {code_coordinator-0.5.322 → code_coordinator-0.5.324}/tests/test_drive_queue_blocked_rendering.py +0 -0
  592. {code_coordinator-0.5.322 → code_coordinator-0.5.324}/tests/test_drive_queue_launch_argv.py +0 -0
  593. {code_coordinator-0.5.322 → code_coordinator-0.5.324}/tests/test_drive_queue_max_parallel_per_repo_config.py +0 -0
  594. {code_coordinator-0.5.322 → code_coordinator-0.5.324}/tests/test_drive_queue_roll_pending.py +0 -0
  595. {code_coordinator-0.5.322 → code_coordinator-0.5.324}/tests/test_drive_queue_self_cordon_escalation.py +0 -0
  596. {code_coordinator-0.5.322 → code_coordinator-0.5.324}/tests/test_drive_state.py +0 -0
  597. {code_coordinator-0.5.322 → code_coordinator-0.5.324}/tests/test_drive_tmux.py +0 -0
  598. {code_coordinator-0.5.322 → code_coordinator-0.5.324}/tests/test_epic_up_capability_detection.py +0 -0
  599. {code_coordinator-0.5.322 → code_coordinator-0.5.324}/tests/test_epic_up_down_symlinked_config_1887.py +0 -0
  600. {code_coordinator-0.5.322 → code_coordinator-0.5.324}/tests/test_epic_up_image_provenance.py +0 -0
  601. {code_coordinator-0.5.322 → code_coordinator-0.5.324}/tests/test_errors.py +0 -0
  602. {code_coordinator-0.5.322 → code_coordinator-0.5.324}/tests/test_events.py +0 -0
  603. {code_coordinator-0.5.322 → code_coordinator-0.5.324}/tests/test_failure_class.py +0 -0
  604. {code_coordinator-0.5.322 → code_coordinator-0.5.324}/tests/test_filelock.py +0 -0
  605. {code_coordinator-0.5.322 → code_coordinator-0.5.324}/tests/test_finalize_interactive_exit_test_verdict.py +0 -0
  606. {code_coordinator-0.5.322 → code_coordinator-0.5.324}/tests/test_fix_of_force_override.py +0 -0
  607. {code_coordinator-0.5.322 → code_coordinator-0.5.324}/tests/test_fleet_config_health.py +0 -0
  608. {code_coordinator-0.5.322 → code_coordinator-0.5.324}/tests/test_fleet_health_probes.py +0 -0
  609. {code_coordinator-0.5.322 → code_coordinator-0.5.324}/tests/test_fleet_health_snapshot.py +0 -0
  610. {code_coordinator-0.5.322 → code_coordinator-0.5.324}/tests/test_fleet_watchdog.py +0 -0
  611. {code_coordinator-0.5.322 → code_coordinator-0.5.324}/tests/test_forge_availability.py +0 -0
  612. {code_coordinator-0.5.322 → code_coordinator-0.5.324}/tests/test_freshness.py +0 -0
  613. {code_coordinator-0.5.322 → code_coordinator-0.5.324}/tests/test_gate_a.py +0 -0
  614. {code_coordinator-0.5.322 → code_coordinator-0.5.324}/tests/test_gate_b.py +0 -0
  615. {code_coordinator-0.5.322 → code_coordinator-0.5.324}/tests/test_gate_snapshot_staleness.py +0 -0
  616. {code_coordinator-0.5.322 → code_coordinator-0.5.324}/tests/test_gates.py +0 -0
  617. {code_coordinator-0.5.322 → code_coordinator-0.5.324}/tests/test_gather_fleet_tmux_sessions.py +0 -0
  618. {code_coordinator-0.5.322 → code_coordinator-0.5.324}/tests/test_gen_mock_index.py +0 -0
  619. {code_coordinator-0.5.322 → code_coordinator-0.5.324}/tests/test_generated_rust_fixture.py +0 -0
  620. {code_coordinator-0.5.322 → code_coordinator-0.5.324}/tests/test_generated_rust_requests.py +0 -0
  621. {code_coordinator-0.5.322 → code_coordinator-0.5.324}/tests/test_generated_types_fixture.py +0 -0
  622. {code_coordinator-0.5.322 → code_coordinator-0.5.324}/tests/test_github_ops.py +0 -0
  623. {code_coordinator-0.5.322 → code_coordinator-0.5.324}/tests/test_github_throttle.py +0 -0
  624. {code_coordinator-0.5.322 → code_coordinator-0.5.324}/tests/test_goal.py +0 -0
  625. {code_coordinator-0.5.322 → code_coordinator-0.5.324}/tests/test_graph_health.py +0 -0
  626. {code_coordinator-0.5.322 → code_coordinator-0.5.324}/tests/test_graph_selfheal_absent_2237.py +0 -0
  627. {code_coordinator-0.5.322 → code_coordinator-0.5.324}/tests/test_handoff.py +0 -0
  628. {code_coordinator-0.5.322 → code_coordinator-0.5.324}/tests/test_health_checks.py +0 -0
  629. {code_coordinator-0.5.322 → code_coordinator-0.5.324}/tests/test_health_cli.py +0 -0
  630. {code_coordinator-0.5.322 → code_coordinator-0.5.324}/tests/test_health_cli_graph.py +0 -0
  631. {code_coordinator-0.5.322 → code_coordinator-0.5.324}/tests/test_health_config.py +0 -0
  632. {code_coordinator-0.5.322 → code_coordinator-0.5.324}/tests/test_health_context.py +0 -0
  633. {code_coordinator-0.5.322 → code_coordinator-0.5.324}/tests/test_health_coord_tui_ci_pin.py +0 -0
  634. {code_coordinator-0.5.322 → code_coordinator-0.5.324}/tests/test_health_coord_web_ci_pin.py +0 -0
  635. {code_coordinator-0.5.322 → code_coordinator-0.5.324}/tests/test_health_deploy_lane_facts.py +0 -0
  636. {code_coordinator-0.5.322 → code_coordinator-0.5.324}/tests/test_health_fix.py +0 -0
  637. {code_coordinator-0.5.322 → code_coordinator-0.5.324}/tests/test_health_incident_regression.py +0 -0
  638. {code_coordinator-0.5.322 → code_coordinator-0.5.324}/tests/test_health_issues_sync_staleness.py +0 -0
  639. {code_coordinator-0.5.322 → code_coordinator-0.5.324}/tests/test_health_pypi.py +0 -0
  640. {code_coordinator-0.5.322 → code_coordinator-0.5.324}/tests/test_health_registry.py +0 -0
  641. {code_coordinator-0.5.322 → code_coordinator-0.5.324}/tests/test_health_release_cordon_probe.py +0 -0
  642. {code_coordinator-0.5.322 → code_coordinator-0.5.324}/tests/test_health_timer_active.py +0 -0
  643. {code_coordinator-0.5.322 → code_coordinator-0.5.324}/tests/test_health_toolchain.py +0 -0
  644. {code_coordinator-0.5.322 → code_coordinator-0.5.324}/tests/test_health_unit_drift.py +0 -0
  645. {code_coordinator-0.5.322 → code_coordinator-0.5.324}/tests/test_health_unit_enablement.py +0 -0
  646. {code_coordinator-0.5.322 → code_coordinator-0.5.324}/tests/test_health_wedged_drive_queue.py +0 -0
  647. {code_coordinator-0.5.322 → code_coordinator-0.5.324}/tests/test_hooks.py +0 -0
  648. {code_coordinator-0.5.322 → code_coordinator-0.5.324}/tests/test_human_attended_437.py +0 -0
  649. {code_coordinator-0.5.322 → code_coordinator-0.5.324}/tests/test_init.py +0 -0
  650. {code_coordinator-0.5.322 → code_coordinator-0.5.324}/tests/test_install_agent_venv_2911.py +0 -0
  651. {code_coordinator-0.5.322 → code_coordinator-0.5.324}/tests/test_integration.py +0 -0
  652. {code_coordinator-0.5.322 → code_coordinator-0.5.324}/tests/test_interactive_briefing_echo.py +0 -0
  653. {code_coordinator-0.5.322 → code_coordinator-0.5.324}/tests/test_interactive_pane_log_2541.py +0 -0
  654. {code_coordinator-0.5.322 → code_coordinator-0.5.324}/tests/test_interactive_prefill_state.py +0 -0
  655. {code_coordinator-0.5.322 → code_coordinator-0.5.324}/tests/test_interactive_session_relaunch.py +0 -0
  656. {code_coordinator-0.5.322 → code_coordinator-0.5.324}/tests/test_interactive_test_verdict_backstop.py +0 -0
  657. {code_coordinator-0.5.322 → code_coordinator-0.5.324}/tests/test_interactive_token_attribution.py +0 -0
  658. {code_coordinator-0.5.322 → code_coordinator-0.5.324}/tests/test_interactive_worktree.py +0 -0
  659. {code_coordinator-0.5.322 → code_coordinator-0.5.324}/tests/test_issue_store_seam.py +0 -0
  660. {code_coordinator-0.5.322 → code_coordinator-0.5.324}/tests/test_issues_sync_status.py +0 -0
  661. {code_coordinator-0.5.322 → code_coordinator-0.5.324}/tests/test_liveness_auditor.py +0 -0
  662. {code_coordinator-0.5.322 → code_coordinator-0.5.324}/tests/test_liveness_notify.py +0 -0
  663. {code_coordinator-0.5.322 → code_coordinator-0.5.324}/tests/test_lock_contention_ratchet.py +0 -0
  664. {code_coordinator-0.5.322 → code_coordinator-0.5.324}/tests/test_machine_onboard.py +0 -0
  665. {code_coordinator-0.5.322 → code_coordinator-0.5.324}/tests/test_machine_pause.py +0 -0
  666. {code_coordinator-0.5.322 → code_coordinator-0.5.324}/tests/test_merge_queue.py +0 -0
  667. {code_coordinator-0.5.322 → code_coordinator-0.5.324}/tests/test_merge_verify.py +0 -0
  668. {code_coordinator-0.5.322 → code_coordinator-0.5.324}/tests/test_milestone_chat.py +0 -0
  669. {code_coordinator-0.5.322 → code_coordinator-0.5.324}/tests/test_milestone_dispatch.py +0 -0
  670. {code_coordinator-0.5.322 → code_coordinator-0.5.324}/tests/test_milestone_gate.py +0 -0
  671. {code_coordinator-0.5.322 → code_coordinator-0.5.324}/tests/test_milestone_order.py +0 -0
  672. {code_coordinator-0.5.322 → code_coordinator-0.5.324}/tests/test_milestone_seam.py +0 -0
  673. {code_coordinator-0.5.322 → code_coordinator-0.5.324}/tests/test_mock_author.py +0 -0
  674. {code_coordinator-0.5.322 → code_coordinator-0.5.324}/tests/test_model_tiering.py +0 -0
  675. {code_coordinator-0.5.322 → code_coordinator-0.5.324}/tests/test_models.py +0 -0
  676. {code_coordinator-0.5.322 → code_coordinator-0.5.324}/tests/test_models_config_labels.py +0 -0
  677. {code_coordinator-0.5.322 → code_coordinator-0.5.324}/tests/test_needs_attention.py +0 -0
  678. {code_coordinator-0.5.322 → code_coordinator-0.5.324}/tests/test_network.py +0 -0
  679. {code_coordinator-0.5.322 → code_coordinator-0.5.324}/tests/test_new_issue_chat.py +0 -0
  680. {code_coordinator-0.5.322 → code_coordinator-0.5.324}/tests/test_next_release_tag.py +0 -0
  681. {code_coordinator-0.5.322 → code_coordinator-0.5.324}/tests/test_node_shim.py +0 -0
  682. {code_coordinator-0.5.322 → code_coordinator-0.5.324}/tests/test_notifier_baseline.py +0 -0
  683. {code_coordinator-0.5.322 → code_coordinator-0.5.324}/tests/test_notifier_cli.py +0 -0
  684. {code_coordinator-0.5.322 → code_coordinator-0.5.324}/tests/test_notifier_collect.py +0 -0
  685. {code_coordinator-0.5.322 → code_coordinator-0.5.324}/tests/test_notifier_config.py +0 -0
  686. {code_coordinator-0.5.322 → code_coordinator-0.5.324}/tests/test_notifier_drive_seam.py +0 -0
  687. {code_coordinator-0.5.322 → code_coordinator-0.5.324}/tests/test_notifier_isolation.py +0 -0
  688. {code_coordinator-0.5.322 → code_coordinator-0.5.324}/tests/test_notifier_predicate.py +0 -0
  689. {code_coordinator-0.5.322 → code_coordinator-0.5.324}/tests/test_notifier_quiet_hours.py +0 -0
  690. {code_coordinator-0.5.322 → code_coordinator-0.5.324}/tests/test_notifier_service.py +0 -0
  691. {code_coordinator-0.5.322 → code_coordinator-0.5.324}/tests/test_notify.py +0 -0
  692. {code_coordinator-0.5.322 → code_coordinator-0.5.324}/tests/test_notify_drain.py +0 -0
  693. {code_coordinator-0.5.322 → code_coordinator-0.5.324}/tests/test_openapi.py +0 -0
  694. {code_coordinator-0.5.322 → code_coordinator-0.5.324}/tests/test_operational_defaults.py +0 -0
  695. {code_coordinator-0.5.322 → code_coordinator-0.5.324}/tests/test_overlap_fence.py +0 -0
  696. {code_coordinator-0.5.322 → code_coordinator-0.5.324}/tests/test_overlap_predict.py +0 -0
  697. {code_coordinator-0.5.322 → code_coordinator-0.5.324}/tests/test_packaged_deploy_units.py +0 -0
  698. {code_coordinator-0.5.322 → code_coordinator-0.5.324}/tests/test_parentage.py +0 -0
  699. {code_coordinator-0.5.322 → code_coordinator-0.5.324}/tests/test_paste_landed.py +0 -0
  700. {code_coordinator-0.5.322 → code_coordinator-0.5.324}/tests/test_phantom_heal_venv_independence_2570.py +0 -0
  701. {code_coordinator-0.5.322 → code_coordinator-0.5.324}/tests/test_pipeline.py +0 -0
  702. {code_coordinator-0.5.322 → code_coordinator-0.5.324}/tests/test_plan_followup_approve_plan_command.py +0 -0
  703. {code_coordinator-0.5.322 → code_coordinator-0.5.324}/tests/test_plan_followup_pr_command.py +0 -0
  704. {code_coordinator-0.5.322 → code_coordinator-0.5.324}/tests/test_plan_followup_review_command.py +0 -0
  705. {code_coordinator-0.5.322 → code_coordinator-0.5.324}/tests/test_plan_only.py +0 -0
  706. {code_coordinator-0.5.322 → code_coordinator-0.5.324}/tests/test_plan_parser.py +0 -0
  707. {code_coordinator-0.5.322 → code_coordinator-0.5.324}/tests/test_platform_paths.py +0 -0
  708. {code_coordinator-0.5.322 → code_coordinator-0.5.324}/tests/test_portal_bridge.py +0 -0
  709. {code_coordinator-0.5.322 → code_coordinator-0.5.324}/tests/test_portal_config.py +0 -0
  710. {code_coordinator-0.5.322 → code_coordinator-0.5.324}/tests/test_portal_sync.py +0 -0
  711. {code_coordinator-0.5.322 → code_coordinator-0.5.324}/tests/test_pr_body_lint.py +0 -0
  712. {code_coordinator-0.5.322 → code_coordinator-0.5.324}/tests/test_prereqs.py +0 -0
  713. {code_coordinator-0.5.322 → code_coordinator-0.5.324}/tests/test_production_db_guard.py +0 -0
  714. {code_coordinator-0.5.322 → code_coordinator-0.5.324}/tests/test_progress.py +0 -0
  715. {code_coordinator-0.5.322 → code_coordinator-0.5.324}/tests/test_provider_seam.py +0 -0
  716. {code_coordinator-0.5.322 → code_coordinator-0.5.324}/tests/test_providers.py +0 -0
  717. {code_coordinator-0.5.322 → code_coordinator-0.5.324}/tests/test_providers_config_labels.py +0 -0
  718. {code_coordinator-0.5.322 → code_coordinator-0.5.324}/tests/test_providers_pty.py +0 -0
  719. {code_coordinator-0.5.322 → code_coordinator-0.5.324}/tests/test_py_rust_mirror_inventory.py +0 -0
  720. {code_coordinator-0.5.322 → code_coordinator-0.5.324}/tests/test_quiet_hours.py +0 -0
  721. {code_coordinator-0.5.322 → code_coordinator-0.5.324}/tests/test_quiet_hours_store_2146.py +0 -0
  722. {code_coordinator-0.5.322 → code_coordinator-0.5.324}/tests/test_reap_merged_sessions.py +0 -0
  723. {code_coordinator-0.5.322 → code_coordinator-0.5.324}/tests/test_reap_stale_interactive_tick.py +0 -0
  724. {code_coordinator-0.5.322 → code_coordinator-0.5.324}/tests/test_reconcile.py +0 -0
  725. {code_coordinator-0.5.322 → code_coordinator-0.5.324}/tests/test_reconcile_branch.py +0 -0
  726. {code_coordinator-0.5.322 → code_coordinator-0.5.324}/tests/test_reconcile_completions.py +0 -0
  727. {code_coordinator-0.5.322 → code_coordinator-0.5.324}/tests/test_reconcile_late_agent_reports_2547.py +0 -0
  728. {code_coordinator-0.5.322 → code_coordinator-0.5.324}/tests/test_reconcile_merges.py +0 -0
  729. {code_coordinator-0.5.322 → code_coordinator-0.5.324}/tests/test_reconcile_no_agent_record.py +0 -0
  730. {code_coordinator-0.5.322 → code_coordinator-0.5.324}/tests/test_reconcile_tick.py +0 -0
  731. {code_coordinator-0.5.322 → code_coordinator-0.5.324}/tests/test_reconcile_usage_limit_done.py +0 -0
  732. {code_coordinator-0.5.322 → code_coordinator-0.5.324}/tests/test_refine_chat.py +0 -0
  733. {code_coordinator-0.5.322 → code_coordinator-0.5.324}/tests/test_release_cordon_2101.py +0 -0
  734. {code_coordinator-0.5.322 → code_coordinator-0.5.324}/tests/test_release_cordon_daemon_leads_2176.py +0 -0
  735. {code_coordinator-0.5.322 → code_coordinator-0.5.324}/tests/test_release_cordon_deadlock_2240.py +0 -0
  736. {code_coordinator-0.5.322 → code_coordinator-0.5.324}/tests/test_release_cordon_stuck_2490.py +0 -0
  737. {code_coordinator-0.5.322 → code_coordinator-0.5.324}/tests/test_release_propagate.py +0 -0
  738. {code_coordinator-0.5.322 → code_coordinator-0.5.324}/tests/test_release_propagate_threshold.py +0 -0
  739. {code_coordinator-0.5.322 → code_coordinator-0.5.324}/tests/test_release_roll_between_legs_2854.py +0 -0
  740. {code_coordinator-0.5.322 → code_coordinator-0.5.324}/tests/test_release_roll_window_handoff.py +0 -0
  741. {code_coordinator-0.5.322 → code_coordinator-0.5.324}/tests/test_release_unified_1242.py +0 -0
  742. {code_coordinator-0.5.322 → code_coordinator-0.5.324}/tests/test_release_verify.py +0 -0
  743. {code_coordinator-0.5.322 → code_coordinator-0.5.324}/tests/test_release_window.py +0 -0
  744. {code_coordinator-0.5.322 → code_coordinator-0.5.324}/tests/test_remote_auto_prune.py +0 -0
  745. {code_coordinator-0.5.322 → code_coordinator-0.5.324}/tests/test_remote_interactive_reaper.py +0 -0
  746. {code_coordinator-0.5.322 → code_coordinator-0.5.324}/tests/test_repo_add.py +0 -0
  747. {code_coordinator-0.5.322 → code_coordinator-0.5.324}/tests/test_repo_dormancy.py +0 -0
  748. {code_coordinator-0.5.322 → code_coordinator-0.5.324}/tests/test_repo_edit_2220.py +0 -0
  749. {code_coordinator-0.5.322 → code_coordinator-0.5.324}/tests/test_repo_graph_fleet_2237.py +0 -0
  750. {code_coordinator-0.5.322 → code_coordinator-0.5.324}/tests/test_repo_onboard_2220.py +0 -0
  751. {code_coordinator-0.5.322 → code_coordinator-0.5.324}/tests/test_report_result_push.py +0 -0
  752. {code_coordinator-0.5.322 → code_coordinator-0.5.324}/tests/test_reports.py +0 -0
  753. {code_coordinator-0.5.322 → code_coordinator-0.5.324}/tests/test_retry.py +0 -0
  754. {code_coordinator-0.5.322 → code_coordinator-0.5.324}/tests/test_retry_advisory_1606.py +0 -0
  755. {code_coordinator-0.5.322 → code_coordinator-0.5.324}/tests/test_retry_type_1636.py +0 -0
  756. {code_coordinator-0.5.322 → code_coordinator-0.5.324}/tests/test_revalidate.py +0 -0
  757. {code_coordinator-0.5.322 → code_coordinator-0.5.324}/tests/test_review.py +0 -0
  758. {code_coordinator-0.5.322 → code_coordinator-0.5.324}/tests/test_review_end_review_without_verdict.py +0 -0
  759. {code_coordinator-0.5.322 → code_coordinator-0.5.324}/tests/test_review_parse_failure_diagnostic.py +0 -0
  760. {code_coordinator-0.5.322 → code_coordinator-0.5.324}/tests/test_review_reaffirm.py +0 -0
  761. {code_coordinator-0.5.322 → code_coordinator-0.5.324}/tests/test_review_state.py +0 -0
  762. {code_coordinator-0.5.322 → code_coordinator-0.5.324}/tests/test_review_verdict_backstop.py +0 -0
  763. {code_coordinator-0.5.322 → code_coordinator-0.5.324}/tests/test_review_verdict_override_audit.py +0 -0
  764. {code_coordinator-0.5.322 → code_coordinator-0.5.324}/tests/test_review_verdict_relay.py +0 -0
  765. {code_coordinator-0.5.322 → code_coordinator-0.5.324}/tests/test_review_zero_commits.py +0 -0
  766. {code_coordinator-0.5.322 → code_coordinator-0.5.324}/tests/test_scoped_review_wiring.py +0 -0
  767. {code_coordinator-0.5.322 → code_coordinator-0.5.324}/tests/test_scorecard.py +0 -0
  768. {code_coordinator-0.5.322 → code_coordinator-0.5.324}/tests/test_self_health.py +0 -0
  769. {code_coordinator-0.5.322 → code_coordinator-0.5.324}/tests/test_serve.py +0 -0
  770. {code_coordinator-0.5.322 → code_coordinator-0.5.324}/tests/test_serve_app_board_trim.py +0 -0
  771. {code_coordinator-0.5.322 → code_coordinator-0.5.324}/tests/test_serve_rest_routes.py +0 -0
  772. {code_coordinator-0.5.322 → code_coordinator-0.5.324}/tests/test_session.py +0 -0
  773. {code_coordinator-0.5.322 → code_coordinator-0.5.324}/tests/test_slice_issue_attribution.py +0 -0
  774. {code_coordinator-0.5.322 → code_coordinator-0.5.324}/tests/test_smoke.py +0 -0
  775. {code_coordinator-0.5.322 → code_coordinator-0.5.324}/tests/test_smoke_live_checkout_restore.py +0 -0
  776. {code_coordinator-0.5.322 → code_coordinator-0.5.324}/tests/test_smoke_workflow.py +0 -0
  777. {code_coordinator-0.5.322 → code_coordinator-0.5.324}/tests/test_spend_ceiling.py +0 -0
  778. {code_coordinator-0.5.322 → code_coordinator-0.5.324}/tests/test_spend_ceiling_coordinator.py +0 -0
  779. {code_coordinator-0.5.322 → code_coordinator-0.5.324}/tests/test_split.py +0 -0
  780. {code_coordinator-0.5.322 → code_coordinator-0.5.324}/tests/test_split_work.py +0 -0
  781. {code_coordinator-0.5.322 → code_coordinator-0.5.324}/tests/test_sql_dialect.py +0 -0
  782. {code_coordinator-0.5.322 → code_coordinator-0.5.324}/tests/test_stage_projection.py +0 -0
  783. {code_coordinator-0.5.322 → code_coordinator-0.5.324}/tests/test_stale_busy_reviewer_697.py +0 -0
  784. {code_coordinator-0.5.322 → code_coordinator-0.5.324}/tests/test_stalled_pipeline.py +0 -0
  785. {code_coordinator-0.5.322 → code_coordinator-0.5.324}/tests/test_state.py +0 -0
  786. {code_coordinator-0.5.322 → code_coordinator-0.5.324}/tests/test_state_review_findings_daemon.py +0 -0
  787. {code_coordinator-0.5.322 → code_coordinator-0.5.324}/tests/test_status_fleet_footer.py +0 -0
  788. {code_coordinator-0.5.322 → code_coordinator-0.5.324}/tests/test_stop_1567.py +0 -0
  789. {code_coordinator-0.5.322 → code_coordinator-0.5.324}/tests/test_store_contract.py +0 -0
  790. {code_coordinator-0.5.322 → code_coordinator-0.5.324}/tests/test_store_migrate.py +0 -0
  791. {code_coordinator-0.5.322 → code_coordinator-0.5.324}/tests/test_stuck.py +0 -0
  792. {code_coordinator-0.5.322 → code_coordinator-0.5.324}/tests/test_stuck_test_state_watchdog_2803.py +0 -0
  793. {code_coordinator-0.5.322 → code_coordinator-0.5.324}/tests/test_terminal_command.py +0 -0
  794. {code_coordinator-0.5.322 → code_coordinator-0.5.324}/tests/test_test_author.py +0 -0
  795. {code_coordinator-0.5.322 → code_coordinator-0.5.324}/tests/test_test_chat.py +0 -0
  796. {code_coordinator-0.5.322 → code_coordinator-0.5.324}/tests/test_test_orchestrator.py +0 -0
  797. {code_coordinator-0.5.322 → code_coordinator-0.5.324}/tests/test_test_report.py +0 -0
  798. {code_coordinator-0.5.322 → code_coordinator-0.5.324}/tests/test_test_verdict_parsing.py +0 -0
  799. {code_coordinator-0.5.322 → code_coordinator-0.5.324}/tests/test_test_verdict_transcript_floor.py +0 -0
  800. {code_coordinator-0.5.322 → code_coordinator-0.5.324}/tests/test_text_io_encoding_audit.py +0 -0
  801. {code_coordinator-0.5.322 → code_coordinator-0.5.324}/tests/test_thin_client_board_audit.py +0 -0
  802. {code_coordinator-0.5.322 → code_coordinator-0.5.324}/tests/test_thin_client_config_load_1080.py +0 -0
  803. {code_coordinator-0.5.322 → code_coordinator-0.5.324}/tests/test_thin_client_daemon_routing_906.py +0 -0
  804. {code_coordinator-0.5.322 → code_coordinator-0.5.324}/tests/test_tmux_host.py +0 -0
  805. {code_coordinator-0.5.322 → code_coordinator-0.5.324}/tests/test_tmux_session.py +0 -0
  806. {code_coordinator-0.5.322 → code_coordinator-0.5.324}/tests/test_transcript_floor.py +0 -0
  807. {code_coordinator-0.5.322 → code_coordinator-0.5.324}/tests/test_usage.py +0 -0
  808. {code_coordinator-0.5.322 → code_coordinator-0.5.324}/tests/test_usage_limits.py +0 -0
  809. {code_coordinator-0.5.322 → code_coordinator-0.5.324}/tests/test_usage_rollup.py +0 -0
  810. {code_coordinator-0.5.322 → code_coordinator-0.5.324}/tests/test_venv_live_install_2121.py +0 -0
  811. {code_coordinator-0.5.322 → code_coordinator-0.5.324}/tests/test_version_single_source.py +0 -0
  812. {code_coordinator-0.5.322 → code_coordinator-0.5.324}/tests/test_watch.py +0 -0
  813. {code_coordinator-0.5.322 → code_coordinator-0.5.324}/tests/test_windows_job_is_a_real_gate_2000.py +0 -0
  814. {code_coordinator-0.5.322 → code_coordinator-0.5.324}/tests/test_worker_env_venv_isolation.py +0 -0
  815. {code_coordinator-0.5.322 → code_coordinator-0.5.324}/tests/test_worker_events.py +0 -0
  816. {code_coordinator-0.5.322 → code_coordinator-0.5.324}/tests/test_worker_image_pin_sync.py +0 -0
  817. {code_coordinator-0.5.322 → code_coordinator-0.5.324}/tests/test_worker_safety.py +0 -0
  818. {code_coordinator-0.5.322 → code_coordinator-0.5.324}/tests/test_worker_test_scoping.py +0 -0
  819. {code_coordinator-0.5.322 → code_coordinator-0.5.324}/tests/test_worktree.py +0 -0
  820. {code_coordinator-0.5.322 → code_coordinator-0.5.324}/tests/test_worktree_rmtree_chokepoint.py +0 -0
  821. {code_coordinator-0.5.322 → code_coordinator-0.5.324}/tests/test_write_parity.py +0 -0
  822. {code_coordinator-0.5.322 → code_coordinator-0.5.324}/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.322
3
+ Version: 0.5.324
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.322
3
+ Version: 0.5.324
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
@@ -403,6 +403,7 @@ tests/test_approve_dependency_busy_2804.py
403
403
  tests/test_approve_reject_plan.py
404
404
  tests/test_approve_usage_gate.py
405
405
  tests/test_approved_work_2532.py
406
+ tests/test_approved_work_2996.py
406
407
  tests/test_assignment_already_recorded_daemon.py
407
408
  tests/test_audit_log.py
408
409
  tests/test_audit_outcome.py
@@ -429,6 +429,7 @@
429
429
  "tests/test_approve_reject_plan.py",
430
430
  "tests/test_approve_usage_gate.py",
431
431
  "tests/test_approved_work_2532.py",
432
+ "tests/test_approved_work_2996.py",
432
433
  "tests/test_assignment_already_recorded_daemon.py",
433
434
  "tests/test_audit_log.py",
434
435
  "tests/test_audit_outcome.py",
@@ -1,7 +1,7 @@
1
1
  {
2
- "tag": "0.5.322",
2
+ "tag": "0.5.324",
3
3
  "distance": 0,
4
- "node": "gc65d3bfc2f39f921d5d2df163c46505669a2a629",
4
+ "node": "gfe0ce4aff039fa4d2a916eda693e9adb5553d439",
5
5
  "dirty": false,
6
6
  "branch": "HEAD",
7
7
  "node_date": "2026-08-31"
@@ -4178,9 +4178,10 @@ never this session's own.
4178
4178
  - Do NOT run `git push`, `git commit`, or any command that writes to a repo \
4179
4179
  checkout — this session files issues and queues work, it does not touch code.
4180
4180
  - If an `enqueue-question`/`enqueue-status`/`decision` command refuses with \
4181
- a thin-client error (this machine isn't the daemon host and isn't routed \
4182
- yet — #2751), say so explicitly to the operator rather than silently \
4183
- dropping the Ask/Propose; do not retry it as some other command.
4181
+ a thin-client error (this machine does not claim every repo the submission \
4182
+ maps to — #2995/#2751; it should not happen, since you were only dispatched \
4183
+ here because it does), say so explicitly to the operator rather than \
4184
+ silently dropping the Ask/Propose; do not retry it as some other command.
4184
4185
  - Keep the operator informed: summarize your plan before writing anything, \
4185
4186
  and report back what you asked/proposed/filed/queued/linked (and any gap) \
4186
4187
  when done.\
@@ -256,6 +256,47 @@ def approved_submission_ids() -> set[str]:
256
256
  return {sid for sid, verdict in _fold_signoff_verdicts().items() if verdict == "approved"}
257
257
 
258
258
 
259
+ def is_pulled_status(status: str) -> bool:
260
+ """Whether *status* is one of :data:`_PULLED_STATUSES` — the public,
261
+ non-underscore way for another module (:mod:`coord.commands.portal`,
262
+ #2996) to ask "would pushing this status withdraw a submission from
263
+ :func:`approved_submissions`?" without reaching into this module's
264
+ private constant.
265
+ """
266
+ return status in _PULLED_STATUSES
267
+
268
+
269
+ def disqualifying_status(submission_id: str) -> str | None:
270
+ """The ``last_status`` responsible for *submission_id* being missing
271
+ from :func:`approved_submissions` despite an ``approved`` sign-off
272
+ verdict on file — or ``None`` when that is not why it is missing (never
273
+ approved, no record at all, or genuinely not pulled) (#2996).
274
+
275
+ Reads local :mod:`coord.portal_store` directly, same as
276
+ :func:`approved_submissions` itself — so, like that function, this is
277
+ only meaningful when called on the daemon host (the caller is
278
+ responsible for that; see :func:`coord.commands.portal.
279
+ _refuse_if_thin_client` and :func:`coord.decomposition_chat.
280
+ resolve_approved_submission`'s own thin-client routing).
281
+
282
+ Exists so a "why isn't this on the queue" failure message
283
+ (:func:`coord.decomposition_chat.resolve_approved_submission`'s callers)
284
+ can name the actual cause — a status an operator pushed by hand, most
285
+ often via ``coord portal enqueue-status`` — instead of the generic
286
+ "is not a currently-approved portal submission", which names neither.
287
+ """
288
+ from coord import portal_store # noqa: PLC0415 — avoid import cycle
289
+
290
+ record = portal_store.get_submission(submission_id)
291
+ if record is None:
292
+ return None
293
+ if record.submission_id not in approved_submission_ids():
294
+ return None
295
+ if record.last_status in _PULLED_STATUSES:
296
+ return record.last_status
297
+ return None
298
+
299
+
259
300
  def approved_submissions(config: "Config") -> list[dict[str, Any]]:
260
301
  """The ``/board`` ``approved_submissions`` payload, **oldest first**.
261
302
 
@@ -835,6 +835,36 @@ def fetch_portal_link(
835
835
  return link if isinstance(link, dict) else None
836
836
 
837
837
 
838
+ def fetch_portal_link_by_submission(
839
+ svc: ServiceConfig, submission_id: str, *, timeout: float = _DEFAULT_TIMEOUT
840
+ ) -> dict | None:
841
+ """GET the portal link for *submission_id* by reverse lookup (#2995) —
842
+ the submission-keyed counterpart to :func:`fetch_portal_link`'s
843
+ ``(repo_name, milestone_number/issue_number)``-keyed one.
844
+
845
+ Backs :func:`coord.portal_store.get_link_by_submission` on a thin
846
+ client — needed once ``coord portal enqueue-status``'s #2996 "no link on
847
+ file" warning became reachable from one. Fail-soft to ``None`` on any
848
+ transport/HTTP/decode error, same reasoning as :func:`fetch_portal_link`:
849
+ a daemon hiccup degrades to the same "not linked" a genuinely unlinked
850
+ submission would show, rather than a traceback, for a read that only
851
+ ever gates a warning.
852
+ """
853
+ try:
854
+ resp = httpx.get(
855
+ f"{svc.url}/portal-link-by-submission",
856
+ params={"submission_id": submission_id},
857
+ headers=_headers(svc),
858
+ timeout=timeout,
859
+ )
860
+ resp.raise_for_status()
861
+ data = resp.json()
862
+ except (httpx.HTTPError, ValueError):
863
+ return None
864
+ link = data.get("link") if isinstance(data, dict) else None
865
+ return link if isinstance(link, dict) else None
866
+
867
+
838
868
  def fetch_portal_ledger(
839
869
  svc: ServiceConfig, submission_id: str, *, timeout: float = _DEFAULT_TIMEOUT
840
870
  ) -> dict:
@@ -64,6 +64,23 @@ exactly like an inbound ``question.answered`` event does, flags it relayed
64
64
  so it never reads as the client's own words, and folds the submission off
65
65
  ``needs-input``. Same daemon-routed shape (``POST /portal-note`` /
66
66
  ``POST /portal-answer``) and the same reason.
67
+
68
+ **``enqueue-question`` and ``enqueue-status`` are the last two, and the odd
69
+ ones out (#2995).** Every exception above routes unconditionally — any
70
+ machine in the fleet may be where the operator is typing. These two widen
71
+ the routed set instead of dropping the guard: ``coord portal decompose-chat
72
+ --interactive`` is dispatched only to a machine that claims the
73
+ submission's mapped repo(s) (#2750), and the Ask move — the one exit that
74
+ session could not take from a thin client, the gap this issue closes — is
75
+ exactly what these two commands queue. So they route through the daemon
76
+ (``POST /portal-enqueue-question`` / ``POST /portal-enqueue-status``) only
77
+ when :func:`_refuse_unless_claiming_machine` confirms the calling machine
78
+ claims every mapped repo; a non-claiming thin client still refuses, same as
79
+ every command at the top of this file. ``enqueue-question`` queues two rows
80
+ (the question and its ``needs-input`` announcement, #2901) — the daemon
81
+ applies both in the ONE request, so a partial application can never leave a
82
+ question with no status row behind it (the mute-question failure #2901
83
+ exists to prevent).
67
84
  """
68
85
 
69
86
  from __future__ import annotations
@@ -98,10 +115,11 @@ def _actor() -> str:
98
115
  def _refuse_if_thin_client(cmd_name: str) -> None:
99
116
  """Refuse *cmd_name* when this machine isn't the daemon host (#2336).
100
117
 
101
- ``sync``/``outbox``/``events``/``enqueue-*``/``requeue`` read and write
102
- the daemon's own ``~/.coord/coord.db`` directly — there is no daemon
103
- proxy for portal state yet (unlike ``coord status``/``coord log``/etc,
104
- which already route through ``board_service`` when it's configured; see
118
+ ``sync``/``outbox``/``events``/``enqueue-design-round``/
119
+ ``enqueue-preview``/``requeue`` read and write the daemon's own
120
+ ``~/.coord/coord.db`` directly — there is no daemon proxy for portal
121
+ state yet (unlike ``coord status``/``coord log``/etc, which already
122
+ route through ``board_service`` when it's configured; see
105
123
  ``coord/client.py``'s module docstring for the bootstrap contract). Run
106
124
  on a machine that has ``board_service`` set in ``~/.coord/client.toml``
107
125
  (a thin client, by definition — every other machine in the fleet that
@@ -111,6 +129,10 @@ def _refuse_if_thin_client(cmd_name: str) -> None:
111
129
  unnoticed on the daemon host for over an hour because every portal
112
130
  command run from a thin client reported nothing pending).
113
131
 
132
+ ``enqueue-question``/``enqueue-status`` used to be in that list too —
133
+ see :func:`_refuse_unless_claiming_machine` below (#2995) for why they
134
+ no longer call this at all.
135
+
114
136
  Mirrors the guard already used for the same reason in
115
137
  ``coord.commands.drive_queue``'s ``diagnose`` command (#615/#906), which
116
138
  refuses rather than "diagnose an empty queue" on a thin client. The
@@ -137,6 +159,101 @@ def _refuse_if_thin_client(cmd_name: str) -> None:
137
159
  )
138
160
 
139
161
 
162
+ def _missing_claimed_repos(machine, repos: list[str]) -> list[str]:
163
+ """Repos in REPOS that MACHINE does not claim — the "does this machine
164
+ claim every repo this submission maps to" predicate, in exactly one
165
+ place (#2995 review, #2085/#2096 "one question, one answer").
166
+
167
+ ``machine is None`` (this box isn't a configured machine in
168
+ ``coordinator.yml`` at all) counts every repo as unclaimed — an
169
+ unconfigured machine claims nothing. Shared by
170
+ :func:`_refuse_unless_claiming_machine` (above) and
171
+ ``_run_decompose_chat_interactive`` (further down this module): both
172
+ ask this exact question before letting a thin/local client touch a
173
+ submission's mapped repo(s), and before this helper existed they asked
174
+ it with two independently-written comprehensions that happened to agree
175
+ only because they were written together in the same commit — nothing
176
+ kept them in sync if either changed later. Callers keep their own
177
+ branching for the ``machine is None`` case where they want a distinct
178
+ message/exit path (``_run_decompose_chat_interactive`` does); this only
179
+ answers "which repos are missing," never how to report it.
180
+ """
181
+ if machine is None:
182
+ return list(repos)
183
+ return [r for r in repos if not machine.can_work_on(r)]
184
+
185
+
186
+ def _refuse_unless_claiming_machine(cfg, submission_id: str, cmd_name: str) -> None:
187
+ """Refuse *cmd_name* on a thin client that does not claim every repo
188
+ SUBMISSION_ID maps to (#2995). A no-op on the daemon host itself.
189
+
190
+ ``enqueue-question``/``enqueue-status`` are the Ask move's exit — the
191
+ one thing `coord portal decompose-chat --interactive` could not do from
192
+ a thin client that claims the submission's repo(s), even though that
193
+ session is explicitly allowed to run there (#2750). Unlike ``note``/
194
+ ``decision``/``link``/``answer`` (#2751/#2867/#2986), which route
195
+ unconditionally — any machine in the fleet may be where the operator is
196
+ typing — this widens the refused set rather than dropping it: a
197
+ ``type="decomposition-chat"`` session is never dispatched to a machine
198
+ that doesn't claim the submission's repo(s) in the first place
199
+ (:func:`coord.decomposition_chat.pick_decomposition_chat_machine`), so a
200
+ caller invoking these commands directly from one that *doesn't* claim
201
+ them is either a mistake or a machine that has no business writing
202
+ against this submission's outbox — that machine still refuses, exactly
203
+ like every other state-touching command in this file.
204
+
205
+ Repos are resolved the same thin-client-safe way
206
+ ``_run_decompose_chat_interactive`` already does before ever launching a
207
+ session (see that function, further down in this module), and for the
208
+ identical reason:
209
+ :func:`coord.decomposition_chat.resolve_approved_submission`, itself
210
+ routed through the daemon's ``GET /board``. A submission that isn't
211
+ currently a recorded ``approved`` sign-off — the only shape that
212
+ projection carries — cannot be claim-checked from here at all, and this
213
+ refuses rather than guess at a repo list it cannot verify.
214
+ """
215
+ from coord.board_service import resolve # noqa: PLC0415
216
+
217
+ svc = resolve()
218
+ if svc is None:
219
+ return
220
+ from urllib.parse import urlparse # noqa: PLC0415
221
+
222
+ from coord.decomposition_chat import resolve_approved_submission # noqa: PLC0415
223
+ from coord.test_orchestrator import local_machine # noqa: PLC0415
224
+
225
+ host = urlparse(svc.url).hostname or svc.url
226
+ submission = resolve_approved_submission(cfg, submission_id)
227
+ if submission is None:
228
+ raise click.ClickException(
229
+ f"coord portal {cmd_name} refuses: submission {submission_id!r} is "
230
+ "not a currently-approved portal submission, so its mapped "
231
+ "repo(s) cannot be resolved from this thin client to verify a "
232
+ "claim. Run it over `ssh` on the daemon host "
233
+ f"({host}) instead. See coord/skills/portal-followup/SKILL.md."
234
+ )
235
+ repos: list[str] = submission.get("repos") or []
236
+ machine = local_machine(cfg)
237
+ missing = _missing_claimed_repos(machine, repos)
238
+ if not repos or missing:
239
+ reason = (
240
+ f"submission {submission_id!r} has no mapped repo (portal."
241
+ "project_repos in coordinator.yml)"
242
+ if not repos
243
+ else (
244
+ f"this machine ({machine.name if machine is not None else 'unconfigured'}) "
245
+ f"does not claim repo(s) {', '.join(missing)} that submission "
246
+ f"{submission_id!r} maps to ({', '.join(repos)})"
247
+ )
248
+ )
249
+ raise click.ClickException(
250
+ f"coord portal {cmd_name} refuses: {reason}. Run it over `ssh` on "
251
+ f"the daemon host ({host}) instead, or from a machine that claims "
252
+ "every repo the submission maps to. See "
253
+ "coord/skills/portal-followup/SKILL.md."
254
+ )
255
+
256
+
140
257
  @click.group("portal")
141
258
  def portal_group() -> None:
142
259
  """coord-portal sync bridge — status, manual push, heartbeat (#2179)."""
@@ -439,11 +556,11 @@ def portal_link(
439
556
  "headless dispatch. Local-only for now (Track B / #486 is remote): "
440
557
  "refuses when this machine does not claim every repo SUBMISSION_ID "
441
558
  "maps to. On a thin client (this machine has `board_service` "
442
- "configured), `coord portal decision`/`ledger`/`link` route through "
443
- "the daemon (#2751) but `enqueue-question`/`enqueue-status` do not "
444
- "yet — an Ask-shaped iteration will refuse loudly mid-conversation "
445
- "on those; ssh to the daemon host instead for that case. Mutually "
446
- "exclusive with --wait/--machine/--timeout/--interval."
559
+ "configured), `coord portal decision`/`ledger`/`link`/`note`/"
560
+ "`answer` and (#2995) `enqueue-question`/`enqueue-status` — "
561
+ "including the Ask move — all route through the daemon, so every "
562
+ "exit an iteration can take works from here. Mutually exclusive "
563
+ "with --wait/--machine/--timeout/--interval."
447
564
  ),
448
565
  )
449
566
  @click.option(
@@ -612,6 +729,7 @@ def _run_decompose_chat_interactive(
612
729
  )
613
730
  from coord.decomposition_chat import ( # noqa: PLC0415
614
731
  build_decomposition_chat_briefing,
732
+ describe_unapproved_submission,
615
733
  fetch_running_context,
616
734
  render_running_context_section,
617
735
  repo_topology_context,
@@ -633,8 +751,7 @@ def _run_decompose_chat_interactive(
633
751
  submission = resolve_approved_submission(cfg, submission_id)
634
752
  if submission is None:
635
753
  click.secho(
636
- f"error: submission {submission_id!r} is not a currently-approved "
637
- "portal submission — nothing to decompose",
754
+ f"error: {describe_unapproved_submission(cfg, submission_id)}",
638
755
  fg="red",
639
756
  )
640
757
  raise SystemExit(1)
@@ -657,7 +774,7 @@ def _run_decompose_chat_interactive(
657
774
  err=True,
658
775
  )
659
776
  raise SystemExit(2)
660
- missing = [r for r in repos if not machine.can_work_on(r)]
777
+ missing = _missing_claimed_repos(machine, repos)
661
778
  if missing:
662
779
  click.echo(
663
780
  f"error: --interactive is local-only for now (Track B / #486 is "
@@ -669,19 +786,12 @@ def _run_decompose_chat_interactive(
669
786
  )
670
787
  raise SystemExit(2)
671
788
 
672
- from coord import board_service as _board_service # noqa: PLC0415
673
-
674
- if _board_service.resolve() is not None:
675
- click.secho(
676
- "note: this machine is a thin client — `coord portal decision`/"
677
- "`ledger`/`link`/`note` route through the daemon (#2751/#2867), "
678
- "but `coord "
679
- "portal enqueue-question`/`enqueue-status` (the Ask move) do "
680
- "not yet and will refuse loudly if this iteration needs them. "
681
- "ssh to the daemon host for that case (#2750's own stated "
682
- "limit).",
683
- fg="yellow",
684
- )
789
+ # #2995: no thin-client caveat left to print here — `decision`/`ledger`/
790
+ # `link`/`note`/`answer` (#2751/#2867/#2986) and now `enqueue-question`/
791
+ # `enqueue-status` (the Ask move's exit) all route through the daemon
792
+ # from exactly this machine, which the claim check above just verified
793
+ # claims every repo SUBMISSION_ID maps to. A prior revision warned here
794
+ # that the Ask move would "refuse loudly" — no longer true.
685
795
 
686
796
  topology_context = repo_topology_context(cfg, repos)
687
797
  discuss_mode, discuss_reason = select_discuss_mode(cfg, submission, discuss_override=discuss)
@@ -1335,22 +1445,77 @@ def _echo_enqueued(row: "OutboxRow", label: str) -> None:
1335
1445
 
1336
1446
 
1337
1447
  @portal_group.command("enqueue-status")
1448
+ @_CONFIG_OPTION
1338
1449
  @click.argument("submission_id")
1339
1450
  @click.argument("status", type=click.Choice(SUBMISSION_STATUSES))
1340
- def portal_enqueue_status(submission_id: str, status: str) -> None:
1451
+ def portal_enqueue_status(config_path, submission_id: str, status: str) -> None:
1341
1452
  """Queue an up-mapped status for SUBMISSION_ID (sent on the next sync).
1342
1453
 
1343
1454
  Unlike `push`, this allocates the revision for you and refuses a status
1344
1455
  that would summon the customer to an empty screen — `awaiting-signoff`
1345
1456
  with no design round queued, `needs-input` with no question (#835).
1457
+
1458
+ **#2996: warns, never refuses, before a `_PULLED_STATUSES` push that
1459
+ would silently withdraw SUBMISSION_ID from decomposition.**
1460
+ `coord.approved_work.approved_submissions` (the "Approved work items"
1461
+ panel's data source) drops any submission whose `last_status` moves to
1462
+ `planned` / `in-progress` / `quality-check` / `shipped` — those four
1463
+ values are only ever supposed to mean "already pulled into a linked
1464
+ milestone/issue and dispatch has begun". Pushing one of them here on a
1465
+ submission with no `coord portal link` on file does that removal anyway,
1466
+ with nothing to say so — the observed failure mode (#2996's own filing)
1467
+ was a status pushed purely to update the customer-facing wording, which
1468
+ happened to also empty the queue and only surfaced later as an unrelated
1469
+ "not a currently-approved portal submission" error. This command still
1470
+ sends the push regardless — there are legitimate reasons to set any of
1471
+ these by hand (a correction, a re-sync, an out-of-band delivery) — it
1472
+ only makes the consequence visible first.
1473
+
1474
+ **#2995: routes through the daemon on a thin client that claims
1475
+ SUBMISSION_ID's mapped repo(s)**, instead of refusing outright like
1476
+ every other state-touching ``enqueue-*`` command — see
1477
+ :func:`_refuse_unless_claiming_machine`. This is the ``enqueue-status``
1478
+ half of the Ask move's exit; ``enqueue-question`` below is the other.
1346
1479
  """
1347
- _refuse_if_thin_client("enqueue-status")
1480
+ cfg = _load_config(config_path)
1481
+ _refuse_unless_claiming_machine(cfg, submission_id, "enqueue-status")
1348
1482
 
1483
+ from coord.approved_work import is_pulled_status # noqa: PLC0415
1349
1484
  from coord.portal_sync import PortalSyncError, enqueue_status # noqa: PLC0415
1350
1485
 
1486
+ if is_pulled_status(status):
1487
+ from coord import portal_store # noqa: PLC0415
1488
+
1489
+ if portal_store.get_link_by_submission(submission_id) is None:
1490
+ click.secho(
1491
+ f"warning: {submission_id} has no linked milestone/issue on "
1492
+ "file (no `coord portal link` recorded) and no decomposition "
1493
+ f"on record — pushing status={status!r} will still be sent, "
1494
+ "but coord treats that status as \"already pulled into "
1495
+ f"decomposition and delivery\": {submission_id} will vanish "
1496
+ "from the TUI's Approved work items panel, and `coord portal "
1497
+ "decompose-chat` will refuse it as no longer approved. If "
1498
+ "the work has not actually been decomposed yet and you just "
1499
+ "want an honest \"we know what's next\" status for the "
1500
+ f"customer, use `coord portal enqueue-status {submission_id} "
1501
+ "in-design` instead — it stays on the queue and announces "
1502
+ "nobody.",
1503
+ fg="yellow",
1504
+ )
1505
+
1506
+ import httpx # noqa: PLC0415
1507
+
1351
1508
  try:
1352
- row = enqueue_status(submission_id, status)
1353
- except PortalSyncError as exc:
1509
+ row = enqueue_status(submission_id, status, config=cfg)
1510
+ except (PortalSyncError, httpx.HTTPStatusError) as exc:
1511
+ # #2995 fix-round: routed through the daemon (see
1512
+ # `_refuse_unless_claiming_machine` above), a rejection comes back
1513
+ # as `httpx.HTTPStatusError` (`board_service.route_write` →
1514
+ # `client.post_record`), not `PortalSyncError` — the daemon-host
1515
+ # path's identical rejection (e.g. an announcing status with
1516
+ # nothing queued) never reaches `post_record` at all. Without this,
1517
+ # a thin-client caller saw a raw traceback where a daemon-host
1518
+ # caller got this same clean red message.
1354
1519
  click.secho(str(exc), fg="red")
1355
1520
  raise SystemExit(1) from exc
1356
1521
  _echo_enqueued(row, f"status={status}")
@@ -1407,23 +1572,38 @@ def portal_enqueue_preview(submission_id: str, preview_url: str) -> None:
1407
1572
 
1408
1573
 
1409
1574
  @portal_group.command("enqueue-question")
1575
+ @_CONFIG_OPTION
1410
1576
  @click.argument("submission_id")
1411
1577
  @click.argument("question")
1412
- def portal_enqueue_question(submission_id: str, question: str) -> None:
1578
+ def portal_enqueue_question(config_path, submission_id: str, question: str) -> None:
1413
1579
  """Queue an open question for SUBMISSION_ID (sent on the next sync).
1414
1580
 
1415
1581
  Also queues the `needs-input` status that announces it (#2901) — a
1416
1582
  question with no status row behind it sends no email, so this command
1417
1583
  always queues both rows in one call rather than leaving the second one
1418
- to a caller who might forget it.
1584
+ to a caller who might forget it. When routed through the daemon (see
1585
+ below), both rows are applied in that one request, so a crash or a
1586
+ dropped response can never leave the question queued without its
1587
+ announcement.
1588
+
1589
+ **#2995: routes through the daemon on a thin client that claims
1590
+ SUBMISSION_ID's mapped repo(s)**, instead of refusing outright — see
1591
+ :func:`_refuse_unless_claiming_machine`. This is the Ask move's other
1592
+ half; ``enqueue-status`` above is the one a plain status push uses.
1419
1593
  """
1420
- _refuse_if_thin_client("enqueue-question")
1594
+ cfg = _load_config(config_path)
1595
+ _refuse_unless_claiming_machine(cfg, submission_id, "enqueue-question")
1421
1596
 
1422
1597
  from coord.portal_sync import PortalSyncError, enqueue_question # noqa: PLC0415
1423
1598
 
1599
+ import httpx # noqa: PLC0415
1600
+
1424
1601
  try:
1425
- question_row, status_row = enqueue_question(submission_id, question)
1426
- except PortalSyncError as exc:
1602
+ question_row, status_row = enqueue_question(submission_id, question, config=cfg)
1603
+ except (PortalSyncError, httpx.HTTPStatusError) as exc:
1604
+ # #2995 fix-round: see the matching comment in `portal_enqueue_status`
1605
+ # above — a routed rejection surfaces as `httpx.HTTPStatusError`, not
1606
+ # `PortalSyncError`.
1427
1607
  click.secho(str(exc), fg="red")
1428
1608
  raise SystemExit(1) from exc
1429
1609
  _echo_enqueued(question_row, "question")
@@ -38,6 +38,7 @@ posture every other dispatcher in this file already uses.
38
38
  from __future__ import annotations
39
39
 
40
40
  import datetime
41
+ import logging
41
42
  import time
42
43
  import uuid
43
44
  from typing import TYPE_CHECKING, Any
@@ -46,6 +47,8 @@ if TYPE_CHECKING: # pragma: no cover - typing only
46
47
  from coord.config import Config
47
48
  from coord.models import Machine
48
49
 
50
+ _log = logging.getLogger(__name__)
51
+
49
52
  #: Sentinel `issue_title` this module writes onto the dispatched assignment
50
53
  #: — mirrors `dispatch_new_issue_chat`'s own `"(new issue draft)"` sentinel
51
54
  #: for a chat type with no real GitHub issue yet. The TUI's own bind path
@@ -546,6 +549,71 @@ def resolve_approved_submission(config: "Config", submission_id: str) -> dict[st
546
549
  )
547
550
 
548
551
 
552
+ def describe_unapproved_submission(config: "Config", submission_id: str) -> str:
553
+ """Human-readable reason :func:`resolve_approved_submission` returned
554
+ ``None`` for *submission_id* (#2996).
555
+
556
+ Names the disqualifying ``last_status`` when that is actually why — most
557
+ often an operator's own ``coord portal enqueue-status`` push to a
558
+ :data:`coord.approved_work._PULLED_STATUSES` value on a submission that
559
+ had not, in fact, been decomposed yet — instead of the generic "is not a
560
+ currently-approved portal submission", which names neither the cause nor
561
+ the status that caused it (the whole complaint in #2996's issue body).
562
+
563
+ Best-effort: the disqualifying-status lookup
564
+ (:func:`coord.approved_work.disqualifying_status`) needs to read the
565
+ daemon's own local :mod:`coord.portal_store` directly, so it is skipped
566
+ (falling back to the plain generic message) when this machine is a thin
567
+ client — the same constraint :func:`resolve_approved_submission` itself
568
+ already works around by routing through the daemon's ``/board`` instead
569
+ of reading the wrong box's empty tables.
570
+
571
+ **This function must never raise.** It exists only to phrase a failure
572
+ its callers have already decided on — ``dispatch_decomposition_chat``
573
+ raises ``RuntimeError(describe_unapproved_submission(...))`` and
574
+ ``_run_decompose_chat_interactive`` prints it — so an exception escaping
575
+ the *enrichment* lookup would replace a clear, actionable error with a
576
+ traceback about a completely different subsystem. The store read is
577
+ therefore best-effort: any failure (an unreadable/locked portal store, a
578
+ schema older than :func:`coord.approved_work.disqualifying_status`
579
+ expects, a thin client that slipped past the ``board_service`` check)
580
+ degrades to the plain generic message, which is exactly the pre-#2996
581
+ behaviour and still correct — just less specific.
582
+ """
583
+ base = f"submission {submission_id!r} is not a currently-approved portal submission"
584
+
585
+ reason: str | None = None
586
+ try:
587
+ from coord import board_service # noqa: PLC0415
588
+
589
+ if board_service.resolve() is None:
590
+ from coord.approved_work import disqualifying_status # noqa: PLC0415
591
+
592
+ reason = disqualifying_status(submission_id)
593
+ except Exception: # noqa: BLE001 — best-effort enrichment, never break the message
594
+ _log.debug(
595
+ "describe_unapproved_submission: disqualifying-status lookup failed "
596
+ "for %s; falling back to the generic message",
597
+ submission_id,
598
+ exc_info=True,
599
+ )
600
+ reason = None
601
+
602
+ if reason:
603
+ return (
604
+ f"{base} — its last_status is {reason!r}, which coord already treats "
605
+ "as pulled into decomposition/delivery (coord.approved_work."
606
+ "_PULLED_STATUSES), so it no longer shows up in the TUI's Approved "
607
+ "work items panel and this command refuses it. If it was pushed to "
608
+ f"that status before decomposition actually happened, `coord portal "
609
+ f"enqueue-status {submission_id} in-design` puts it back on the "
610
+ "queue without re-mailing the customer. Nothing to decompose."
611
+ )
612
+ return (
613
+ f"{base} (coord.approved_work.approved_submissions) — nothing to decompose"
614
+ )
615
+
616
+
549
617
  def dispatch_decomposition_chat(
550
618
  submission_id: str,
551
619
  config: "Config",
@@ -576,10 +644,7 @@ def dispatch_decomposition_chat(
576
644
  """
577
645
  submission = resolve_approved_submission(config, submission_id)
578
646
  if submission is None:
579
- raise RuntimeError(
580
- f"submission {submission_id!r} is not a currently-approved portal "
581
- "submission (coord.approved_work.approved_submissions) — nothing to decompose"
582
- )
647
+ raise RuntimeError(describe_unapproved_submission(config, submission_id))
583
648
 
584
649
  repos: list[str] = submission.get("repos") or []
585
650
  if not repos:
@@ -1749,6 +1749,13 @@ def list_milestone_links() -> list[PortalLink]:
1749
1749
  return [link for link in links if link is not None]
1750
1750
 
1751
1751
 
1752
+ def _get_link_by_submission_local(submission_id: str) -> PortalLink | None:
1753
+ for link in list_milestone_links():
1754
+ if link.submission_id == submission_id:
1755
+ return link
1756
+ return None
1757
+
1758
+
1752
1759
  def get_link_by_submission(submission_id: str) -> PortalLink | None:
1753
1760
  """Reverse lookup: the link for a portal ``submission_id``, if any —
1754
1761
  whether it is scoped to a milestone or (#2665) a single issue.
@@ -1761,11 +1768,29 @@ def get_link_by_submission(submission_id: str) -> PortalLink | None:
1761
1768
  against. Links are few enough (one per submission a customer has ever
1762
1769
  been sent to) that a linear scan of :func:`list_milestone_links` is
1763
1770
  simply the read path — no new index, no new table.
1771
+
1772
+ Every caller until #2995 ran exclusively on the daemon (the tick loop's
1773
+ own consumers, plus ``/portal-answer``'s status fold), so this read
1774
+ stayed local-only. ``coord portal enqueue-status``'s #2996 "no link on
1775
+ file" warning changed that: it is the one CLI-reachable call site, and
1776
+ once ``enqueue-status`` itself started routing through the daemon on a
1777
+ thin client (#2995), a local-only read here would silently check that
1778
+ machine's own empty ``~/.coord/coord.db`` and warn every time, whether or
1779
+ not a link actually exists. Routed through the daemon's
1780
+ ``GET /portal-link-by-submission`` when ``board_service`` is configured,
1781
+ same as :func:`get_portal_link`; fails soft to ``None`` on a routing
1782
+ hiccup for the same reason that function does — "couldn't ask"
1783
+ collapsing to "not linked" is the safe default for a warning-only read.
1764
1784
  """
1765
- for link in list_milestone_links():
1766
- if link.submission_id == submission_id:
1767
- return link
1768
- return None
1785
+ from coord import board_service # noqa: PLC0415
1786
+
1787
+ svc = board_service.resolve()
1788
+ if svc is not None:
1789
+ from coord.client import fetch_portal_link_by_submission # noqa: PLC0415
1790
+
1791
+ raw = fetch_portal_link_by_submission(svc, submission_id)
1792
+ return PortalLink.from_dict(raw) if raw is not None else None
1793
+ return _get_link_by_submission_local(submission_id)
1769
1794
 
1770
1795
 
1771
1796
  # ── the running-context ledger (#2749, IL-3, epic #2746) ────────────────────