code-coordinator 0.5.321__tar.gz → 0.5.323__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.321 → code_coordinator-0.5.323}/PKG-INFO +1 -1
  2. {code_coordinator-0.5.321 → code_coordinator-0.5.323}/code_coordinator.egg-info/PKG-INFO +1 -1
  3. {code_coordinator-0.5.321 → code_coordinator-0.5.323}/code_coordinator.egg-info/SOURCES.txt +1 -0
  4. {code_coordinator-0.5.321 → code_coordinator-0.5.323}/code_coordinator.egg-info/scm_file_list.json +1 -0
  5. {code_coordinator-0.5.321 → code_coordinator-0.5.323}/code_coordinator.egg-info/scm_version.json +2 -2
  6. {code_coordinator-0.5.321 → code_coordinator-0.5.323}/coord/approved_work.py +41 -0
  7. {code_coordinator-0.5.321 → code_coordinator-0.5.323}/coord/commands/portal.py +54 -2
  8. {code_coordinator-0.5.321 → code_coordinator-0.5.323}/coord/config.py +11 -1
  9. {code_coordinator-0.5.321 → code_coordinator-0.5.323}/coord/db.py +27 -2
  10. {code_coordinator-0.5.321 → code_coordinator-0.5.323}/coord/decomposition_chat.py +69 -4
  11. {code_coordinator-0.5.321 → code_coordinator-0.5.323}/coord/portal_bridge.py +4 -0
  12. {code_coordinator-0.5.321 → code_coordinator-0.5.323}/coord/portal_store.py +122 -1
  13. {code_coordinator-0.5.321 → code_coordinator-0.5.323}/coord/portal_sync.py +343 -11
  14. code_coordinator-0.5.323/tests/test_approved_work_2996.py +163 -0
  15. {code_coordinator-0.5.321 → code_coordinator-0.5.323}/tests/test_cli_portal.py +108 -0
  16. {code_coordinator-0.5.321 → code_coordinator-0.5.323}/tests/test_db.py +3 -1
  17. {code_coordinator-0.5.321 → code_coordinator-0.5.323}/tests/test_portal_bridge.py +15 -0
  18. {code_coordinator-0.5.321 → code_coordinator-0.5.323}/tests/test_portal_config.py +1 -0
  19. {code_coordinator-0.5.321 → code_coordinator-0.5.323}/tests/test_portal_store.py +6 -1
  20. {code_coordinator-0.5.321 → code_coordinator-0.5.323}/tests/test_portal_sync.py +402 -0
  21. {code_coordinator-0.5.321 → code_coordinator-0.5.323}/.claude/commands/board.md +0 -0
  22. {code_coordinator-0.5.321 → code_coordinator-0.5.323}/.claude/commands/complete-session.md +0 -0
  23. {code_coordinator-0.5.321 → code_coordinator-0.5.323}/.claude/commands/coordinator.md +0 -0
  24. {code_coordinator-0.5.321 → code_coordinator-0.5.323}/.githooks/_lib.sh +0 -0
  25. {code_coordinator-0.5.321 → code_coordinator-0.5.323}/.githooks/post-checkout +0 -0
  26. {code_coordinator-0.5.321 → code_coordinator-0.5.323}/.githooks/post-commit +0 -0
  27. {code_coordinator-0.5.321 → code_coordinator-0.5.323}/.githooks/post-merge +0 -0
  28. {code_coordinator-0.5.321 → code_coordinator-0.5.323}/.github/ISSUE_TEMPLATE/bug_report.md +0 -0
  29. {code_coordinator-0.5.321 → code_coordinator-0.5.323}/.github/coord-ci-acceptance.yml +0 -0
  30. {code_coordinator-0.5.321 → code_coordinator-0.5.323}/.github/workflows/auto-release.yml +0 -0
  31. {code_coordinator-0.5.321 → code_coordinator-0.5.323}/.github/workflows/publish.yml +0 -0
  32. {code_coordinator-0.5.321 → code_coordinator-0.5.323}/.github/workflows/test.yml +0 -0
  33. {code_coordinator-0.5.321 → code_coordinator-0.5.323}/.gitignore +0 -0
  34. {code_coordinator-0.5.321 → code_coordinator-0.5.323}/CLAUDE.md +0 -0
  35. {code_coordinator-0.5.321 → code_coordinator-0.5.323}/GOAL.md +0 -0
  36. {code_coordinator-0.5.321 → code_coordinator-0.5.323}/LICENSE +0 -0
  37. {code_coordinator-0.5.321 → code_coordinator-0.5.323}/MANIFEST.in +0 -0
  38. {code_coordinator-0.5.321 → code_coordinator-0.5.323}/README.md +0 -0
  39. {code_coordinator-0.5.321 → code_coordinator-0.5.323}/code_coordinator.egg-info/dependency_links.txt +0 -0
  40. {code_coordinator-0.5.321 → code_coordinator-0.5.323}/code_coordinator.egg-info/entry_points.txt +0 -0
  41. {code_coordinator-0.5.321 → code_coordinator-0.5.323}/code_coordinator.egg-info/requires.txt +0 -0
  42. {code_coordinator-0.5.321 → code_coordinator-0.5.323}/code_coordinator.egg-info/top_level.txt +0 -0
  43. {code_coordinator-0.5.321 → code_coordinator-0.5.323}/coord/__init__.py +0 -0
  44. {code_coordinator-0.5.321 → code_coordinator-0.5.323}/coord/_board_mapping.py +0 -0
  45. {code_coordinator-0.5.321 → code_coordinator-0.5.323}/coord/acceptance.py +0 -0
  46. {code_coordinator-0.5.321 → code_coordinator-0.5.323}/coord/acceptance_drivers.py +0 -0
  47. {code_coordinator-0.5.321 → code_coordinator-0.5.323}/coord/agent.py +0 -0
  48. {code_coordinator-0.5.321 → code_coordinator-0.5.323}/coord/agent_app.py +0 -0
  49. {code_coordinator-0.5.321 → code_coordinator-0.5.323}/coord/agent_update.py +0 -0
  50. {code_coordinator-0.5.321 → code_coordinator-0.5.323}/coord/agents/opencode/.gitignore +0 -0
  51. {code_coordinator-0.5.321 → code_coordinator-0.5.323}/coord/agents/opencode/agents/work.md +0 -0
  52. {code_coordinator-0.5.321 → code_coordinator-0.5.323}/coord/agents/opencode/routing.jsonc +0 -0
  53. {code_coordinator-0.5.321 → code_coordinator-0.5.323}/coord/audit.py +0 -0
  54. {code_coordinator-0.5.321 → code_coordinator-0.5.323}/coord/auto_loop.py +0 -0
  55. {code_coordinator-0.5.321 → code_coordinator-0.5.323}/coord/block_log.py +0 -0
  56. {code_coordinator-0.5.321 → code_coordinator-0.5.323}/coord/board_schema.py +0 -0
  57. {code_coordinator-0.5.321 → code_coordinator-0.5.323}/coord/board_service.py +0 -0
  58. {code_coordinator-0.5.321 → code_coordinator-0.5.323}/coord/board_wire.py +0 -0
  59. {code_coordinator-0.5.321 → code_coordinator-0.5.323}/coord/brain.py +0 -0
  60. {code_coordinator-0.5.321 → code_coordinator-0.5.323}/coord/branch_model.py +0 -0
  61. {code_coordinator-0.5.321 → code_coordinator-0.5.323}/coord/bug_intake.py +0 -0
  62. {code_coordinator-0.5.321 → code_coordinator-0.5.323}/coord/cargo_cache.py +0 -0
  63. {code_coordinator-0.5.321 → code_coordinator-0.5.323}/coord/ci_fix.py +0 -0
  64. {code_coordinator-0.5.321 → code_coordinator-0.5.323}/coord/ci_github.py +0 -0
  65. {code_coordinator-0.5.321 → code_coordinator-0.5.323}/coord/ci_gitlab.py +0 -0
  66. {code_coordinator-0.5.321 → code_coordinator-0.5.323}/coord/ci_store.py +0 -0
  67. {code_coordinator-0.5.321 → code_coordinator-0.5.323}/coord/claim.py +0 -0
  68. {code_coordinator-0.5.321 → code_coordinator-0.5.323}/coord/cli.py +0 -0
  69. {code_coordinator-0.5.321 → code_coordinator-0.5.323}/coord/client.py +0 -0
  70. {code_coordinator-0.5.321 → code_coordinator-0.5.323}/coord/commands/__init__.py +0 -0
  71. {code_coordinator-0.5.321 → code_coordinator-0.5.323}/coord/commands/_common.py +0 -0
  72. {code_coordinator-0.5.321 → code_coordinator-0.5.323}/coord/commands/acceptance.py +0 -0
  73. {code_coordinator-0.5.321 → code_coordinator-0.5.323}/coord/commands/agent_ops.py +0 -0
  74. {code_coordinator-0.5.321 → code_coordinator-0.5.323}/coord/commands/audit.py +0 -0
  75. {code_coordinator-0.5.321 → code_coordinator-0.5.323}/coord/commands/chat.py +0 -0
  76. {code_coordinator-0.5.321 → code_coordinator-0.5.323}/coord/commands/dispatch.py +0 -0
  77. {code_coordinator-0.5.321 → code_coordinator-0.5.323}/coord/commands/dispatch_workers.py +0 -0
  78. {code_coordinator-0.5.321 → code_coordinator-0.5.323}/coord/commands/drive.py +0 -0
  79. {code_coordinator-0.5.321 → code_coordinator-0.5.323}/coord/commands/drive_queue.py +0 -0
  80. {code_coordinator-0.5.321 → code_coordinator-0.5.323}/coord/commands/gate_a.py +0 -0
  81. {code_coordinator-0.5.321 → code_coordinator-0.5.323}/coord/commands/gates.py +0 -0
  82. {code_coordinator-0.5.321 → code_coordinator-0.5.323}/coord/commands/issues.py +0 -0
  83. {code_coordinator-0.5.321 → code_coordinator-0.5.323}/coord/commands/lifecycle.py +0 -0
  84. {code_coordinator-0.5.321 → code_coordinator-0.5.323}/coord/commands/machine.py +0 -0
  85. {code_coordinator-0.5.321 → code_coordinator-0.5.323}/coord/commands/merge.py +0 -0
  86. {code_coordinator-0.5.321 → code_coordinator-0.5.323}/coord/commands/milestone.py +0 -0
  87. {code_coordinator-0.5.321 → code_coordinator-0.5.323}/coord/commands/plan_followup.py +0 -0
  88. {code_coordinator-0.5.321 → code_coordinator-0.5.323}/coord/commands/plans.py +0 -0
  89. {code_coordinator-0.5.321 → code_coordinator-0.5.323}/coord/commands/pr.py +0 -0
  90. {code_coordinator-0.5.321 → code_coordinator-0.5.323}/coord/commands/release.py +0 -0
  91. {code_coordinator-0.5.321 → code_coordinator-0.5.323}/coord/commands/repo.py +0 -0
  92. {code_coordinator-0.5.321 → code_coordinator-0.5.323}/coord/commands/report.py +0 -0
  93. {code_coordinator-0.5.321 → code_coordinator-0.5.323}/coord/commands/review.py +0 -0
  94. {code_coordinator-0.5.321 → code_coordinator-0.5.323}/coord/commands/scorecard.py +0 -0
  95. {code_coordinator-0.5.321 → code_coordinator-0.5.323}/coord/commands/sessions.py +0 -0
  96. {code_coordinator-0.5.321 → code_coordinator-0.5.323}/coord/commands/setup.py +0 -0
  97. {code_coordinator-0.5.321 → code_coordinator-0.5.323}/coord/commands/status.py +0 -0
  98. {code_coordinator-0.5.321 → code_coordinator-0.5.323}/coord/commands/store_migrate.py +0 -0
  99. {code_coordinator-0.5.321 → code_coordinator-0.5.323}/coord/commands/terminal.py +0 -0
  100. {code_coordinator-0.5.321 → code_coordinator-0.5.323}/coord/commands/test_gate.py +0 -0
  101. {code_coordinator-0.5.321 → code_coordinator-0.5.323}/coord/commands/tui.py +0 -0
  102. {code_coordinator-0.5.321 → code_coordinator-0.5.323}/coord/comments.py +0 -0
  103. {code_coordinator-0.5.321 → code_coordinator-0.5.323}/coord/config_reload.py +0 -0
  104. {code_coordinator-0.5.321 → code_coordinator-0.5.323}/coord/confirm_test.py +0 -0
  105. {code_coordinator-0.5.321 → code_coordinator-0.5.323}/coord/conflict_fix.py +0 -0
  106. {code_coordinator-0.5.321 → code_coordinator-0.5.323}/coord/dao.py +0 -0
  107. {code_coordinator-0.5.321 → code_coordinator-0.5.323}/coord/dashboard/__init__.py +0 -0
  108. {code_coordinator-0.5.321 → code_coordinator-0.5.323}/coord/dashboard/fixture.py +0 -0
  109. {code_coordinator-0.5.321 → code_coordinator-0.5.323}/coord/dashboard/index.html +0 -0
  110. {code_coordinator-0.5.321 → code_coordinator-0.5.323}/coord/dashboard/server.py +0 -0
  111. {code_coordinator-0.5.321 → code_coordinator-0.5.323}/coord/dashboard/terminal.py +0 -0
  112. {code_coordinator-0.5.321 → code_coordinator-0.5.323}/coord/dead_end.py +0 -0
  113. {code_coordinator-0.5.321 → code_coordinator-0.5.323}/coord/deploy/README.md +0 -0
  114. {code_coordinator-0.5.321 → code_coordinator-0.5.323}/coord/deploy/coord-agent.service +0 -0
  115. {code_coordinator-0.5.321 → code_coordinator-0.5.323}/coord/deploy/coord-db-backup.service +0 -0
  116. {code_coordinator-0.5.321 → code_coordinator-0.5.323}/coord/deploy/coord-db-backup.sh +0 -0
  117. {code_coordinator-0.5.321 → code_coordinator-0.5.323}/coord/deploy/coord-db-backup.timer +0 -0
  118. {code_coordinator-0.5.321 → code_coordinator-0.5.323}/coord/deploy/coord-drive-queue.service +0 -0
  119. {code_coordinator-0.5.321 → code_coordinator-0.5.323}/coord/deploy/coord-drive-queue.timer +0 -0
  120. {code_coordinator-0.5.321 → code_coordinator-0.5.323}/coord/deploy/coord-failure-notify.service +0 -0
  121. {code_coordinator-0.5.321 → code_coordinator-0.5.323}/coord/deploy/coord-fleet-watchdog.service +0 -0
  122. {code_coordinator-0.5.321 → code_coordinator-0.5.323}/coord/deploy/coord-fleet-watchdog.timer +0 -0
  123. {code_coordinator-0.5.321 → code_coordinator-0.5.323}/coord/deploy/coord-notify.service +0 -0
  124. {code_coordinator-0.5.321 → code_coordinator-0.5.323}/coord/deploy/coord-notify.timer +0 -0
  125. {code_coordinator-0.5.321 → code_coordinator-0.5.323}/coord/deploy/coord-release-propagate.service +0 -0
  126. {code_coordinator-0.5.321 → code_coordinator-0.5.323}/coord/deploy/coord-release-propagate.timer +0 -0
  127. {code_coordinator-0.5.321 → code_coordinator-0.5.323}/coord/deploy/coord-release-window.service +0 -0
  128. {code_coordinator-0.5.321 → code_coordinator-0.5.323}/coord/deploy/coord-release-window.timer +0 -0
  129. {code_coordinator-0.5.321 → code_coordinator-0.5.323}/coord/deploy/coord-serve.service +0 -0
  130. {code_coordinator-0.5.321 → code_coordinator-0.5.323}/coord/deploy/coord-web-dist-build.service +0 -0
  131. {code_coordinator-0.5.321 → code_coordinator-0.5.323}/coord/deploy/coord-web-dist-build.timer +0 -0
  132. {code_coordinator-0.5.321 → code_coordinator-0.5.323}/coord/deploy/coord-web.service +0 -0
  133. {code_coordinator-0.5.321 → code_coordinator-0.5.323}/coord/deploy_manifest.py +0 -0
  134. {code_coordinator-0.5.321 → code_coordinator-0.5.323}/coord/deploy_units.py +0 -0
  135. {code_coordinator-0.5.321 → code_coordinator-0.5.323}/coord/deprecation_telemetry.py +0 -0
  136. {code_coordinator-0.5.321 → code_coordinator-0.5.323}/coord/deps.py +0 -0
  137. {code_coordinator-0.5.321 → code_coordinator-0.5.323}/coord/diagnose.py +0 -0
  138. {code_coordinator-0.5.321 → code_coordinator-0.5.323}/coord/dispatch.py +0 -0
  139. {code_coordinator-0.5.321 → code_coordinator-0.5.323}/coord/dist_name.py +0 -0
  140. {code_coordinator-0.5.321 → code_coordinator-0.5.323}/coord/drive.py +0 -0
  141. {code_coordinator-0.5.321 → code_coordinator-0.5.323}/coord/drive_queue.py +0 -0
  142. {code_coordinator-0.5.321 → code_coordinator-0.5.323}/coord/drive_state.py +0 -0
  143. {code_coordinator-0.5.321 → code_coordinator-0.5.323}/coord/events.py +0 -0
  144. {code_coordinator-0.5.321 → code_coordinator-0.5.323}/coord/failure_class.py +0 -0
  145. {code_coordinator-0.5.321 → code_coordinator-0.5.323}/coord/filelock.py +0 -0
  146. {code_coordinator-0.5.321 → code_coordinator-0.5.323}/coord/fleet_config_health.py +0 -0
  147. {code_coordinator-0.5.321 → code_coordinator-0.5.323}/coord/forge_availability.py +0 -0
  148. {code_coordinator-0.5.321 → code_coordinator-0.5.323}/coord/freshness.py +0 -0
  149. {code_coordinator-0.5.321 → code_coordinator-0.5.323}/coord/gate_a.py +0 -0
  150. {code_coordinator-0.5.321 → code_coordinator-0.5.323}/coord/gate_b.py +0 -0
  151. {code_coordinator-0.5.321 → code_coordinator-0.5.323}/coord/gate_snapshot.py +0 -0
  152. {code_coordinator-0.5.321 → code_coordinator-0.5.323}/coord/gates.py +0 -0
  153. {code_coordinator-0.5.321 → code_coordinator-0.5.323}/coord/github_ops.py +0 -0
  154. {code_coordinator-0.5.321 → code_coordinator-0.5.323}/coord/github_throttle.py +0 -0
  155. {code_coordinator-0.5.321 → code_coordinator-0.5.323}/coord/goal.py +0 -0
  156. {code_coordinator-0.5.321 → code_coordinator-0.5.323}/coord/graph_health.py +0 -0
  157. {code_coordinator-0.5.321 → code_coordinator-0.5.323}/coord/health/__init__.py +0 -0
  158. {code_coordinator-0.5.321 → code_coordinator-0.5.323}/coord/health/aggregate.py +0 -0
  159. {code_coordinator-0.5.321 → code_coordinator-0.5.323}/coord/health/checks/__init__.py +0 -0
  160. {code_coordinator-0.5.321 → code_coordinator-0.5.323}/coord/health/checks/_ci_pin.py +0 -0
  161. {code_coordinator-0.5.321 → code_coordinator-0.5.323}/coord/health/checks/agent_install.py +0 -0
  162. {code_coordinator-0.5.321 → code_coordinator-0.5.323}/coord/health/checks/cargo_targets.py +0 -0
  163. {code_coordinator-0.5.321 → code_coordinator-0.5.323}/coord/health/checks/claude_binary.py +0 -0
  164. {code_coordinator-0.5.321 → code_coordinator-0.5.323}/coord/health/checks/coord_tui_ci_pin.py +0 -0
  165. {code_coordinator-0.5.321 → code_coordinator-0.5.323}/coord/health/checks/coord_web_ci_pin.py +0 -0
  166. {code_coordinator-0.5.321 → code_coordinator-0.5.323}/coord/health/checks/deploy_lane_facts.py +0 -0
  167. {code_coordinator-0.5.321 → code_coordinator-0.5.323}/coord/health/checks/disk.py +0 -0
  168. {code_coordinator-0.5.321 → code_coordinator-0.5.323}/coord/health/checks/fleet_board.py +0 -0
  169. {code_coordinator-0.5.321 → code_coordinator-0.5.323}/coord/health/checks/fleet_deploy_lanes.py +0 -0
  170. {code_coordinator-0.5.321 → code_coordinator-0.5.323}/coord/health/checks/fleet_phantom.py +0 -0
  171. {code_coordinator-0.5.321 → code_coordinator-0.5.323}/coord/health/checks/fleet_unit_drift.py +0 -0
  172. {code_coordinator-0.5.321 → code_coordinator-0.5.323}/coord/health/checks/graph.py +0 -0
  173. {code_coordinator-0.5.321 → code_coordinator-0.5.323}/coord/health/checks/graphify_cli.py +0 -0
  174. {code_coordinator-0.5.321 → code_coordinator-0.5.323}/coord/health/checks/index_lock.py +0 -0
  175. {code_coordinator-0.5.321 → code_coordinator-0.5.323}/coord/health/checks/issues_sync_staleness.py +0 -0
  176. {code_coordinator-0.5.321 → code_coordinator-0.5.323}/coord/health/checks/plan_usage.py +0 -0
  177. {code_coordinator-0.5.321 → code_coordinator-0.5.323}/coord/health/checks/release_cordon.py +0 -0
  178. {code_coordinator-0.5.321 → code_coordinator-0.5.323}/coord/health/checks/repo_state.py +0 -0
  179. {code_coordinator-0.5.321 → code_coordinator-0.5.323}/coord/health/checks/spawned_coord.py +0 -0
  180. {code_coordinator-0.5.321 → code_coordinator-0.5.323}/coord/health/checks/stalled_pipeline.py +0 -0
  181. {code_coordinator-0.5.321 → code_coordinator-0.5.323}/coord/health/checks/timer_active.py +0 -0
  182. {code_coordinator-0.5.321 → code_coordinator-0.5.323}/coord/health/checks/toolchain.py +0 -0
  183. {code_coordinator-0.5.321 → code_coordinator-0.5.323}/coord/health/checks/unit_drift.py +0 -0
  184. {code_coordinator-0.5.321 → code_coordinator-0.5.323}/coord/health/checks/unit_enablement.py +0 -0
  185. {code_coordinator-0.5.321 → code_coordinator-0.5.323}/coord/health/checks/wedged_drive_queue.py +0 -0
  186. {code_coordinator-0.5.321 → code_coordinator-0.5.323}/coord/health/checks/worktrees.py +0 -0
  187. {code_coordinator-0.5.321 → code_coordinator-0.5.323}/coord/health/cli.py +0 -0
  188. {code_coordinator-0.5.321 → code_coordinator-0.5.323}/coord/health/context.py +0 -0
  189. {code_coordinator-0.5.321 → code_coordinator-0.5.323}/coord/health/fleet_snapshot.py +0 -0
  190. {code_coordinator-0.5.321 → code_coordinator-0.5.323}/coord/health/models.py +0 -0
  191. {code_coordinator-0.5.321 → code_coordinator-0.5.323}/coord/health/pypi.py +0 -0
  192. {code_coordinator-0.5.321 → code_coordinator-0.5.323}/coord/health/registry.py +0 -0
  193. {code_coordinator-0.5.321 → code_coordinator-0.5.323}/coord/health/render.py +0 -0
  194. {code_coordinator-0.5.321 → code_coordinator-0.5.323}/coord/health/units.py +0 -0
  195. {code_coordinator-0.5.321 → code_coordinator-0.5.323}/coord/hooks.py +0 -0
  196. {code_coordinator-0.5.321 → code_coordinator-0.5.323}/coord/housekeeping.py +0 -0
  197. {code_coordinator-0.5.321 → code_coordinator-0.5.323}/coord/interactive.py +0 -0
  198. {code_coordinator-0.5.321 → code_coordinator-0.5.323}/coord/issue_store.py +0 -0
  199. {code_coordinator-0.5.321 → code_coordinator-0.5.323}/coord/issues_sync_status.py +0 -0
  200. {code_coordinator-0.5.321 → code_coordinator-0.5.323}/coord/liveness_auditor.py +0 -0
  201. {code_coordinator-0.5.321 → code_coordinator-0.5.323}/coord/machine_onboard.py +0 -0
  202. {code_coordinator-0.5.321 → code_coordinator-0.5.323}/coord/machine_pause.py +0 -0
  203. {code_coordinator-0.5.321 → code_coordinator-0.5.323}/coord/merge_queue.py +0 -0
  204. {code_coordinator-0.5.321 → code_coordinator-0.5.323}/coord/milestone_chat.py +0 -0
  205. {code_coordinator-0.5.321 → code_coordinator-0.5.323}/coord/milestone_dispatch.py +0 -0
  206. {code_coordinator-0.5.321 → code_coordinator-0.5.323}/coord/milestone_gate.py +0 -0
  207. {code_coordinator-0.5.321 → code_coordinator-0.5.323}/coord/milestone_order.py +0 -0
  208. {code_coordinator-0.5.321 → code_coordinator-0.5.323}/coord/mock_author.py +0 -0
  209. {code_coordinator-0.5.321 → code_coordinator-0.5.323}/coord/models.py +0 -0
  210. {code_coordinator-0.5.321 → code_coordinator-0.5.323}/coord/network.py +0 -0
  211. {code_coordinator-0.5.321 → code_coordinator-0.5.323}/coord/new_issue_chat.py +0 -0
  212. {code_coordinator-0.5.321 → code_coordinator-0.5.323}/coord/notifier/__init__.py +0 -0
  213. {code_coordinator-0.5.321 → code_coordinator-0.5.323}/coord/notifier/baseline.py +0 -0
  214. {code_coordinator-0.5.321 → code_coordinator-0.5.323}/coord/notifier/cli.py +0 -0
  215. {code_coordinator-0.5.321 → code_coordinator-0.5.323}/coord/notifier/collect.py +0 -0
  216. {code_coordinator-0.5.321 → code_coordinator-0.5.323}/coord/notifier/digest.py +0 -0
  217. {code_coordinator-0.5.321 → code_coordinator-0.5.323}/coord/notifier/models.py +0 -0
  218. {code_coordinator-0.5.321 → code_coordinator-0.5.323}/coord/notifier/predicate.py +0 -0
  219. {code_coordinator-0.5.321 → code_coordinator-0.5.323}/coord/notifier/service.py +0 -0
  220. {code_coordinator-0.5.321 → code_coordinator-0.5.323}/coord/notifier/store.py +0 -0
  221. {code_coordinator-0.5.321 → code_coordinator-0.5.323}/coord/notifier/transport.py +0 -0
  222. {code_coordinator-0.5.321 → code_coordinator-0.5.323}/coord/notify.py +0 -0
  223. {code_coordinator-0.5.321 → code_coordinator-0.5.323}/coord/openapi.py +0 -0
  224. {code_coordinator-0.5.321 → code_coordinator-0.5.323}/coord/overlap_fence.py +0 -0
  225. {code_coordinator-0.5.321 → code_coordinator-0.5.323}/coord/overlap_predict.py +0 -0
  226. {code_coordinator-0.5.321 → code_coordinator-0.5.323}/coord/parentage.py +0 -0
  227. {code_coordinator-0.5.321 → code_coordinator-0.5.323}/coord/parentage_github.py +0 -0
  228. {code_coordinator-0.5.321 → code_coordinator-0.5.323}/coord/pipeline.py +0 -0
  229. {code_coordinator-0.5.321 → code_coordinator-0.5.323}/coord/plan_parser.py +0 -0
  230. {code_coordinator-0.5.321 → code_coordinator-0.5.323}/coord/plans.py +0 -0
  231. {code_coordinator-0.5.321 → code_coordinator-0.5.323}/coord/platform_paths.py +0 -0
  232. {code_coordinator-0.5.321 → code_coordinator-0.5.323}/coord/pr_body_lint.py +0 -0
  233. {code_coordinator-0.5.321 → code_coordinator-0.5.323}/coord/prereqs.py +0 -0
  234. {code_coordinator-0.5.321 → code_coordinator-0.5.323}/coord/progress.py +0 -0
  235. {code_coordinator-0.5.321 → code_coordinator-0.5.323}/coord/providers/__init__.py +0 -0
  236. {code_coordinator-0.5.321 → code_coordinator-0.5.323}/coord/providers/base.py +0 -0
  237. {code_coordinator-0.5.321 → code_coordinator-0.5.323}/coord/providers/claude.py +0 -0
  238. {code_coordinator-0.5.321 → code_coordinator-0.5.323}/coord/providers/claude_pty.py +0 -0
  239. {code_coordinator-0.5.321 → code_coordinator-0.5.323}/coord/providers/opencode.py +0 -0
  240. {code_coordinator-0.5.321 → code_coordinator-0.5.323}/coord/queue_diagnose.py +0 -0
  241. {code_coordinator-0.5.321 → code_coordinator-0.5.323}/coord/reconcile.py +0 -0
  242. {code_coordinator-0.5.321 → code_coordinator-0.5.323}/coord/reconcile_tick.py +0 -0
  243. {code_coordinator-0.5.321 → code_coordinator-0.5.323}/coord/refine_chat.py +0 -0
  244. {code_coordinator-0.5.321 → code_coordinator-0.5.323}/coord/release_cordon.py +0 -0
  245. {code_coordinator-0.5.321 → code_coordinator-0.5.323}/coord/release_propagate.py +0 -0
  246. {code_coordinator-0.5.321 → code_coordinator-0.5.323}/coord/release_verify.py +0 -0
  247. {code_coordinator-0.5.321 → code_coordinator-0.5.323}/coord/release_window.py +0 -0
  248. {code_coordinator-0.5.321 → code_coordinator-0.5.323}/coord/repo_dormancy.py +0 -0
  249. {code_coordinator-0.5.321 → code_coordinator-0.5.323}/coord/repo_edit.py +0 -0
  250. {code_coordinator-0.5.321 → code_coordinator-0.5.323}/coord/repo_onboard.py +0 -0
  251. {code_coordinator-0.5.321 → code_coordinator-0.5.323}/coord/reports.py +0 -0
  252. {code_coordinator-0.5.321 → code_coordinator-0.5.323}/coord/rest_schema.py +0 -0
  253. {code_coordinator-0.5.321 → code_coordinator-0.5.323}/coord/revalidate.py +0 -0
  254. {code_coordinator-0.5.321 → code_coordinator-0.5.323}/coord/review.py +0 -0
  255. {code_coordinator-0.5.321 → code_coordinator-0.5.323}/coord/scorecard.py +0 -0
  256. {code_coordinator-0.5.321 → code_coordinator-0.5.323}/coord/self_health.py +0 -0
  257. {code_coordinator-0.5.321 → code_coordinator-0.5.323}/coord/serve_app.py +0 -0
  258. {code_coordinator-0.5.321 → code_coordinator-0.5.323}/coord/skills/coord-dispatch-verbs/SKILL.md +0 -0
  259. {code_coordinator-0.5.321 → code_coordinator-0.5.323}/coord/skills/drive-queue-preflight/SKILL.md +0 -0
  260. {code_coordinator-0.5.321 → code_coordinator-0.5.323}/coord/skills/fleet-restart-safety/SKILL.md +0 -0
  261. {code_coordinator-0.5.321 → code_coordinator-0.5.323}/coord/skills/merge-stuck-triage/SKILL.md +0 -0
  262. {code_coordinator-0.5.321 → code_coordinator-0.5.323}/coord/skills/pipeline-limbo-triage/SKILL.md +0 -0
  263. {code_coordinator-0.5.321 → code_coordinator-0.5.323}/coord/skills/portal-followup/SKILL.md +0 -0
  264. {code_coordinator-0.5.321 → code_coordinator-0.5.323}/coord/skills/release-now/SKILL.md +0 -0
  265. {code_coordinator-0.5.321 → code_coordinator-0.5.323}/coord/skills/review-verdict-recovery/SKILL.md +0 -0
  266. {code_coordinator-0.5.321 → code_coordinator-0.5.323}/coord/skills/tui-quadraui-workflow/SKILL.md +0 -0
  267. {code_coordinator-0.5.321 → code_coordinator-0.5.323}/coord/skills/update-issue/SKILL.md +0 -0
  268. {code_coordinator-0.5.321 → code_coordinator-0.5.323}/coord/smoke.py +0 -0
  269. {code_coordinator-0.5.321 → code_coordinator-0.5.323}/coord/spend_ceiling.py +0 -0
  270. {code_coordinator-0.5.321 → code_coordinator-0.5.323}/coord/split_work.py +0 -0
  271. {code_coordinator-0.5.321 → code_coordinator-0.5.323}/coord/sql.py +0 -0
  272. {code_coordinator-0.5.321 → code_coordinator-0.5.323}/coord/stage_projection.py +0 -0
  273. {code_coordinator-0.5.321 → code_coordinator-0.5.323}/coord/state.py +0 -0
  274. {code_coordinator-0.5.321 → code_coordinator-0.5.323}/coord/store_migrate.py +0 -0
  275. {code_coordinator-0.5.321 → code_coordinator-0.5.323}/coord/test_author.py +0 -0
  276. {code_coordinator-0.5.321 → code_coordinator-0.5.323}/coord/test_chat.py +0 -0
  277. {code_coordinator-0.5.321 → code_coordinator-0.5.323}/coord/test_orchestrator.py +0 -0
  278. {code_coordinator-0.5.321 → code_coordinator-0.5.323}/coord/test_report.py +0 -0
  279. {code_coordinator-0.5.321 → code_coordinator-0.5.323}/coord/tui_release.py +0 -0
  280. {code_coordinator-0.5.321 → code_coordinator-0.5.323}/coord/usage.py +0 -0
  281. {code_coordinator-0.5.321 → code_coordinator-0.5.323}/coord/usage_limits.py +0 -0
  282. {code_coordinator-0.5.321 → code_coordinator-0.5.323}/coord/usage_rollup.py +0 -0
  283. {code_coordinator-0.5.321 → code_coordinator-0.5.323}/coord/worker_events.py +0 -0
  284. {code_coordinator-0.5.321 → code_coordinator-0.5.323}/coordinator.example.yml +0 -0
  285. {code_coordinator-0.5.321 → code_coordinator-0.5.323}/deploy/coord-agent.service +0 -0
  286. {code_coordinator-0.5.321 → code_coordinator-0.5.323}/deploy/coord-db-backup.service +0 -0
  287. {code_coordinator-0.5.321 → code_coordinator-0.5.323}/deploy/coord-db-backup.sh +0 -0
  288. {code_coordinator-0.5.321 → code_coordinator-0.5.323}/deploy/coord-db-backup.timer +0 -0
  289. {code_coordinator-0.5.321 → code_coordinator-0.5.323}/deploy/coord-drive-queue.service +0 -0
  290. {code_coordinator-0.5.321 → code_coordinator-0.5.323}/deploy/coord-drive-queue.timer +0 -0
  291. {code_coordinator-0.5.321 → code_coordinator-0.5.323}/deploy/coord-failure-notify.service +0 -0
  292. {code_coordinator-0.5.321 → code_coordinator-0.5.323}/deploy/coord-failure-notify.sh +0 -0
  293. {code_coordinator-0.5.321 → code_coordinator-0.5.323}/deploy/coord-fleet-watchdog.service +0 -0
  294. {code_coordinator-0.5.321 → code_coordinator-0.5.323}/deploy/coord-fleet-watchdog.timer +0 -0
  295. {code_coordinator-0.5.321 → code_coordinator-0.5.323}/deploy/coord-notify.service +0 -0
  296. {code_coordinator-0.5.321 → code_coordinator-0.5.323}/deploy/coord-notify.timer +0 -0
  297. {code_coordinator-0.5.321 → code_coordinator-0.5.323}/deploy/coord-release-propagate.service +0 -0
  298. {code_coordinator-0.5.321 → code_coordinator-0.5.323}/deploy/coord-release-propagate.timer +0 -0
  299. {code_coordinator-0.5.321 → code_coordinator-0.5.323}/deploy/coord-release-window.service +0 -0
  300. {code_coordinator-0.5.321 → code_coordinator-0.5.323}/deploy/coord-release-window.timer +0 -0
  301. {code_coordinator-0.5.321 → code_coordinator-0.5.323}/deploy/coord-serve.service +0 -0
  302. {code_coordinator-0.5.321 → code_coordinator-0.5.323}/deploy/coord-web-dist-build.service +0 -0
  303. {code_coordinator-0.5.321 → code_coordinator-0.5.323}/deploy/coord-web-dist-build.sh +0 -0
  304. {code_coordinator-0.5.321 → code_coordinator-0.5.323}/deploy/coord-web-dist-build.timer +0 -0
  305. {code_coordinator-0.5.321 → code_coordinator-0.5.323}/deploy/coord-web-rollback.sh +0 -0
  306. {code_coordinator-0.5.321 → code_coordinator-0.5.323}/deploy/coord-web.service +0 -0
  307. {code_coordinator-0.5.321 → code_coordinator-0.5.323}/deploy/node-shim.sh +0 -0
  308. {code_coordinator-0.5.321 → code_coordinator-0.5.323}/docs/ADR_COORD_TUI_CI.md +0 -0
  309. {code_coordinator-0.5.321 → code_coordinator-0.5.323}/docs/ADR_COORD_WEB_ACCEPTANCE_SUITE.md +0 -0
  310. {code_coordinator-0.5.321 → code_coordinator-0.5.323}/docs/ADR_COORD_WEB_CI.md +0 -0
  311. {code_coordinator-0.5.321 → code_coordinator-0.5.323}/docs/ADR_COORD_WEB_DIST.md +0 -0
  312. {code_coordinator-0.5.321 → code_coordinator-0.5.323}/docs/ADR_PY_RUST_MIRRORS.md +0 -0
  313. {code_coordinator-0.5.321 → code_coordinator-0.5.323}/docs/AGENT_OPERATIONS.md +0 -0
  314. {code_coordinator-0.5.321 → code_coordinator-0.5.323}/docs/ARCHITECTURE.md +0 -0
  315. {code_coordinator-0.5.321 → code_coordinator-0.5.323}/docs/ARCH_SECURITY_GATES.md +0 -0
  316. {code_coordinator-0.5.321 → code_coordinator-0.5.323}/docs/COCKPIT.md +0 -0
  317. {code_coordinator-0.5.321 → code_coordinator-0.5.323}/docs/CONTROL_CENTER.md +0 -0
  318. {code_coordinator-0.5.321 → code_coordinator-0.5.323}/docs/COST_DISCIPLINE.md +0 -0
  319. {code_coordinator-0.5.321 → code_coordinator-0.5.323}/docs/CROSS_PLATFORM.md +0 -0
  320. {code_coordinator-0.5.321 → code_coordinator-0.5.323}/docs/CUSTOMER_FACING_APPS.md +0 -0
  321. {code_coordinator-0.5.321 → code_coordinator-0.5.323}/docs/CUSTOMER_PORTAL.md +0 -0
  322. {code_coordinator-0.5.321 → code_coordinator-0.5.323}/docs/DRIVE_QUEUE.md +0 -0
  323. {code_coordinator-0.5.321 → code_coordinator-0.5.323}/docs/EPHEMERAL_WORKERS.md +0 -0
  324. {code_coordinator-0.5.321 → code_coordinator-0.5.323}/docs/FORGE_MIGRATION.md +0 -0
  325. {code_coordinator-0.5.321 → code_coordinator-0.5.323}/docs/GRAPHIFY_SETUP.md +0 -0
  326. {code_coordinator-0.5.321 → code_coordinator-0.5.323}/docs/ISSUE_GUIDANCE.md +0 -0
  327. {code_coordinator-0.5.321 → code_coordinator-0.5.323}/docs/MAC_MINI.md +0 -0
  328. {code_coordinator-0.5.321 → code_coordinator-0.5.323}/docs/MERGE_AUTO_DRAIN_TRUST_BAR.md +0 -0
  329. {code_coordinator-0.5.321 → code_coordinator-0.5.323}/docs/NOTIFIER.md +0 -0
  330. {code_coordinator-0.5.321 → code_coordinator-0.5.323}/docs/OPENCODE_VERIFICATION.md +0 -0
  331. {code_coordinator-0.5.321 → code_coordinator-0.5.323}/docs/OPERATING_GOTCHAS.md +0 -0
  332. {code_coordinator-0.5.321 → code_coordinator-0.5.323}/docs/OPERATOR_GUIDES.md +0 -0
  333. {code_coordinator-0.5.321 → code_coordinator-0.5.323}/docs/ORACLE_LOOP.md +0 -0
  334. {code_coordinator-0.5.321 → code_coordinator-0.5.323}/docs/PHONE_WEBAPP.md +0 -0
  335. {code_coordinator-0.5.321 → code_coordinator-0.5.323}/docs/PIPELINE_V2.md +0 -0
  336. {code_coordinator-0.5.321 → code_coordinator-0.5.323}/docs/PLATFORM_EVOLUTION.md +0 -0
  337. {code_coordinator-0.5.321 → code_coordinator-0.5.323}/docs/SECOND_BACKEND.md +0 -0
  338. {code_coordinator-0.5.321 → code_coordinator-0.5.323}/docs/STORE_SERVICE.md +0 -0
  339. {code_coordinator-0.5.321 → code_coordinator-0.5.323}/docs/TEST_FIRST_BUG_LANE.md +0 -0
  340. {code_coordinator-0.5.321 → code_coordinator-0.5.323}/docs/WEB_CONTROL_CENTER.md +0 -0
  341. {code_coordinator-0.5.321 → code_coordinator-0.5.323}/docs/WSL_WINDOWS_WORKER.md +0 -0
  342. {code_coordinator-0.5.321 → code_coordinator-0.5.323}/docs/mocks/web/README.md +0 -0
  343. {code_coordinator-0.5.321 → code_coordinator-0.5.323}/docs/mocks/web/_tokens.css +0 -0
  344. {code_coordinator-0.5.321 → code_coordinator-0.5.323}/docs/mocks/web/issue-detail.html +0 -0
  345. {code_coordinator-0.5.321 → code_coordinator-0.5.323}/docs/mocks/web/pipeline-narrow.html +0 -0
  346. {code_coordinator-0.5.321 → code_coordinator-0.5.323}/docs/mocks/web/pipeline-wide.html +0 -0
  347. {code_coordinator-0.5.321 → code_coordinator-0.5.323}/graphify-out/.gitignore +0 -0
  348. {code_coordinator-0.5.321 → code_coordinator-0.5.323}/install-agent.sh +0 -0
  349. {code_coordinator-0.5.321 → code_coordinator-0.5.323}/pyproject.toml +0 -0
  350. {code_coordinator-0.5.321 → code_coordinator-0.5.323}/scripts/audit_review_verdict_overrides.py +0 -0
  351. {code_coordinator-0.5.321 → code_coordinator-0.5.323}/scripts/azure-workers/bootstrap-shared.sh +0 -0
  352. {code_coordinator-0.5.321 → code_coordinator-0.5.323}/scripts/azure-workers/build-worker-image.sh +0 -0
  353. {code_coordinator-0.5.321 → code_coordinator-0.5.323}/scripts/azure-workers/coordinator-machine.py +0 -0
  354. {code_coordinator-0.5.321 → code_coordinator-0.5.323}/scripts/azure-workers/epic-down.sh +0 -0
  355. {code_coordinator-0.5.321 → code_coordinator-0.5.323}/scripts/azure-workers/epic-up.sh +0 -0
  356. {code_coordinator-0.5.321 → code_coordinator-0.5.323}/scripts/azure-workers/preflight.sh +0 -0
  357. {code_coordinator-0.5.321 → code_coordinator-0.5.323}/scripts/azure-workers/provision-worker.sh +0 -0
  358. {code_coordinator-0.5.321 → code_coordinator-0.5.323}/scripts/azure-workers/scrub-and-generalize.sh +0 -0
  359. {code_coordinator-0.5.321 → code_coordinator-0.5.323}/scripts/azure-workers/tailnet-acl.hujson +0 -0
  360. {code_coordinator-0.5.321 → code_coordinator-0.5.323}/scripts/azure-workers/verify-github-token.sh +0 -0
  361. {code_coordinator-0.5.321 → code_coordinator-0.5.323}/scripts/check_gh_argv_containment.py +0 -0
  362. {code_coordinator-0.5.321 → code_coordinator-0.5.323}/scripts/codegen.py +0 -0
  363. {code_coordinator-0.5.321 → code_coordinator-0.5.323}/scripts/coord-test-runner.sh +0 -0
  364. {code_coordinator-0.5.321 → code_coordinator-0.5.323}/scripts/coord-tui-scaffold/.github/coord-ci-acceptance.yml +0 -0
  365. {code_coordinator-0.5.321 → code_coordinator-0.5.323}/scripts/coord-tui-scaffold/.github/workflows/cargo-test.yml +0 -0
  366. {code_coordinator-0.5.321 → code_coordinator-0.5.323}/scripts/coord-tui-scaffold/.github/workflows/codegen-drift.yml +0 -0
  367. {code_coordinator-0.5.321 → code_coordinator-0.5.323}/scripts/coord-tui-scaffold/CLAUDE.md +0 -0
  368. {code_coordinator-0.5.321 → code_coordinator-0.5.323}/scripts/coord-venv-rollback.sh +0 -0
  369. {code_coordinator-0.5.321 → code_coordinator-0.5.323}/scripts/drive-batch.sh +0 -0
  370. {code_coordinator-0.5.321 → code_coordinator-0.5.323}/scripts/extract-coord-tui.sh +0 -0
  371. {code_coordinator-0.5.321 → code_coordinator-0.5.323}/scripts/fleet_watchdog.py +0 -0
  372. {code_coordinator-0.5.321 → code_coordinator-0.5.323}/scripts/gen_board_fixture.py +0 -0
  373. {code_coordinator-0.5.321 → code_coordinator-0.5.323}/scripts/gen_mock_index.py +0 -0
  374. {code_coordinator-0.5.321 → code_coordinator-0.5.323}/scripts/next_release_tag.py +0 -0
  375. {code_coordinator-0.5.321 → code_coordinator-0.5.323}/scripts/run_tests_in_populated_home.sh +0 -0
  376. {code_coordinator-0.5.321 → code_coordinator-0.5.323}/scripts/run_tests_without_gh.sh +0 -0
  377. {code_coordinator-0.5.321 → code_coordinator-0.5.323}/scripts/smoke_437_interactive.py +0 -0
  378. {code_coordinator-0.5.321 → code_coordinator-0.5.323}/scripts/verify_878_review_capture.py +0 -0
  379. {code_coordinator-0.5.321 → code_coordinator-0.5.323}/scripts/verify_release_published.py +0 -0
  380. {code_coordinator-0.5.321 → code_coordinator-0.5.323}/scripts/verify_release_wheel.py +0 -0
  381. {code_coordinator-0.5.321 → code_coordinator-0.5.323}/setup.cfg +0 -0
  382. {code_coordinator-0.5.321 → code_coordinator-0.5.323}/tests/SMOKE_SET.md +0 -0
  383. {code_coordinator-0.5.321 → code_coordinator-0.5.323}/tests/__init__.py +0 -0
  384. {code_coordinator-0.5.321 → code_coordinator-0.5.323}/tests/acceptance/ms-37/conftest.py +0 -0
  385. {code_coordinator-0.5.321 → code_coordinator-0.5.323}/tests/acceptance/ms-37/contract.md +0 -0
  386. {code_coordinator-0.5.321 → code_coordinator-0.5.323}/tests/acceptance/ms-37/manifest.yml +0 -0
  387. {code_coordinator-0.5.321 → code_coordinator-0.5.323}/tests/acceptance/ms-37/test_usage_cli_1115.py +0 -0
  388. {code_coordinator-0.5.321 → code_coordinator-0.5.323}/tests/acceptance/ms-37/test_usage_core_1118.py +0 -0
  389. {code_coordinator-0.5.321 → code_coordinator-0.5.323}/tests/acceptance/ms-51/contract.md +0 -0
  390. {code_coordinator-0.5.321 → code_coordinator-0.5.323}/tests/acceptance/ms-51/home-active-extended.spec.ts +0 -0
  391. {code_coordinator-0.5.321 → code_coordinator-0.5.323}/tests/acceptance/ms-51/home-active.spec.ts +0 -0
  392. {code_coordinator-0.5.321 → code_coordinator-0.5.323}/tests/acceptance/ms-51/manifest.yml +0 -0
  393. {code_coordinator-0.5.321 → code_coordinator-0.5.323}/tests/acceptance/ms-51/mocks/home-active.html +0 -0
  394. {code_coordinator-0.5.321 → code_coordinator-0.5.323}/tests/acceptance/ms-51/tsconfig.json +0 -0
  395. {code_coordinator-0.5.321 → code_coordinator-0.5.323}/tests/acceptance/ms-example/mocks/home-active.html +0 -0
  396. {code_coordinator-0.5.321 → code_coordinator-0.5.323}/tests/backends.py +0 -0
  397. {code_coordinator-0.5.321 → code_coordinator-0.5.323}/tests/conftest.py +0 -0
  398. {code_coordinator-0.5.321 → code_coordinator-0.5.323}/tests/fixtures/board-pipeline-basic.json +0 -0
  399. {code_coordinator-0.5.321 → code_coordinator-0.5.323}/tests/fixtures/board-pipeline-terminal-gates.json +0 -0
  400. {code_coordinator-0.5.321 → code_coordinator-0.5.323}/tests/fixtures/opencode_run_failure_sample.jsonl +0 -0
  401. {code_coordinator-0.5.321 → code_coordinator-0.5.323}/tests/fixtures/opencode_run_length_sample.jsonl +0 -0
  402. {code_coordinator-0.5.321 → code_coordinator-0.5.323}/tests/fixtures/opencode_run_sample.jsonl +0 -0
  403. {code_coordinator-0.5.321 → code_coordinator-0.5.323}/tests/fixtures/playwright/all_pass.json +0 -0
  404. {code_coordinator-0.5.321 → code_coordinator-0.5.323}/tests/fixtures/playwright/global_setup_crash.json +0 -0
  405. {code_coordinator-0.5.321 → code_coordinator-0.5.323}/tests/fixtures/playwright/mixed_fail.json +0 -0
  406. {code_coordinator-0.5.321 → code_coordinator-0.5.323}/tests/fixtures/playwright/retry_then_pass.json +0 -0
  407. {code_coordinator-0.5.321 → code_coordinator-0.5.323}/tests/fixtures/playwright/retry_then_pass.junit.xml +0 -0
  408. {code_coordinator-0.5.321 → code_coordinator-0.5.323}/tests/fixtures/playwright/skip.json +0 -0
  409. {code_coordinator-0.5.321 → code_coordinator-0.5.323}/tests/fixtures/playwright/truncated.json +0 -0
  410. {code_coordinator-0.5.321 → code_coordinator-0.5.323}/tests/fixtures/test_report/cargo_compile_error.txt +0 -0
  411. {code_coordinator-0.5.321 → code_coordinator-0.5.323}/tests/fixtures/test_report/cargo_multi_target_failures.txt +0 -0
  412. {code_coordinator-0.5.321 → code_coordinator-0.5.323}/tests/fixtures/test_report/cargo_no_parseable_failures.txt +0 -0
  413. {code_coordinator-0.5.321 → code_coordinator-0.5.323}/tests/fixtures/test_report/pytest_collection_error.txt +0 -0
  414. {code_coordinator-0.5.321 → code_coordinator-0.5.323}/tests/fixtures/test_report/pytest_error_string_in_body.txt +0 -0
  415. {code_coordinator-0.5.321 → code_coordinator-0.5.323}/tests/fixtures/test_report/pytest_internal_error.txt +0 -0
  416. {code_coordinator-0.5.321 → code_coordinator-0.5.323}/tests/fixtures/test_report/pytest_mixed_failures.txt +0 -0
  417. {code_coordinator-0.5.321 → code_coordinator-0.5.323}/tests/fixtures/test_report/pytest_no_parseable_failures.txt +0 -0
  418. {code_coordinator-0.5.321 → code_coordinator-0.5.323}/tests/test_acceptance.py +0 -0
  419. {code_coordinator-0.5.321 → code_coordinator-0.5.323}/tests/test_acceptance_drivers.py +0 -0
  420. {code_coordinator-0.5.321 → code_coordinator-0.5.323}/tests/test_agent.py +0 -0
  421. {code_coordinator-0.5.321 → code_coordinator-0.5.323}/tests/test_agent_api_error.py +0 -0
  422. {code_coordinator-0.5.321 → code_coordinator-0.5.323}/tests/test_agent_app.py +0 -0
  423. {code_coordinator-0.5.321 → code_coordinator-0.5.323}/tests/test_agent_branch_base.py +0 -0
  424. {code_coordinator-0.5.321 → code_coordinator-0.5.323}/tests/test_agent_branch_capture.py +0 -0
  425. {code_coordinator-0.5.321 → code_coordinator-0.5.323}/tests/test_agent_config_free_1712.py +0 -0
  426. {code_coordinator-0.5.321 → code_coordinator-0.5.323}/tests/test_agent_deploy_units_endpoint.py +0 -0
  427. {code_coordinator-0.5.321 → code_coordinator-0.5.323}/tests/test_agent_dirty_worktree.py +0 -0
  428. {code_coordinator-0.5.321 → code_coordinator-0.5.323}/tests/test_agent_drive_queue_reconcile_2373.py +0 -0
  429. {code_coordinator-0.5.321 → code_coordinator-0.5.323}/tests/test_agent_graph_self_heal.py +0 -0
  430. {code_coordinator-0.5.321 → code_coordinator-0.5.323}/tests/test_agent_health_h3.py +0 -0
  431. {code_coordinator-0.5.321 → code_coordinator-0.5.323}/tests/test_agent_idle_restart.py +0 -0
  432. {code_coordinator-0.5.321 → code_coordinator-0.5.323}/tests/test_agent_push_failure.py +0 -0
  433. {code_coordinator-0.5.321 → code_coordinator-0.5.323}/tests/test_agent_reap.py +0 -0
  434. {code_coordinator-0.5.321 → code_coordinator-0.5.323}/tests/test_agent_repos_and_pull.py +0 -0
  435. {code_coordinator-0.5.321 → code_coordinator-0.5.323}/tests/test_agent_restart_services_endpoint.py +0 -0
  436. {code_coordinator-0.5.321 → code_coordinator-0.5.323}/tests/test_agent_skills_self_heal.py +0 -0
  437. {code_coordinator-0.5.321 → code_coordinator-0.5.323}/tests/test_agent_startup_diagnostics.py +0 -0
  438. {code_coordinator-0.5.321 → code_coordinator-0.5.323}/tests/test_agent_update.py +0 -0
  439. {code_coordinator-0.5.321 → code_coordinator-0.5.323}/tests/test_agent_update_bluegreen.py +0 -0
  440. {code_coordinator-0.5.321 → code_coordinator-0.5.323}/tests/test_agent_usage_limit.py +0 -0
  441. {code_coordinator-0.5.321 → code_coordinator-0.5.323}/tests/test_agent_zero_commit.py +0 -0
  442. {code_coordinator-0.5.321 → code_coordinator-0.5.323}/tests/test_ambient_home_isolation.py +0 -0
  443. {code_coordinator-0.5.321 → code_coordinator-0.5.323}/tests/test_approve_dependency_busy_2804.py +0 -0
  444. {code_coordinator-0.5.321 → code_coordinator-0.5.323}/tests/test_approve_reject_plan.py +0 -0
  445. {code_coordinator-0.5.321 → code_coordinator-0.5.323}/tests/test_approve_usage_gate.py +0 -0
  446. {code_coordinator-0.5.321 → code_coordinator-0.5.323}/tests/test_approved_work_2532.py +0 -0
  447. {code_coordinator-0.5.321 → code_coordinator-0.5.323}/tests/test_assignment_already_recorded_daemon.py +0 -0
  448. {code_coordinator-0.5.321 → code_coordinator-0.5.323}/tests/test_audit_log.py +0 -0
  449. {code_coordinator-0.5.321 → code_coordinator-0.5.323}/tests/test_audit_outcome.py +0 -0
  450. {code_coordinator-0.5.321 → code_coordinator-0.5.323}/tests/test_audit_query.py +0 -0
  451. {code_coordinator-0.5.321 → code_coordinator-0.5.323}/tests/test_auto_loop.py +0 -0
  452. {code_coordinator-0.5.321 → code_coordinator-0.5.323}/tests/test_auto_release_publish_2035.py +0 -0
  453. {code_coordinator-0.5.321 → code_coordinator-0.5.323}/tests/test_backend_selection.py +0 -0
  454. {code_coordinator-0.5.321 → code_coordinator-0.5.323}/tests/test_base_checkout_restore.py +0 -0
  455. {code_coordinator-0.5.321 → code_coordinator-0.5.323}/tests/test_block_log.py +0 -0
  456. {code_coordinator-0.5.321 → code_coordinator-0.5.323}/tests/test_board_cap_762.py +0 -0
  457. {code_coordinator-0.5.321 → code_coordinator-0.5.323}/tests/test_board_fixture.py +0 -0
  458. {code_coordinator-0.5.321 → code_coordinator-0.5.323}/tests/test_board_read_path.py +0 -0
  459. {code_coordinator-0.5.321 → code_coordinator-0.5.323}/tests/test_board_schema.py +0 -0
  460. {code_coordinator-0.5.321 → code_coordinator-0.5.323}/tests/test_board_service.py +0 -0
  461. {code_coordinator-0.5.321 → code_coordinator-0.5.323}/tests/test_board_state.py +0 -0
  462. {code_coordinator-0.5.321 → code_coordinator-0.5.323}/tests/test_board_wire.py +0 -0
  463. {code_coordinator-0.5.321 → code_coordinator-0.5.323}/tests/test_brain.py +0 -0
  464. {code_coordinator-0.5.321 → code_coordinator-0.5.323}/tests/test_branch_model.py +0 -0
  465. {code_coordinator-0.5.321 → code_coordinator-0.5.323}/tests/test_bug_intake.py +0 -0
  466. {code_coordinator-0.5.321 → code_coordinator-0.5.323}/tests/test_build_worker_image_env_update.py +0 -0
  467. {code_coordinator-0.5.321 → code_coordinator-0.5.323}/tests/test_cargo_cache.py +0 -0
  468. {code_coordinator-0.5.321 → code_coordinator-0.5.323}/tests/test_check_gh_argv_containment.py +0 -0
  469. {code_coordinator-0.5.321 → code_coordinator-0.5.323}/tests/test_ci_acceptance_gate_1950.py +0 -0
  470. {code_coordinator-0.5.321 → code_coordinator-0.5.323}/tests/test_ci_fix.py +0 -0
  471. {code_coordinator-0.5.321 → code_coordinator-0.5.323}/tests/test_ci_gitlab.py +0 -0
  472. {code_coordinator-0.5.321 → code_coordinator-0.5.323}/tests/test_ci_parity_2091.py +0 -0
  473. {code_coordinator-0.5.321 → code_coordinator-0.5.323}/tests/test_ci_store.py +0 -0
  474. {code_coordinator-0.5.321 → code_coordinator-0.5.323}/tests/test_claim.py +0 -0
  475. {code_coordinator-0.5.321 → code_coordinator-0.5.323}/tests/test_claude_md_budget.py +0 -0
  476. {code_coordinator-0.5.321 → code_coordinator-0.5.323}/tests/test_cli_acceptance.py +0 -0
  477. {code_coordinator-0.5.321 → code_coordinator-0.5.323}/tests/test_cli_assign.py +0 -0
  478. {code_coordinator-0.5.321 → code_coordinator-0.5.323}/tests/test_cli_assign_interactive_oracle_gate.py +0 -0
  479. {code_coordinator-0.5.321 → code_coordinator-0.5.323}/tests/test_cli_assign_interactive_remote.py +0 -0
  480. {code_coordinator-0.5.321 → code_coordinator-0.5.323}/tests/test_cli_assign_provider.py +0 -0
  481. {code_coordinator-0.5.321 → code_coordinator-0.5.323}/tests/test_cli_assign_repo_drift_2219.py +0 -0
  482. {code_coordinator-0.5.321 → code_coordinator-0.5.323}/tests/test_cli_audit.py +0 -0
  483. {code_coordinator-0.5.321 → code_coordinator-0.5.323}/tests/test_cli_chat_continue.py +0 -0
  484. {code_coordinator-0.5.321 → code_coordinator-0.5.323}/tests/test_cli_decide.py +0 -0
  485. {code_coordinator-0.5.321 → code_coordinator-0.5.323}/tests/test_cli_diagnose_capability_rules.py +0 -0
  486. {code_coordinator-0.5.321 → code_coordinator-0.5.323}/tests/test_cli_diagnose_config_provenance.py +0 -0
  487. {code_coordinator-0.5.321 → code_coordinator-0.5.323}/tests/test_cli_diagnose_forge_availability.py +0 -0
  488. {code_coordinator-0.5.321 → code_coordinator-0.5.323}/tests/test_cli_diagnose_graph.py +0 -0
  489. {code_coordinator-0.5.321 → code_coordinator-0.5.323}/tests/test_cli_diagnose_self.py +0 -0
  490. {code_coordinator-0.5.321 → code_coordinator-0.5.323}/tests/test_cli_diagnose_test_coverage.py +0 -0
  491. {code_coordinator-0.5.321 → code_coordinator-0.5.323}/tests/test_cli_doctor.py +0 -0
  492. {code_coordinator-0.5.321 → code_coordinator-0.5.323}/tests/test_cli_doctor_config_free_1801.py +0 -0
  493. {code_coordinator-0.5.321 → code_coordinator-0.5.323}/tests/test_cli_doctor_config_mismatch_1712.py +0 -0
  494. {code_coordinator-0.5.321 → code_coordinator-0.5.323}/tests/test_cli_drive.py +0 -0
  495. {code_coordinator-0.5.321 → code_coordinator-0.5.323}/tests/test_cli_drive_queue.py +0 -0
  496. {code_coordinator-0.5.321 → code_coordinator-0.5.323}/tests/test_cli_escalate.py +0 -0
  497. {code_coordinator-0.5.321 → code_coordinator-0.5.323}/tests/test_cli_fix_headless_review.py +0 -0
  498. {code_coordinator-0.5.321 → code_coordinator-0.5.323}/tests/test_cli_gate_a.py +0 -0
  499. {code_coordinator-0.5.321 → code_coordinator-0.5.323}/tests/test_cli_install_drift.py +0 -0
  500. {code_coordinator-0.5.321 → code_coordinator-0.5.323}/tests/test_cli_install_skills.py +0 -0
  501. {code_coordinator-0.5.321 → code_coordinator-0.5.323}/tests/test_cli_issue_comment.py +0 -0
  502. {code_coordinator-0.5.321 → code_coordinator-0.5.323}/tests/test_cli_issue_create_label.py +0 -0
  503. {code_coordinator-0.5.321 → code_coordinator-0.5.323}/tests/test_cli_issue_reopen.py +0 -0
  504. {code_coordinator-0.5.321 → code_coordinator-0.5.323}/tests/test_cli_issue_view_list.py +0 -0
  505. {code_coordinator-0.5.321 → code_coordinator-0.5.323}/tests/test_cli_merge.py +0 -0
  506. {code_coordinator-0.5.321 → code_coordinator-0.5.323}/tests/test_cli_milestone_assign.py +0 -0
  507. {code_coordinator-0.5.321 → code_coordinator-0.5.323}/tests/test_cli_milestone_capture.py +0 -0
  508. {code_coordinator-0.5.321 → code_coordinator-0.5.323}/tests/test_cli_milestone_chat_add_child.py +0 -0
  509. {code_coordinator-0.5.321 → code_coordinator-0.5.323}/tests/test_cli_milestone_dispatch.py +0 -0
  510. {code_coordinator-0.5.321 → code_coordinator-0.5.323}/tests/test_cli_milestone_gate_b.py +0 -0
  511. {code_coordinator-0.5.321 → code_coordinator-0.5.323}/tests/test_cli_milestone_gate_c.py +0 -0
  512. {code_coordinator-0.5.321 → code_coordinator-0.5.323}/tests/test_cli_milestone_order.py +0 -0
  513. {code_coordinator-0.5.321 → code_coordinator-0.5.323}/tests/test_cli_milestone_remove_and_issue_close.py +0 -0
  514. {code_coordinator-0.5.321 → code_coordinator-0.5.323}/tests/test_cli_milestone_ship.py +0 -0
  515. {code_coordinator-0.5.321 → code_coordinator-0.5.323}/tests/test_cli_network.py +0 -0
  516. {code_coordinator-0.5.321 → code_coordinator-0.5.323}/tests/test_cli_new_issue_chat.py +0 -0
  517. {code_coordinator-0.5.321 → code_coordinator-0.5.323}/tests/test_cli_plans.py +0 -0
  518. {code_coordinator-0.5.321 → code_coordinator-0.5.323}/tests/test_cli_pr.py +0 -0
  519. {code_coordinator-0.5.321 → code_coordinator-0.5.323}/tests/test_cli_pull_artifact.py +0 -0
  520. {code_coordinator-0.5.321 → code_coordinator-0.5.323}/tests/test_cli_queue.py +0 -0
  521. {code_coordinator-0.5.321 → code_coordinator-0.5.323}/tests/test_cli_reattach_sessions.py +0 -0
  522. {code_coordinator-0.5.321 → code_coordinator-0.5.323}/tests/test_cli_refine_board.py +0 -0
  523. {code_coordinator-0.5.321 → code_coordinator-0.5.323}/tests/test_cli_release_preflight.py +0 -0
  524. {code_coordinator-0.5.321 → code_coordinator-0.5.323}/tests/test_cli_release_propagate.py +0 -0
  525. {code_coordinator-0.5.321 → code_coordinator-0.5.323}/tests/test_cli_release_window.py +0 -0
  526. {code_coordinator-0.5.321 → code_coordinator-0.5.323}/tests/test_cli_repo_2220.py +0 -0
  527. {code_coordinator-0.5.321 → code_coordinator-0.5.323}/tests/test_cli_review_test_author_tracking_epic_2639.py +0 -0
  528. {code_coordinator-0.5.321 → code_coordinator-0.5.323}/tests/test_cli_scorecard.py +0 -0
  529. {code_coordinator-0.5.321 → code_coordinator-0.5.323}/tests/test_cli_set_review_findings.py +0 -0
  530. {code_coordinator-0.5.321 → code_coordinator-0.5.323}/tests/test_cli_status_advisory_terminal.py +0 -0
  531. {code_coordinator-0.5.321 → code_coordinator-0.5.323}/tests/test_cli_status_contested_tag.py +0 -0
  532. {code_coordinator-0.5.321 → code_coordinator-0.5.323}/tests/test_cli_status_merge_queue.py +0 -0
  533. {code_coordinator-0.5.321 → code_coordinator-0.5.323}/tests/test_cli_status_provider.py +0 -0
  534. {code_coordinator-0.5.321 → code_coordinator-0.5.323}/tests/test_cli_status_review_finalizing.py +0 -0
  535. {code_coordinator-0.5.321 → code_coordinator-0.5.323}/tests/test_cli_status_test_failed_tag.py +0 -0
  536. {code_coordinator-0.5.321 → code_coordinator-0.5.323}/tests/test_cli_status_usage_limit.py +0 -0
  537. {code_coordinator-0.5.321 → code_coordinator-0.5.323}/tests/test_cli_sync_comments_873.py +0 -0
  538. {code_coordinator-0.5.321 → code_coordinator-0.5.323}/tests/test_cli_test_plan.py +0 -0
  539. {code_coordinator-0.5.321 → code_coordinator-0.5.323}/tests/test_cli_track.py +0 -0
  540. {code_coordinator-0.5.321 → code_coordinator-0.5.323}/tests/test_cli_tui_update.py +0 -0
  541. {code_coordinator-0.5.321 → code_coordinator-0.5.323}/tests/test_cli_wait.py +0 -0
  542. {code_coordinator-0.5.321 → code_coordinator-0.5.323}/tests/test_client_base_install.py +0 -0
  543. {code_coordinator-0.5.321 → code_coordinator-0.5.323}/tests/test_client_resource_migration_1946.py +0 -0
  544. {code_coordinator-0.5.321 → code_coordinator-0.5.323}/tests/test_commands_common.py +0 -0
  545. {code_coordinator-0.5.321 → code_coordinator-0.5.323}/tests/test_comments.py +0 -0
  546. {code_coordinator-0.5.321 → code_coordinator-0.5.323}/tests/test_completion_summary.py +0 -0
  547. {code_coordinator-0.5.321 → code_coordinator-0.5.323}/tests/test_config.py +0 -0
  548. {code_coordinator-0.5.321 → code_coordinator-0.5.323}/tests/test_config_acceptance.py +0 -0
  549. {code_coordinator-0.5.321 → code_coordinator-0.5.323}/tests/test_config_audit.py +0 -0
  550. {code_coordinator-0.5.321 → code_coordinator-0.5.323}/tests/test_config_pricing.py +0 -0
  551. {code_coordinator-0.5.321 → code_coordinator-0.5.323}/tests/test_config_snapshot_noncanonical_2208.py +0 -0
  552. {code_coordinator-0.5.321 → code_coordinator-0.5.323}/tests/test_config_usage_gate.py +0 -0
  553. {code_coordinator-0.5.321 → code_coordinator-0.5.323}/tests/test_confirm_test.py +0 -0
  554. {code_coordinator-0.5.321 → code_coordinator-0.5.323}/tests/test_conflict_fix.py +0 -0
  555. {code_coordinator-0.5.321 → code_coordinator-0.5.323}/tests/test_conflict_fix_semantic.py +0 -0
  556. {code_coordinator-0.5.321 → code_coordinator-0.5.323}/tests/test_coord_log_daemon_fallback_2547.py +0 -0
  557. {code_coordinator-0.5.321 → code_coordinator-0.5.323}/tests/test_coord_test.py +0 -0
  558. {code_coordinator-0.5.321 → code_coordinator-0.5.323}/tests/test_coord_test_runner_acceptance_toolchain_2936.py +0 -0
  559. {code_coordinator-0.5.321 → code_coordinator-0.5.323}/tests/test_coord_test_runner_baseline.py +0 -0
  560. {code_coordinator-0.5.321 → code_coordinator-0.5.323}/tests/test_coord_test_runner_populated_home.py +0 -0
  561. {code_coordinator-0.5.321 → code_coordinator-0.5.323}/tests/test_coord_test_runner_routing.py +0 -0
  562. {code_coordinator-0.5.321 → code_coordinator-0.5.323}/tests/test_coord_test_runner_toolchain.py +0 -0
  563. {code_coordinator-0.5.321 → code_coordinator-0.5.323}/tests/test_coord_uat.py +0 -0
  564. {code_coordinator-0.5.321 → code_coordinator-0.5.323}/tests/test_coord_web_sse_restart_live.py +0 -0
  565. {code_coordinator-0.5.321 → code_coordinator-0.5.323}/tests/test_coordinator_machine.py +0 -0
  566. {code_coordinator-0.5.321 → code_coordinator-0.5.323}/tests/test_cross_platform_imports.py +0 -0
  567. {code_coordinator-0.5.321 → code_coordinator-0.5.323}/tests/test_dao.py +0 -0
  568. {code_coordinator-0.5.321 → code_coordinator-0.5.323}/tests/test_dashboard.py +0 -0
  569. {code_coordinator-0.5.321 → code_coordinator-0.5.323}/tests/test_dashboard_api.py +0 -0
  570. {code_coordinator-0.5.321 → code_coordinator-0.5.323}/tests/test_dashboard_fixture.py +0 -0
  571. {code_coordinator-0.5.321 → code_coordinator-0.5.323}/tests/test_dashboard_terminal.py +0 -0
  572. {code_coordinator-0.5.321 → code_coordinator-0.5.323}/tests/test_dashboard_terminal_live.py +0 -0
  573. {code_coordinator-0.5.321 → code_coordinator-0.5.323}/tests/test_dead_end.py +0 -0
  574. {code_coordinator-0.5.321 → code_coordinator-0.5.323}/tests/test_decomposition_chat.py +0 -0
  575. {code_coordinator-0.5.321 → code_coordinator-0.5.323}/tests/test_deploy_coord_db_backup.py +0 -0
  576. {code_coordinator-0.5.321 → code_coordinator-0.5.323}/tests/test_deploy_coord_web_dist.py +0 -0
  577. {code_coordinator-0.5.321 → code_coordinator-0.5.323}/tests/test_deploy_coord_web_rollback.py +0 -0
  578. {code_coordinator-0.5.321 → code_coordinator-0.5.323}/tests/test_deploy_drive_queue_unit.py +0 -0
  579. {code_coordinator-0.5.321 → code_coordinator-0.5.323}/tests/test_deploy_failure_notify_unit.py +0 -0
  580. {code_coordinator-0.5.321 → code_coordinator-0.5.323}/tests/test_deploy_manifest.py +0 -0
  581. {code_coordinator-0.5.321 → code_coordinator-0.5.323}/tests/test_deploy_notify_unit.py +0 -0
  582. {code_coordinator-0.5.321 → code_coordinator-0.5.323}/tests/test_deploy_units_lane.py +0 -0
  583. {code_coordinator-0.5.321 → code_coordinator-0.5.323}/tests/test_deploy_web_unit.py +0 -0
  584. {code_coordinator-0.5.321 → code_coordinator-0.5.323}/tests/test_deprecation_telemetry.py +0 -0
  585. {code_coordinator-0.5.321 → code_coordinator-0.5.323}/tests/test_deps.py +0 -0
  586. {code_coordinator-0.5.321 → code_coordinator-0.5.323}/tests/test_diagnose.py +0 -0
  587. {code_coordinator-0.5.321 → code_coordinator-0.5.323}/tests/test_dispatch.py +0 -0
  588. {code_coordinator-0.5.321 → code_coordinator-0.5.323}/tests/test_dispatch_target_validation.py +0 -0
  589. {code_coordinator-0.5.321 → code_coordinator-0.5.323}/tests/test_dist_name.py +0 -0
  590. {code_coordinator-0.5.321 → code_coordinator-0.5.323}/tests/test_done_housekeeping.py +0 -0
  591. {code_coordinator-0.5.321 → code_coordinator-0.5.323}/tests/test_drive.py +0 -0
  592. {code_coordinator-0.5.321 → code_coordinator-0.5.323}/tests/test_drive_queue.py +0 -0
  593. {code_coordinator-0.5.321 → code_coordinator-0.5.323}/tests/test_drive_queue_blocked_rendering.py +0 -0
  594. {code_coordinator-0.5.321 → code_coordinator-0.5.323}/tests/test_drive_queue_launch_argv.py +0 -0
  595. {code_coordinator-0.5.321 → code_coordinator-0.5.323}/tests/test_drive_queue_max_parallel_per_repo_config.py +0 -0
  596. {code_coordinator-0.5.321 → code_coordinator-0.5.323}/tests/test_drive_queue_roll_pending.py +0 -0
  597. {code_coordinator-0.5.321 → code_coordinator-0.5.323}/tests/test_drive_queue_self_cordon_escalation.py +0 -0
  598. {code_coordinator-0.5.321 → code_coordinator-0.5.323}/tests/test_drive_state.py +0 -0
  599. {code_coordinator-0.5.321 → code_coordinator-0.5.323}/tests/test_drive_tmux.py +0 -0
  600. {code_coordinator-0.5.321 → code_coordinator-0.5.323}/tests/test_epic_up_capability_detection.py +0 -0
  601. {code_coordinator-0.5.321 → code_coordinator-0.5.323}/tests/test_epic_up_down_symlinked_config_1887.py +0 -0
  602. {code_coordinator-0.5.321 → code_coordinator-0.5.323}/tests/test_epic_up_image_provenance.py +0 -0
  603. {code_coordinator-0.5.321 → code_coordinator-0.5.323}/tests/test_errors.py +0 -0
  604. {code_coordinator-0.5.321 → code_coordinator-0.5.323}/tests/test_events.py +0 -0
  605. {code_coordinator-0.5.321 → code_coordinator-0.5.323}/tests/test_failure_class.py +0 -0
  606. {code_coordinator-0.5.321 → code_coordinator-0.5.323}/tests/test_filelock.py +0 -0
  607. {code_coordinator-0.5.321 → code_coordinator-0.5.323}/tests/test_finalize_interactive_exit_test_verdict.py +0 -0
  608. {code_coordinator-0.5.321 → code_coordinator-0.5.323}/tests/test_fix_of_force_override.py +0 -0
  609. {code_coordinator-0.5.321 → code_coordinator-0.5.323}/tests/test_fleet_config_health.py +0 -0
  610. {code_coordinator-0.5.321 → code_coordinator-0.5.323}/tests/test_fleet_health_probes.py +0 -0
  611. {code_coordinator-0.5.321 → code_coordinator-0.5.323}/tests/test_fleet_health_snapshot.py +0 -0
  612. {code_coordinator-0.5.321 → code_coordinator-0.5.323}/tests/test_fleet_watchdog.py +0 -0
  613. {code_coordinator-0.5.321 → code_coordinator-0.5.323}/tests/test_forge_availability.py +0 -0
  614. {code_coordinator-0.5.321 → code_coordinator-0.5.323}/tests/test_freshness.py +0 -0
  615. {code_coordinator-0.5.321 → code_coordinator-0.5.323}/tests/test_gate_a.py +0 -0
  616. {code_coordinator-0.5.321 → code_coordinator-0.5.323}/tests/test_gate_b.py +0 -0
  617. {code_coordinator-0.5.321 → code_coordinator-0.5.323}/tests/test_gate_snapshot_staleness.py +0 -0
  618. {code_coordinator-0.5.321 → code_coordinator-0.5.323}/tests/test_gates.py +0 -0
  619. {code_coordinator-0.5.321 → code_coordinator-0.5.323}/tests/test_gather_fleet_tmux_sessions.py +0 -0
  620. {code_coordinator-0.5.321 → code_coordinator-0.5.323}/tests/test_gen_mock_index.py +0 -0
  621. {code_coordinator-0.5.321 → code_coordinator-0.5.323}/tests/test_generated_rust_fixture.py +0 -0
  622. {code_coordinator-0.5.321 → code_coordinator-0.5.323}/tests/test_generated_rust_requests.py +0 -0
  623. {code_coordinator-0.5.321 → code_coordinator-0.5.323}/tests/test_generated_types_fixture.py +0 -0
  624. {code_coordinator-0.5.321 → code_coordinator-0.5.323}/tests/test_github_ops.py +0 -0
  625. {code_coordinator-0.5.321 → code_coordinator-0.5.323}/tests/test_github_throttle.py +0 -0
  626. {code_coordinator-0.5.321 → code_coordinator-0.5.323}/tests/test_goal.py +0 -0
  627. {code_coordinator-0.5.321 → code_coordinator-0.5.323}/tests/test_graph_health.py +0 -0
  628. {code_coordinator-0.5.321 → code_coordinator-0.5.323}/tests/test_graph_selfheal_absent_2237.py +0 -0
  629. {code_coordinator-0.5.321 → code_coordinator-0.5.323}/tests/test_handoff.py +0 -0
  630. {code_coordinator-0.5.321 → code_coordinator-0.5.323}/tests/test_health_checks.py +0 -0
  631. {code_coordinator-0.5.321 → code_coordinator-0.5.323}/tests/test_health_cli.py +0 -0
  632. {code_coordinator-0.5.321 → code_coordinator-0.5.323}/tests/test_health_cli_graph.py +0 -0
  633. {code_coordinator-0.5.321 → code_coordinator-0.5.323}/tests/test_health_config.py +0 -0
  634. {code_coordinator-0.5.321 → code_coordinator-0.5.323}/tests/test_health_context.py +0 -0
  635. {code_coordinator-0.5.321 → code_coordinator-0.5.323}/tests/test_health_coord_tui_ci_pin.py +0 -0
  636. {code_coordinator-0.5.321 → code_coordinator-0.5.323}/tests/test_health_coord_web_ci_pin.py +0 -0
  637. {code_coordinator-0.5.321 → code_coordinator-0.5.323}/tests/test_health_deploy_lane_facts.py +0 -0
  638. {code_coordinator-0.5.321 → code_coordinator-0.5.323}/tests/test_health_fix.py +0 -0
  639. {code_coordinator-0.5.321 → code_coordinator-0.5.323}/tests/test_health_incident_regression.py +0 -0
  640. {code_coordinator-0.5.321 → code_coordinator-0.5.323}/tests/test_health_issues_sync_staleness.py +0 -0
  641. {code_coordinator-0.5.321 → code_coordinator-0.5.323}/tests/test_health_pypi.py +0 -0
  642. {code_coordinator-0.5.321 → code_coordinator-0.5.323}/tests/test_health_registry.py +0 -0
  643. {code_coordinator-0.5.321 → code_coordinator-0.5.323}/tests/test_health_release_cordon_probe.py +0 -0
  644. {code_coordinator-0.5.321 → code_coordinator-0.5.323}/tests/test_health_timer_active.py +0 -0
  645. {code_coordinator-0.5.321 → code_coordinator-0.5.323}/tests/test_health_toolchain.py +0 -0
  646. {code_coordinator-0.5.321 → code_coordinator-0.5.323}/tests/test_health_unit_drift.py +0 -0
  647. {code_coordinator-0.5.321 → code_coordinator-0.5.323}/tests/test_health_unit_enablement.py +0 -0
  648. {code_coordinator-0.5.321 → code_coordinator-0.5.323}/tests/test_health_wedged_drive_queue.py +0 -0
  649. {code_coordinator-0.5.321 → code_coordinator-0.5.323}/tests/test_hooks.py +0 -0
  650. {code_coordinator-0.5.321 → code_coordinator-0.5.323}/tests/test_human_attended_437.py +0 -0
  651. {code_coordinator-0.5.321 → code_coordinator-0.5.323}/tests/test_init.py +0 -0
  652. {code_coordinator-0.5.321 → code_coordinator-0.5.323}/tests/test_install_agent_venv_2911.py +0 -0
  653. {code_coordinator-0.5.321 → code_coordinator-0.5.323}/tests/test_integration.py +0 -0
  654. {code_coordinator-0.5.321 → code_coordinator-0.5.323}/tests/test_interactive_briefing_echo.py +0 -0
  655. {code_coordinator-0.5.321 → code_coordinator-0.5.323}/tests/test_interactive_pane_log_2541.py +0 -0
  656. {code_coordinator-0.5.321 → code_coordinator-0.5.323}/tests/test_interactive_prefill_state.py +0 -0
  657. {code_coordinator-0.5.321 → code_coordinator-0.5.323}/tests/test_interactive_session_relaunch.py +0 -0
  658. {code_coordinator-0.5.321 → code_coordinator-0.5.323}/tests/test_interactive_test_verdict_backstop.py +0 -0
  659. {code_coordinator-0.5.321 → code_coordinator-0.5.323}/tests/test_interactive_token_attribution.py +0 -0
  660. {code_coordinator-0.5.321 → code_coordinator-0.5.323}/tests/test_interactive_worktree.py +0 -0
  661. {code_coordinator-0.5.321 → code_coordinator-0.5.323}/tests/test_issue_store_seam.py +0 -0
  662. {code_coordinator-0.5.321 → code_coordinator-0.5.323}/tests/test_issues_sync_status.py +0 -0
  663. {code_coordinator-0.5.321 → code_coordinator-0.5.323}/tests/test_liveness_auditor.py +0 -0
  664. {code_coordinator-0.5.321 → code_coordinator-0.5.323}/tests/test_liveness_notify.py +0 -0
  665. {code_coordinator-0.5.321 → code_coordinator-0.5.323}/tests/test_lock_contention_ratchet.py +0 -0
  666. {code_coordinator-0.5.321 → code_coordinator-0.5.323}/tests/test_machine_onboard.py +0 -0
  667. {code_coordinator-0.5.321 → code_coordinator-0.5.323}/tests/test_machine_pause.py +0 -0
  668. {code_coordinator-0.5.321 → code_coordinator-0.5.323}/tests/test_merge_queue.py +0 -0
  669. {code_coordinator-0.5.321 → code_coordinator-0.5.323}/tests/test_merge_verify.py +0 -0
  670. {code_coordinator-0.5.321 → code_coordinator-0.5.323}/tests/test_milestone_chat.py +0 -0
  671. {code_coordinator-0.5.321 → code_coordinator-0.5.323}/tests/test_milestone_dispatch.py +0 -0
  672. {code_coordinator-0.5.321 → code_coordinator-0.5.323}/tests/test_milestone_gate.py +0 -0
  673. {code_coordinator-0.5.321 → code_coordinator-0.5.323}/tests/test_milestone_order.py +0 -0
  674. {code_coordinator-0.5.321 → code_coordinator-0.5.323}/tests/test_milestone_seam.py +0 -0
  675. {code_coordinator-0.5.321 → code_coordinator-0.5.323}/tests/test_mock_author.py +0 -0
  676. {code_coordinator-0.5.321 → code_coordinator-0.5.323}/tests/test_model_tiering.py +0 -0
  677. {code_coordinator-0.5.321 → code_coordinator-0.5.323}/tests/test_models.py +0 -0
  678. {code_coordinator-0.5.321 → code_coordinator-0.5.323}/tests/test_models_config_labels.py +0 -0
  679. {code_coordinator-0.5.321 → code_coordinator-0.5.323}/tests/test_needs_attention.py +0 -0
  680. {code_coordinator-0.5.321 → code_coordinator-0.5.323}/tests/test_network.py +0 -0
  681. {code_coordinator-0.5.321 → code_coordinator-0.5.323}/tests/test_new_issue_chat.py +0 -0
  682. {code_coordinator-0.5.321 → code_coordinator-0.5.323}/tests/test_next_release_tag.py +0 -0
  683. {code_coordinator-0.5.321 → code_coordinator-0.5.323}/tests/test_node_shim.py +0 -0
  684. {code_coordinator-0.5.321 → code_coordinator-0.5.323}/tests/test_notifier_baseline.py +0 -0
  685. {code_coordinator-0.5.321 → code_coordinator-0.5.323}/tests/test_notifier_cli.py +0 -0
  686. {code_coordinator-0.5.321 → code_coordinator-0.5.323}/tests/test_notifier_collect.py +0 -0
  687. {code_coordinator-0.5.321 → code_coordinator-0.5.323}/tests/test_notifier_config.py +0 -0
  688. {code_coordinator-0.5.321 → code_coordinator-0.5.323}/tests/test_notifier_drive_seam.py +0 -0
  689. {code_coordinator-0.5.321 → code_coordinator-0.5.323}/tests/test_notifier_isolation.py +0 -0
  690. {code_coordinator-0.5.321 → code_coordinator-0.5.323}/tests/test_notifier_predicate.py +0 -0
  691. {code_coordinator-0.5.321 → code_coordinator-0.5.323}/tests/test_notifier_quiet_hours.py +0 -0
  692. {code_coordinator-0.5.321 → code_coordinator-0.5.323}/tests/test_notifier_service.py +0 -0
  693. {code_coordinator-0.5.321 → code_coordinator-0.5.323}/tests/test_notify.py +0 -0
  694. {code_coordinator-0.5.321 → code_coordinator-0.5.323}/tests/test_notify_drain.py +0 -0
  695. {code_coordinator-0.5.321 → code_coordinator-0.5.323}/tests/test_openapi.py +0 -0
  696. {code_coordinator-0.5.321 → code_coordinator-0.5.323}/tests/test_operational_defaults.py +0 -0
  697. {code_coordinator-0.5.321 → code_coordinator-0.5.323}/tests/test_overlap_fence.py +0 -0
  698. {code_coordinator-0.5.321 → code_coordinator-0.5.323}/tests/test_overlap_predict.py +0 -0
  699. {code_coordinator-0.5.321 → code_coordinator-0.5.323}/tests/test_packaged_deploy_units.py +0 -0
  700. {code_coordinator-0.5.321 → code_coordinator-0.5.323}/tests/test_parentage.py +0 -0
  701. {code_coordinator-0.5.321 → code_coordinator-0.5.323}/tests/test_paste_landed.py +0 -0
  702. {code_coordinator-0.5.321 → code_coordinator-0.5.323}/tests/test_phantom_heal_venv_independence_2570.py +0 -0
  703. {code_coordinator-0.5.321 → code_coordinator-0.5.323}/tests/test_pipeline.py +0 -0
  704. {code_coordinator-0.5.321 → code_coordinator-0.5.323}/tests/test_plan_followup_approve_plan_command.py +0 -0
  705. {code_coordinator-0.5.321 → code_coordinator-0.5.323}/tests/test_plan_followup_pr_command.py +0 -0
  706. {code_coordinator-0.5.321 → code_coordinator-0.5.323}/tests/test_plan_followup_review_command.py +0 -0
  707. {code_coordinator-0.5.321 → code_coordinator-0.5.323}/tests/test_plan_only.py +0 -0
  708. {code_coordinator-0.5.321 → code_coordinator-0.5.323}/tests/test_plan_parser.py +0 -0
  709. {code_coordinator-0.5.321 → code_coordinator-0.5.323}/tests/test_platform_paths.py +0 -0
  710. {code_coordinator-0.5.321 → code_coordinator-0.5.323}/tests/test_pr_body_lint.py +0 -0
  711. {code_coordinator-0.5.321 → code_coordinator-0.5.323}/tests/test_prereqs.py +0 -0
  712. {code_coordinator-0.5.321 → code_coordinator-0.5.323}/tests/test_production_db_guard.py +0 -0
  713. {code_coordinator-0.5.321 → code_coordinator-0.5.323}/tests/test_progress.py +0 -0
  714. {code_coordinator-0.5.321 → code_coordinator-0.5.323}/tests/test_provider_seam.py +0 -0
  715. {code_coordinator-0.5.321 → code_coordinator-0.5.323}/tests/test_providers.py +0 -0
  716. {code_coordinator-0.5.321 → code_coordinator-0.5.323}/tests/test_providers_config_labels.py +0 -0
  717. {code_coordinator-0.5.321 → code_coordinator-0.5.323}/tests/test_providers_pty.py +0 -0
  718. {code_coordinator-0.5.321 → code_coordinator-0.5.323}/tests/test_py_rust_mirror_inventory.py +0 -0
  719. {code_coordinator-0.5.321 → code_coordinator-0.5.323}/tests/test_quiet_hours.py +0 -0
  720. {code_coordinator-0.5.321 → code_coordinator-0.5.323}/tests/test_quiet_hours_store_2146.py +0 -0
  721. {code_coordinator-0.5.321 → code_coordinator-0.5.323}/tests/test_reap_merged_sessions.py +0 -0
  722. {code_coordinator-0.5.321 → code_coordinator-0.5.323}/tests/test_reap_stale_interactive_tick.py +0 -0
  723. {code_coordinator-0.5.321 → code_coordinator-0.5.323}/tests/test_reconcile.py +0 -0
  724. {code_coordinator-0.5.321 → code_coordinator-0.5.323}/tests/test_reconcile_branch.py +0 -0
  725. {code_coordinator-0.5.321 → code_coordinator-0.5.323}/tests/test_reconcile_completions.py +0 -0
  726. {code_coordinator-0.5.321 → code_coordinator-0.5.323}/tests/test_reconcile_late_agent_reports_2547.py +0 -0
  727. {code_coordinator-0.5.321 → code_coordinator-0.5.323}/tests/test_reconcile_merges.py +0 -0
  728. {code_coordinator-0.5.321 → code_coordinator-0.5.323}/tests/test_reconcile_no_agent_record.py +0 -0
  729. {code_coordinator-0.5.321 → code_coordinator-0.5.323}/tests/test_reconcile_tick.py +0 -0
  730. {code_coordinator-0.5.321 → code_coordinator-0.5.323}/tests/test_reconcile_usage_limit_done.py +0 -0
  731. {code_coordinator-0.5.321 → code_coordinator-0.5.323}/tests/test_refine_chat.py +0 -0
  732. {code_coordinator-0.5.321 → code_coordinator-0.5.323}/tests/test_release_cordon_2101.py +0 -0
  733. {code_coordinator-0.5.321 → code_coordinator-0.5.323}/tests/test_release_cordon_daemon_leads_2176.py +0 -0
  734. {code_coordinator-0.5.321 → code_coordinator-0.5.323}/tests/test_release_cordon_deadlock_2240.py +0 -0
  735. {code_coordinator-0.5.321 → code_coordinator-0.5.323}/tests/test_release_cordon_stuck_2490.py +0 -0
  736. {code_coordinator-0.5.321 → code_coordinator-0.5.323}/tests/test_release_propagate.py +0 -0
  737. {code_coordinator-0.5.321 → code_coordinator-0.5.323}/tests/test_release_propagate_threshold.py +0 -0
  738. {code_coordinator-0.5.321 → code_coordinator-0.5.323}/tests/test_release_roll_between_legs_2854.py +0 -0
  739. {code_coordinator-0.5.321 → code_coordinator-0.5.323}/tests/test_release_roll_window_handoff.py +0 -0
  740. {code_coordinator-0.5.321 → code_coordinator-0.5.323}/tests/test_release_unified_1242.py +0 -0
  741. {code_coordinator-0.5.321 → code_coordinator-0.5.323}/tests/test_release_verify.py +0 -0
  742. {code_coordinator-0.5.321 → code_coordinator-0.5.323}/tests/test_release_window.py +0 -0
  743. {code_coordinator-0.5.321 → code_coordinator-0.5.323}/tests/test_remote_auto_prune.py +0 -0
  744. {code_coordinator-0.5.321 → code_coordinator-0.5.323}/tests/test_remote_interactive_reaper.py +0 -0
  745. {code_coordinator-0.5.321 → code_coordinator-0.5.323}/tests/test_repo_add.py +0 -0
  746. {code_coordinator-0.5.321 → code_coordinator-0.5.323}/tests/test_repo_dormancy.py +0 -0
  747. {code_coordinator-0.5.321 → code_coordinator-0.5.323}/tests/test_repo_edit_2220.py +0 -0
  748. {code_coordinator-0.5.321 → code_coordinator-0.5.323}/tests/test_repo_graph_fleet_2237.py +0 -0
  749. {code_coordinator-0.5.321 → code_coordinator-0.5.323}/tests/test_repo_onboard_2220.py +0 -0
  750. {code_coordinator-0.5.321 → code_coordinator-0.5.323}/tests/test_report_result_push.py +0 -0
  751. {code_coordinator-0.5.321 → code_coordinator-0.5.323}/tests/test_reports.py +0 -0
  752. {code_coordinator-0.5.321 → code_coordinator-0.5.323}/tests/test_retry.py +0 -0
  753. {code_coordinator-0.5.321 → code_coordinator-0.5.323}/tests/test_retry_advisory_1606.py +0 -0
  754. {code_coordinator-0.5.321 → code_coordinator-0.5.323}/tests/test_retry_type_1636.py +0 -0
  755. {code_coordinator-0.5.321 → code_coordinator-0.5.323}/tests/test_revalidate.py +0 -0
  756. {code_coordinator-0.5.321 → code_coordinator-0.5.323}/tests/test_review.py +0 -0
  757. {code_coordinator-0.5.321 → code_coordinator-0.5.323}/tests/test_review_end_review_without_verdict.py +0 -0
  758. {code_coordinator-0.5.321 → code_coordinator-0.5.323}/tests/test_review_parse_failure_diagnostic.py +0 -0
  759. {code_coordinator-0.5.321 → code_coordinator-0.5.323}/tests/test_review_reaffirm.py +0 -0
  760. {code_coordinator-0.5.321 → code_coordinator-0.5.323}/tests/test_review_state.py +0 -0
  761. {code_coordinator-0.5.321 → code_coordinator-0.5.323}/tests/test_review_verdict_backstop.py +0 -0
  762. {code_coordinator-0.5.321 → code_coordinator-0.5.323}/tests/test_review_verdict_override_audit.py +0 -0
  763. {code_coordinator-0.5.321 → code_coordinator-0.5.323}/tests/test_review_verdict_relay.py +0 -0
  764. {code_coordinator-0.5.321 → code_coordinator-0.5.323}/tests/test_review_zero_commits.py +0 -0
  765. {code_coordinator-0.5.321 → code_coordinator-0.5.323}/tests/test_scoped_review_wiring.py +0 -0
  766. {code_coordinator-0.5.321 → code_coordinator-0.5.323}/tests/test_scorecard.py +0 -0
  767. {code_coordinator-0.5.321 → code_coordinator-0.5.323}/tests/test_self_health.py +0 -0
  768. {code_coordinator-0.5.321 → code_coordinator-0.5.323}/tests/test_serve.py +0 -0
  769. {code_coordinator-0.5.321 → code_coordinator-0.5.323}/tests/test_serve_app_board_trim.py +0 -0
  770. {code_coordinator-0.5.321 → code_coordinator-0.5.323}/tests/test_serve_rest_routes.py +0 -0
  771. {code_coordinator-0.5.321 → code_coordinator-0.5.323}/tests/test_session.py +0 -0
  772. {code_coordinator-0.5.321 → code_coordinator-0.5.323}/tests/test_slice_issue_attribution.py +0 -0
  773. {code_coordinator-0.5.321 → code_coordinator-0.5.323}/tests/test_smoke.py +0 -0
  774. {code_coordinator-0.5.321 → code_coordinator-0.5.323}/tests/test_smoke_live_checkout_restore.py +0 -0
  775. {code_coordinator-0.5.321 → code_coordinator-0.5.323}/tests/test_smoke_workflow.py +0 -0
  776. {code_coordinator-0.5.321 → code_coordinator-0.5.323}/tests/test_spend_ceiling.py +0 -0
  777. {code_coordinator-0.5.321 → code_coordinator-0.5.323}/tests/test_spend_ceiling_coordinator.py +0 -0
  778. {code_coordinator-0.5.321 → code_coordinator-0.5.323}/tests/test_split.py +0 -0
  779. {code_coordinator-0.5.321 → code_coordinator-0.5.323}/tests/test_split_work.py +0 -0
  780. {code_coordinator-0.5.321 → code_coordinator-0.5.323}/tests/test_sql_dialect.py +0 -0
  781. {code_coordinator-0.5.321 → code_coordinator-0.5.323}/tests/test_sqlite_connect_ratchet.py +0 -0
  782. {code_coordinator-0.5.321 → code_coordinator-0.5.323}/tests/test_stage_projection.py +0 -0
  783. {code_coordinator-0.5.321 → code_coordinator-0.5.323}/tests/test_stale_busy_reviewer_697.py +0 -0
  784. {code_coordinator-0.5.321 → code_coordinator-0.5.323}/tests/test_stalled_pipeline.py +0 -0
  785. {code_coordinator-0.5.321 → code_coordinator-0.5.323}/tests/test_state.py +0 -0
  786. {code_coordinator-0.5.321 → code_coordinator-0.5.323}/tests/test_state_review_findings_daemon.py +0 -0
  787. {code_coordinator-0.5.321 → code_coordinator-0.5.323}/tests/test_status_fleet_footer.py +0 -0
  788. {code_coordinator-0.5.321 → code_coordinator-0.5.323}/tests/test_stop_1567.py +0 -0
  789. {code_coordinator-0.5.321 → code_coordinator-0.5.323}/tests/test_store_contract.py +0 -0
  790. {code_coordinator-0.5.321 → code_coordinator-0.5.323}/tests/test_store_migrate.py +0 -0
  791. {code_coordinator-0.5.321 → code_coordinator-0.5.323}/tests/test_stuck.py +0 -0
  792. {code_coordinator-0.5.321 → code_coordinator-0.5.323}/tests/test_stuck_test_state_watchdog_2803.py +0 -0
  793. {code_coordinator-0.5.321 → code_coordinator-0.5.323}/tests/test_terminal_command.py +0 -0
  794. {code_coordinator-0.5.321 → code_coordinator-0.5.323}/tests/test_test_author.py +0 -0
  795. {code_coordinator-0.5.321 → code_coordinator-0.5.323}/tests/test_test_chat.py +0 -0
  796. {code_coordinator-0.5.321 → code_coordinator-0.5.323}/tests/test_test_orchestrator.py +0 -0
  797. {code_coordinator-0.5.321 → code_coordinator-0.5.323}/tests/test_test_report.py +0 -0
  798. {code_coordinator-0.5.321 → code_coordinator-0.5.323}/tests/test_test_verdict_parsing.py +0 -0
  799. {code_coordinator-0.5.321 → code_coordinator-0.5.323}/tests/test_test_verdict_transcript_floor.py +0 -0
  800. {code_coordinator-0.5.321 → code_coordinator-0.5.323}/tests/test_text_io_encoding_audit.py +0 -0
  801. {code_coordinator-0.5.321 → code_coordinator-0.5.323}/tests/test_thin_client_board_audit.py +0 -0
  802. {code_coordinator-0.5.321 → code_coordinator-0.5.323}/tests/test_thin_client_config_load_1080.py +0 -0
  803. {code_coordinator-0.5.321 → code_coordinator-0.5.323}/tests/test_thin_client_daemon_routing_906.py +0 -0
  804. {code_coordinator-0.5.321 → code_coordinator-0.5.323}/tests/test_tmux_host.py +0 -0
  805. {code_coordinator-0.5.321 → code_coordinator-0.5.323}/tests/test_tmux_session.py +0 -0
  806. {code_coordinator-0.5.321 → code_coordinator-0.5.323}/tests/test_transcript_floor.py +0 -0
  807. {code_coordinator-0.5.321 → code_coordinator-0.5.323}/tests/test_usage.py +0 -0
  808. {code_coordinator-0.5.321 → code_coordinator-0.5.323}/tests/test_usage_limits.py +0 -0
  809. {code_coordinator-0.5.321 → code_coordinator-0.5.323}/tests/test_usage_rollup.py +0 -0
  810. {code_coordinator-0.5.321 → code_coordinator-0.5.323}/tests/test_venv_live_install_2121.py +0 -0
  811. {code_coordinator-0.5.321 → code_coordinator-0.5.323}/tests/test_version_single_source.py +0 -0
  812. {code_coordinator-0.5.321 → code_coordinator-0.5.323}/tests/test_watch.py +0 -0
  813. {code_coordinator-0.5.321 → code_coordinator-0.5.323}/tests/test_windows_job_is_a_real_gate_2000.py +0 -0
  814. {code_coordinator-0.5.321 → code_coordinator-0.5.323}/tests/test_worker_env_venv_isolation.py +0 -0
  815. {code_coordinator-0.5.321 → code_coordinator-0.5.323}/tests/test_worker_events.py +0 -0
  816. {code_coordinator-0.5.321 → code_coordinator-0.5.323}/tests/test_worker_image_pin_sync.py +0 -0
  817. {code_coordinator-0.5.321 → code_coordinator-0.5.323}/tests/test_worker_safety.py +0 -0
  818. {code_coordinator-0.5.321 → code_coordinator-0.5.323}/tests/test_worker_test_scoping.py +0 -0
  819. {code_coordinator-0.5.321 → code_coordinator-0.5.323}/tests/test_worktree.py +0 -0
  820. {code_coordinator-0.5.321 → code_coordinator-0.5.323}/tests/test_worktree_rmtree_chokepoint.py +0 -0
  821. {code_coordinator-0.5.321 → code_coordinator-0.5.323}/tests/test_write_parity.py +0 -0
  822. {code_coordinator-0.5.321 → code_coordinator-0.5.323}/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.321
3
+ Version: 0.5.323
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.321
3
+ Version: 0.5.323
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.321",
2
+ "tag": "0.5.323",
3
3
  "distance": 0,
4
- "node": "g0b3cfbaeacfdc63b22ee0b9e78fa04e6afa9ccad",
4
+ "node": "g6d62d0b99d361f200c0329792182a2f8918b2864",
5
5
  "dirty": false,
6
6
  "branch": "HEAD",
7
7
  "node_date": "2026-08-31"
@@ -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
 
@@ -612,6 +612,7 @@ def _run_decompose_chat_interactive(
612
612
  )
613
613
  from coord.decomposition_chat import ( # noqa: PLC0415
614
614
  build_decomposition_chat_briefing,
615
+ describe_unapproved_submission,
615
616
  fetch_running_context,
616
617
  render_running_context_section,
617
618
  repo_topology_context,
@@ -633,8 +634,7 @@ def _run_decompose_chat_interactive(
633
634
  submission = resolve_approved_submission(cfg, submission_id)
634
635
  if submission is None:
635
636
  click.secho(
636
- f"error: submission {submission_id!r} is not a currently-approved "
637
- "portal submission — nothing to decompose",
637
+ f"error: {describe_unapproved_submission(cfg, submission_id)}",
638
638
  fg="red",
639
639
  )
640
640
  raise SystemExit(1)
@@ -1343,11 +1343,48 @@ def portal_enqueue_status(submission_id: str, status: str) -> None:
1343
1343
  Unlike `push`, this allocates the revision for you and refuses a status
1344
1344
  that would summon the customer to an empty screen — `awaiting-signoff`
1345
1345
  with no design round queued, `needs-input` with no question (#835).
1346
+
1347
+ **#2996: warns, never refuses, before a `_PULLED_STATUSES` push that
1348
+ would silently withdraw SUBMISSION_ID from decomposition.**
1349
+ `coord.approved_work.approved_submissions` (the "Approved work items"
1350
+ panel's data source) drops any submission whose `last_status` moves to
1351
+ `planned` / `in-progress` / `quality-check` / `shipped` — those four
1352
+ values are only ever supposed to mean "already pulled into a linked
1353
+ milestone/issue and dispatch has begun". Pushing one of them here on a
1354
+ submission with no `coord portal link` on file does that removal anyway,
1355
+ with nothing to say so — the observed failure mode (#2996's own filing)
1356
+ was a status pushed purely to update the customer-facing wording, which
1357
+ happened to also empty the queue and only surfaced later as an unrelated
1358
+ "not a currently-approved portal submission" error. This command still
1359
+ sends the push regardless — there are legitimate reasons to set any of
1360
+ these by hand (a correction, a re-sync, an out-of-band delivery) — it
1361
+ only makes the consequence visible first.
1346
1362
  """
1347
1363
  _refuse_if_thin_client("enqueue-status")
1348
1364
 
1365
+ from coord.approved_work import is_pulled_status # noqa: PLC0415
1349
1366
  from coord.portal_sync import PortalSyncError, enqueue_status # noqa: PLC0415
1350
1367
 
1368
+ if is_pulled_status(status):
1369
+ from coord import portal_store # noqa: PLC0415
1370
+
1371
+ if portal_store.get_link_by_submission(submission_id) is None:
1372
+ click.secho(
1373
+ f"warning: {submission_id} has no linked milestone/issue on "
1374
+ "file (no `coord portal link` recorded) and no decomposition "
1375
+ f"on record — pushing status={status!r} will still be sent, "
1376
+ "but coord treats that status as \"already pulled into "
1377
+ f"decomposition and delivery\": {submission_id} will vanish "
1378
+ "from the TUI's Approved work items panel, and `coord portal "
1379
+ "decompose-chat` will refuse it as no longer approved. If "
1380
+ "the work has not actually been decomposed yet and you just "
1381
+ "want an honest \"we know what's next\" status for the "
1382
+ f"customer, use `coord portal enqueue-status {submission_id} "
1383
+ "in-design` instead — it stays on the queue and announces "
1384
+ "nobody.",
1385
+ fg="yellow",
1386
+ )
1387
+
1351
1388
  try:
1352
1389
  row = enqueue_status(submission_id, status)
1353
1390
  except PortalSyncError as exc:
@@ -1838,6 +1875,13 @@ def _render_ledger_text(payload: dict) -> str:
1838
1875
  lines.append(_render_answer_line(a, indent=" "))
1839
1876
  else:
1840
1877
  lines.append(" (unanswered — needs-input)")
1878
+ # #2987: `.get` — a thin client may be talking to a daemon that
1879
+ # predates this key.
1880
+ for c in entry.get("confirmations") or []:
1881
+ when = datetime.datetime.fromtimestamp(
1882
+ c["recorded_at"], tz=datetime.timezone.utc
1883
+ ).strftime("%Y-%m-%d %H:%M UTC")
1884
+ lines.append(f" [CONFIRMED by {c['actor'] or 'customer'}, {when}]")
1841
1885
  for a in unpaired:
1842
1886
  tag = " RELAYED" if a.get("relayed") else ""
1843
1887
  lines.append(
@@ -2076,6 +2120,14 @@ def portal_answer(
2076
2120
  refused — it routes through the daemon's ``/portal-answer`` seam when
2077
2121
  ``board_service`` is configured, so it works from wherever the operator
2078
2122
  happens to be.
2123
+
2124
+ Also queues the answer OUTBOUND to the portal (#2987, coord-portal#159,
2125
+ best-effort) — draft-gated like a question or design round under the
2126
+ default ``portal.approval`` policy, so it sits in ``coord portal
2127
+ drafts`` until approved. Once sent, the client sees exactly what was
2128
+ recorded and can confirm or correct it in one tap; a confirm marks this
2129
+ ledger row client-confirmed, a correction lands as a normal answer
2130
+ alongside it.
2079
2131
  """
2080
2132
  from coord import portal_store # noqa: PLC0415
2081
2133
  from coord.board_service import resolve # noqa: PLC0415
@@ -2173,7 +2173,12 @@ class PortalProjectRepo:
2173
2173
  #: imports ``coord.db``, and config must stay importable by everything.
2174
2174
  #: ``tests/test_portal_config.py`` pins the two lists together so the copy
2175
2175
  #: cannot silently drift.
2176
- PORTAL_OUTBOX_KINDS = ("status", "design_round", "question", "preview")
2176
+ PORTAL_OUTBOX_KINDS = (
2177
+ "status", "design_round", "question", "preview",
2178
+ # #2987: a relayed answer (#2986) pushed outbound for the client to
2179
+ # confirm/correct — see `coord.portal_sync.KIND_RELAYED_ANSWER`.
2180
+ "relayed_answer",
2181
+ )
2177
2182
 
2178
2183
  #: The draft gate's default policy (#2903, phase 1 of #2902): the two kinds
2179
2184
  #: that carry **agent-authored prose to a customer** are held for an
@@ -2184,11 +2189,16 @@ PORTAL_OUTBOX_KINDS = ("status", "design_round", "question", "preview")
2184
2189
  #: read and rewrite, and gating them would produce a rubber-stamp queue of
2185
2190
  #: "In progress" ×N that trains the operator to approve without reading,
2186
2191
  #: which is the failure mode this gate exists to prevent (see epic #2902).
2192
+ #: #2987: a relayed answer is prose an operator typed on the client's
2193
+ #: behalf — "the most worth reading before it sends" (the issue's own
2194
+ #: framing) — so it is gated like the other two prose kinds, not left
2195
+ #: ungated like `status`/`preview`.
2187
2196
  DEFAULT_PORTAL_APPROVAL: dict[str, bool] = {
2188
2197
  "status": False,
2189
2198
  "design_round": True,
2190
2199
  "question": True,
2191
2200
  "preview": False,
2201
+ "relayed_answer": True,
2192
2202
  }
2193
2203
 
2194
2204
 
@@ -591,7 +591,10 @@ def retry_on_locked(
591
591
  #
592
592
  # #2786: bumped 5 -> 6 for the `assignments.num_turns` column appended to
593
593
  # `_migrate_add_columns` below.
594
- _DB_SCHEMA_VERSION = 6
594
+ #
595
+ # #2987: bumped 6 -> 7 for the two `portal_sync_state.relayed_answer_
596
+ # watermark_*` columns appended to `_migrate_add_columns` below.
597
+ _DB_SCHEMA_VERSION = 7
595
598
 
596
599
 
597
600
  def _read_schema_version(conn: sqlite3.Connection) -> int:
@@ -1237,7 +1240,17 @@ _SCHEMA_SQL = """
1237
1240
  verdict_watermark_at REAL,
1238
1241
  verdict_watermark_rowid TEXT,
1239
1242
  question_watermark_at REAL,
1240
- question_watermark_rowid TEXT
1243
+ question_watermark_rowid TEXT,
1244
+ -- #2987: the relayed-answer CONFIRMATION consumer's own read
1245
+ -- position — same shape and same reason as
1246
+ -- `question_watermark_at`/`question_watermark_rowid` just above
1247
+ -- (a private watermark, independent of `handled_at`, so the
1248
+ -- never-marked backlog every OTHER event kind leaves behind
1249
+ -- cannot starve this consumer of a `relayed_answer.confirmed`
1250
+ -- event newer than it). See
1251
+ -- `coord.portal_sync._consume_relayed_answer_confirmations`.
1252
+ relayed_answer_watermark_at REAL,
1253
+ relayed_answer_watermark_rowid TEXT
1241
1254
  );
1242
1255
 
1243
1256
  -- #2749 (IL-3, epic #2746): the running-context ledger — the record
@@ -1755,6 +1768,18 @@ _MIGRATE_ADD_COLUMNS: list[str] = [
1755
1768
  # `question_answered` event a no-op rather than a duplicate ledger row.
1756
1769
  "ALTER TABLE portal_sync_state ADD COLUMN question_watermark_at REAL",
1757
1770
  "ALTER TABLE portal_sync_state ADD COLUMN question_watermark_rowid TEXT",
1771
+ # #2987: the relayed-answer confirmation consumer's own read position
1772
+ # into `portal_events` — same reason and same shape as
1773
+ # `question_watermark_at`/`question_watermark_rowid` above. NULL (read
1774
+ # as `(0.0, "")`, before every real event) for every database predating
1775
+ # this migration, which replays the full existing inbox exactly once on
1776
+ # upgrade — safe for the same reason replaying it is safe for the
1777
+ # question consumer: `append_ledger_entry`'s `(submission_id, kind,
1778
+ # source_event_id)` dedupe makes a re-observed event a no-op rather than
1779
+ # a duplicate ledger row. See
1780
+ # `coord.portal_sync._consume_relayed_answer_confirmations`.
1781
+ "ALTER TABLE portal_sync_state ADD COLUMN relayed_answer_watermark_at REAL",
1782
+ "ALTER TABLE portal_sync_state ADD COLUMN relayed_answer_watermark_rowid TEXT",
1758
1783
  # #2786: worker-reported turn count, parsed off the final stream-json
1759
1784
  # `result` event into `WorkerSummary.num_turns` (coord/worker_events.py)
1760
1785
  # alongside the four token columns above, but never persisted until now.
@@ -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:
@@ -95,6 +95,10 @@ COORD_OWNED_FIELDS = (
95
95
  "artifacts",
96
96
  "onhold_since",
97
97
  "preview_url",
98
+ # #2987: a relayed answer coord recorded on the client's behalf
99
+ # (`coord portal answer`, #2986), pushed OUT so the client can see and
100
+ # confirm/correct it — the wire shape coord-portal#159 specifies.
101
+ "relayed_answer",
98
102
  )
99
103
 
100
104
 
@@ -948,6 +948,9 @@ class DraftGateError(ValueError):
948
948
  EDITABLE_DRAFT_FIELDS: dict[str, tuple[str, ...]] = {
949
949
  "question": ("question",),
950
950
  "design_round": ("design_round.outcome_definition",),
951
+ # #2987: the operator's own relayed text — the exact prose the draft
952
+ # gate exists to let a human read before it reaches the client.
953
+ "relayed_answer": ("relayed_answer.text",),
951
954
  }
952
955
 
953
956
 
@@ -1450,6 +1453,63 @@ def events_after_question_watermark(
1450
1453
  return [(r["event_id"], _event_from_row(r)) for r in rows]
1451
1454
 
1452
1455
 
1456
+ def get_relayed_answer_watermark() -> tuple[float, str]:
1457
+ """The relayed-answer CONFIRMATION consumer's own read position (#2987)
1458
+ — ``(0.0, "")`` if never set. A private watermark, independent of
1459
+ ``verdict_watermark_*``/``question_watermark_*`` above, for the same
1460
+ reason those two are independent of each other: this consumer walks the
1461
+ same ``portal_events`` inbox at its own pace, and every event kind it
1462
+ ignores must not pile up ahead of the next ``relayed_answer.confirmed``
1463
+ event forever. See :func:`get_verdict_watermark`'s docstring for why the
1464
+ sentinel is ``(0.0, "")`` and not ``(0.0, 0)``.
1465
+ """
1466
+ row = sql.execute(
1467
+ _conn(),
1468
+ "SELECT relayed_answer_watermark_at, relayed_answer_watermark_rowid "
1469
+ "FROM portal_sync_state WHERE id = 1",
1470
+ ).fetchone()
1471
+ if row is None or row["relayed_answer_watermark_at"] is None:
1472
+ return (0.0, "")
1473
+ return (
1474
+ row["relayed_answer_watermark_at"],
1475
+ row["relayed_answer_watermark_rowid"] or "",
1476
+ )
1477
+
1478
+
1479
+ def set_relayed_answer_watermark(received_at: float, event_id: str) -> None:
1480
+ """Advance the relayed-answer confirmation consumer's read position past
1481
+ ``(received_at, event_id)`` — called after a scan has looked at that
1482
+ row, whatever kind it turned out to be, same reasoning as
1483
+ :func:`set_verdict_watermark`.
1484
+ """
1485
+ _update_sync_state(
1486
+ relayed_answer_watermark_at=received_at,
1487
+ relayed_answer_watermark_rowid=event_id,
1488
+ )
1489
+
1490
+
1491
+ def events_after_relayed_answer_watermark(
1492
+ received_at: float, after_event_id: str, *, limit: int = 100
1493
+ ) -> list[tuple[str, "PortalEvent"]]:
1494
+ """The relayed-answer confirmation consumer's own paginated scan —
1495
+ identical query to :func:`events_after_question_watermark`, against this
1496
+ consumer's own watermark instead. See
1497
+ :func:`coord.portal_sync._consume_relayed_answer_confirmations`.
1498
+ """
1499
+ rows = sql.execute(
1500
+ _conn(),
1501
+ """
1502
+ SELECT * FROM portal_events
1503
+ WHERE received_at > ?
1504
+ OR (received_at = ? AND event_id > ?)
1505
+ ORDER BY received_at ASC, event_id ASC
1506
+ LIMIT ?
1507
+ """,
1508
+ (received_at, received_at, after_event_id, limit),
1509
+ ).fetchall()
1510
+ return [(r["event_id"], _event_from_row(r)) for r in rows]
1511
+
1512
+
1453
1513
  def note_push(*, now: float | None = None) -> None:
1454
1514
  _update_sync_state(last_push_at=time.time() if now is None else now)
1455
1515
 
@@ -1754,6 +1814,18 @@ LEDGER_KIND_DRAFT_REJECTED = "draft_rejected"
1754
1814
  #: IS a narrative cannot be regenerated — that asymmetry is the design").
1755
1815
  LEDGER_KIND_OPERATOR_NOTE = "operator_note"
1756
1816
 
1817
+ #: #2987: the client tapped "confirm" on a relayed answer the portal showed
1818
+ #: them. A new row, not a mutation of the #2986 answer row it confirms — the
1819
+ #: ledger has no UPDATE path (see :func:`append_ledger_entry`'s docstring) —
1820
+ #: paired to the same ``question_revision`` so :func:`render_ledger_payload`
1821
+ #: can fold it into the same Q&A bucket. A CORRECTION needs no kind of its
1822
+ #: own: it arrives as an ordinary inbound ``question.answered`` event and
1823
+ #: lands as a normal (non-``relayed``) :data:`LEDGER_KIND_QUESTION_ANSWERED`
1824
+ #: row in the same bucket via the existing #2749 consumer — append-only, so
1825
+ #: both the relayed answer and the correction that supersedes it stay
1826
+ #: visible, in the order they were recorded.
1827
+ LEDGER_KIND_ANSWER_CONFIRMED = "answer_confirmed"
1828
+
1757
1829
  #: Marks a ledger ``actor`` as a human at coord's CLI rather than the portal
1758
1830
  #: wire, so a later session can tell operator-relayed context from something
1759
1831
  #: the client actually wrote. See :func:`operator_actor`.
@@ -2093,6 +2165,30 @@ def _fold_status_after_answer(config: Any, submission_id: str) -> None:
2093
2165
  )
2094
2166
 
2095
2167
 
2168
+ def _push_relayed_answer(config: Any, submission_id: str, entry: LedgerEntry) -> None:
2169
+ """Best-effort: queue *entry* — a #2986 relayed answer just ledgered —
2170
+ for the portal to see, so the client can confirm or correct it (#2987).
2171
+
2172
+ Never raises. The ledger write above is the durable, coord-side record
2173
+ of the fact; this is the OUTBOUND half of it, and a failure here (a
2174
+ stale/missing config, the draft-gate policy read finding nothing to
2175
+ read) must never make the ledger append look like it failed — same
2176
+ posture as :func:`_fold_status_after_answer` right above, and the same
2177
+ #2179 failure posture the rest of this bridge holds to: the answer
2178
+ stays recorded locally either way.
2179
+ """
2180
+ try:
2181
+ from coord import portal_sync # noqa: PLC0415
2182
+
2183
+ portal_sync.enqueue_relayed_answer(submission_id, entry, config=config)
2184
+ except Exception: # noqa: BLE001 — outbound queuing is best-effort here
2185
+ _log.warning(
2186
+ "portal answer: could not enqueue outbound relayed_answer for %s",
2187
+ submission_id,
2188
+ exc_info=True,
2189
+ )
2190
+
2191
+
2096
2192
  def _answer_question_local(
2097
2193
  submission_id: str,
2098
2194
  text: str,
@@ -2149,6 +2245,7 @@ def _answer_question_local(
2149
2245
  now=now,
2150
2246
  )
2151
2247
  _fold_status_after_answer(config, submission_id)
2248
+ _push_relayed_answer(config, submission_id, entry)
2152
2249
  return entry
2153
2250
 
2154
2251
 
@@ -2189,6 +2286,12 @@ def answer_question(
2189
2286
  (:func:`coord.portal_sync._record_question_answer`) is additive, not a
2190
2287
  conflict: the ledger is append-only, so both rows coexist under the same
2191
2288
  ``question_revision`` in the order they were recorded.
2289
+
2290
+ Also queues the answer OUTBOUND (#2987, best-effort — see
2291
+ :func:`_push_relayed_answer`), draft-gated like ``design_round``/
2292
+ ``question`` so nothing customer-facing sends without operator approval,
2293
+ so the client sees exactly what was recorded and can confirm or correct
2294
+ it in one tap.
2192
2295
  """
2193
2296
  routed = _route_answer(
2194
2297
  {
@@ -2668,6 +2771,14 @@ def render_ledger_payload(submission_id: str) -> dict[str, Any]:
2668
2771
  ``operator_notes`` key, in ledger ``seq`` order — deliberately NOT mixed
2669
2772
  into ``qa`` (they answer no question) and NOT folded into ``narrative``
2670
2773
  (they are ledger-class facts, and the narrative is regenerable).
2774
+
2775
+ A relayed answer's client CONFIRMATION (#2987,
2776
+ :data:`LEDGER_KIND_ANSWER_CONFIRMED`) folds into the same bucket as
2777
+ ``confirmations`` — never merged into ``answers`` itself, so a renderer
2778
+ can tell "the client said this" from "the client confirmed what we said
2779
+ they said" without inspecting payloads. A correction needs no such
2780
+ folding: it arrives as an ordinary (non-``relayed``) row in ``answers``
2781
+ and both stay visible in ``seq`` order, same as any other append.
2671
2782
  """
2672
2783
  ledger = ledger_for_submission(submission_id)
2673
2784
  decisions = decisions_for_submission(submission_id)
@@ -2681,7 +2792,7 @@ def render_ledger_payload(submission_id: str) -> dict[str, Any]:
2681
2792
  operator_notes.append(entry)
2682
2793
  elif entry.kind == LEDGER_KIND_QUESTION_PUSHED:
2683
2794
  questions.setdefault(
2684
- entry.question_revision, {"question": entry, "answers": []}
2795
+ entry.question_revision, {"question": entry, "answers": [], "confirmations": []}
2685
2796
  )
2686
2797
  elif entry.kind == LEDGER_KIND_QUESTION_ANSWERED:
2687
2798
  bucket = questions.get(entry.question_revision)
@@ -2689,6 +2800,10 @@ def render_ledger_payload(submission_id: str) -> dict[str, Any]:
2689
2800
  bucket["answers"].append(entry)
2690
2801
  else:
2691
2802
  unpaired_answers.append(entry)
2803
+ elif entry.kind == LEDGER_KIND_ANSWER_CONFIRMED:
2804
+ bucket = questions.get(entry.question_revision)
2805
+ if bucket is not None:
2806
+ bucket["confirmations"].append(entry)
2692
2807
 
2693
2808
  current_decisions = [d for d in decisions if d.is_current]
2694
2809
  archived_decisions = [d for d in decisions if not d.is_current]
@@ -2714,6 +2829,12 @@ def render_ledger_payload(submission_id: str) -> dict[str, Any]:
2714
2829
  }
2715
2830
  for a in qa["answers"]
2716
2831
  ],
2832
+ # #2987: every time the client confirmed a relayed answer for
2833
+ # this question — empty when none has been (yet, or ever).
2834
+ "confirmations": [
2835
+ {"actor": c.actor, "recorded_at": c.recorded_at}
2836
+ for c in qa["confirmations"]
2837
+ ],
2717
2838
  }
2718
2839
  for revision, qa in questions.items()
2719
2840
  ],