@team-agent/installer 0.2.10 → 0.3.0

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 (326) hide show
  1. package/Cargo.lock +744 -0
  2. package/Cargo.toml +34 -0
  3. package/crates/team-agent/Cargo.toml +33 -0
  4. package/crates/team-agent/src/cli/adapters.rs +1343 -0
  5. package/crates/team-agent/src/cli/diagnose.rs +554 -0
  6. package/crates/team-agent/src/cli/emit.rs +1077 -0
  7. package/crates/team-agent/src/cli/helpers.rs +88 -0
  8. package/crates/team-agent/src/cli/leader.rs +216 -0
  9. package/crates/team-agent/src/cli/mod.rs +1141 -0
  10. package/crates/team-agent/src/cli/profile.rs +306 -0
  11. package/crates/team-agent/src/cli/send.rs +215 -0
  12. package/crates/team-agent/src/cli/status.rs +179 -0
  13. package/crates/team-agent/src/cli/status_port.rs +502 -0
  14. package/crates/team-agent/src/cli/tests/base.rs +616 -0
  15. package/crates/team-agent/src/cli/tests/compile.rs +96 -0
  16. package/crates/team-agent/src/cli/tests/divergence.rs +509 -0
  17. package/crates/team-agent/src/cli/tests/lane_c.rs +333 -0
  18. package/crates/team-agent/src/cli/tests/leader_watch.rs +395 -0
  19. package/crates/team-agent/src/cli/tests/main_preserved.rs +675 -0
  20. package/crates/team-agent/src/cli/tests/missing_subcommands.rs +390 -0
  21. package/crates/team-agent/src/cli/tests/mod.rs +97 -0
  22. package/crates/team-agent/src/cli/tests/peer_allow.rs +137 -0
  23. package/crates/team-agent/src/cli/tests/repair_state_byte_lock.rs +302 -0
  24. package/crates/team-agent/src/cli/tests/run_delegation.rs +305 -0
  25. package/crates/team-agent/src/cli/tests/status_send.rs +385 -0
  26. package/crates/team-agent/src/cli/tests/verb_profile.rs +182 -0
  27. package/crates/team-agent/src/cli/tests/verb_settle.rs +236 -0
  28. package/crates/team-agent/src/cli/tests/verb_validate.rs +184 -0
  29. package/crates/team-agent/src/cli/types.rs +605 -0
  30. package/crates/team-agent/src/compiler/tests.rs +701 -0
  31. package/crates/team-agent/src/compiler.rs +489 -0
  32. package/crates/team-agent/src/coordinator/backoff.rs +153 -0
  33. package/crates/team-agent/src/coordinator/health.rs +436 -0
  34. package/crates/team-agent/src/coordinator/mod.rs +80 -0
  35. package/crates/team-agent/src/coordinator/orphan.rs +179 -0
  36. package/crates/team-agent/src/coordinator/tests/abnormal.rs +255 -0
  37. package/crates/team-agent/src/coordinator/tests/basics.rs +262 -0
  38. package/crates/team-agent/src/coordinator/tests/daemon.rs +323 -0
  39. package/crates/team-agent/src/coordinator/tests/health_sync.rs +263 -0
  40. package/crates/team-agent/src/coordinator/tests/main_preserved.rs +136 -0
  41. package/crates/team-agent/src/coordinator/tests/mod.rs +310 -0
  42. package/crates/team-agent/src/coordinator/tests/spine.rs +261 -0
  43. package/crates/team-agent/src/coordinator/tests/takeover.rs +227 -0
  44. package/crates/team-agent/src/coordinator/tests/tick_core.rs +256 -0
  45. package/crates/team-agent/src/coordinator/tests/watch.rs +167 -0
  46. package/crates/team-agent/src/coordinator/tick.rs +2032 -0
  47. package/crates/team-agent/src/coordinator/types.rs +584 -0
  48. package/crates/team-agent/src/db/migration.rs +716 -0
  49. package/crates/team-agent/src/db/mod.rs +23 -0
  50. package/crates/team-agent/src/db/schema.rs +378 -0
  51. package/crates/team-agent/src/event_log.rs +375 -0
  52. package/crates/team-agent/src/fake_worker.rs +253 -0
  53. package/crates/team-agent/src/leader/helpers.rs +190 -0
  54. package/crates/team-agent/src/leader/inject.rs +33 -0
  55. package/crates/team-agent/src/leader/lease.rs +1063 -0
  56. package/crates/team-agent/src/leader/mod.rs +99 -0
  57. package/crates/team-agent/src/leader/owner_bind.rs +292 -0
  58. package/crates/team-agent/src/leader/rediscover/tests.rs +525 -0
  59. package/crates/team-agent/src/leader/rediscover.rs +1099 -0
  60. package/crates/team-agent/src/leader/start.rs +273 -0
  61. package/crates/team-agent/src/leader/takeover.rs +235 -0
  62. package/crates/team-agent/src/leader/tests/basics.rs +183 -0
  63. package/crates/team-agent/src/leader/tests/byte_findings.rs +234 -0
  64. package/crates/team-agent/src/leader/tests/identity.rs +206 -0
  65. package/crates/team-agent/src/leader/tests/idle.rs +271 -0
  66. package/crates/team-agent/src/leader/tests/lease_api.rs +225 -0
  67. package/crates/team-agent/src/leader/tests/lease_claim.rs +253 -0
  68. package/crates/team-agent/src/leader/tests/mod.rs +125 -0
  69. package/crates/team-agent/src/leader/tests/rediscover.rs +351 -0
  70. package/crates/team-agent/src/leader/tests/wake_start_owner.rs +204 -0
  71. package/crates/team-agent/src/leader/types.rs +487 -0
  72. package/crates/team-agent/src/lib.rs +85 -0
  73. package/crates/team-agent/src/lifecycle/display.rs +228 -0
  74. package/crates/team-agent/src/lifecycle/helpers.rs +112 -0
  75. package/crates/team-agent/src/lifecycle/launch/plan.rs +227 -0
  76. package/crates/team-agent/src/lifecycle/launch.rs +1833 -0
  77. package/crates/team-agent/src/lifecycle/mod.rs +62 -0
  78. package/crates/team-agent/src/lifecycle/restart/agent.rs +533 -0
  79. package/crates/team-agent/src/lifecycle/restart/common.rs +517 -0
  80. package/crates/team-agent/src/lifecycle/restart/orchestrator.rs +41 -0
  81. package/crates/team-agent/src/lifecycle/restart/rebuild.rs +268 -0
  82. package/crates/team-agent/src/lifecycle/restart/remove.rs +780 -0
  83. package/crates/team-agent/src/lifecycle/restart/selection.rs +208 -0
  84. package/crates/team-agent/src/lifecycle/restart/team_state.rs +242 -0
  85. package/crates/team-agent/src/lifecycle/restart.rs +76 -0
  86. package/crates/team-agent/src/lifecycle/tests/agent_ops.rs +455 -0
  87. package/crates/team-agent/src/lifecycle/tests/core.rs +989 -0
  88. package/crates/team-agent/src/lifecycle/tests/lane_ops.rs +583 -0
  89. package/crates/team-agent/src/lifecycle/tests/launch_spawn.rs +933 -0
  90. package/crates/team-agent/src/lifecycle/tests/main_preserved.rs +265 -0
  91. package/crates/team-agent/src/lifecycle/tests.rs +27 -0
  92. package/crates/team-agent/src/lifecycle/types.rs +685 -0
  93. package/crates/team-agent/src/main.rs +41 -0
  94. package/crates/team-agent/src/mcp_server/helpers.rs +228 -0
  95. package/crates/team-agent/src/mcp_server/mod.rs +183 -0
  96. package/crates/team-agent/src/mcp_server/normalize.rs +312 -0
  97. package/crates/team-agent/src/mcp_server/tests/golden.rs +283 -0
  98. package/crates/team-agent/src/mcp_server/tests/normalize.rs +244 -0
  99. package/crates/team-agent/src/mcp_server/tests/scoped.rs +189 -0
  100. package/crates/team-agent/src/mcp_server/tests/send.rs +222 -0
  101. package/crates/team-agent/src/mcp_server/tests/tools.rs +158 -0
  102. package/crates/team-agent/src/mcp_server/tests/wire.rs +159 -0
  103. package/crates/team-agent/src/mcp_server/tests.rs +38 -0
  104. package/crates/team-agent/src/mcp_server/tools.rs +603 -0
  105. package/crates/team-agent/src/mcp_server/types.rs +421 -0
  106. package/crates/team-agent/src/mcp_server/wire.rs +388 -0
  107. package/crates/team-agent/src/message_store.rs +767 -0
  108. package/crates/team-agent/src/messaging/activity.rs +433 -0
  109. package/crates/team-agent/src/messaging/delivery.rs +542 -0
  110. package/crates/team-agent/src/messaging/helpers.rs +209 -0
  111. package/crates/team-agent/src/messaging/leader_receiver.rs +340 -0
  112. package/crates/team-agent/src/messaging/mod.rs +147 -0
  113. package/crates/team-agent/src/messaging/peers.rs +32 -0
  114. package/crates/team-agent/src/messaging/results.rs +537 -0
  115. package/crates/team-agent/src/messaging/scheduler.rs +344 -0
  116. package/crates/team-agent/src/messaging/selftest.rs +100 -0
  117. package/crates/team-agent/src/messaging/send.rs +582 -0
  118. package/crates/team-agent/src/messaging/tests/basic.rs +357 -0
  119. package/crates/team-agent/src/messaging/tests/main_preserved.rs +122 -0
  120. package/crates/team-agent/src/messaging/tests/mod.rs +293 -0
  121. package/crates/team-agent/src/messaging/tests/runtime.rs +1422 -0
  122. package/crates/team-agent/src/messaging/tests/spine.rs +437 -0
  123. package/crates/team-agent/src/messaging/trust.rs +192 -0
  124. package/crates/team-agent/src/messaging/types.rs +355 -0
  125. package/crates/team-agent/src/messaging/watchers.rs +591 -0
  126. package/crates/team-agent/src/model/enums.rs +311 -0
  127. package/crates/team-agent/src/model/errors.rs +17 -0
  128. package/crates/team-agent/src/model/ids.rs +155 -0
  129. package/crates/team-agent/src/model/mod.rs +22 -0
  130. package/crates/team-agent/src/model/paths.rs +228 -0
  131. package/crates/team-agent/src/model/permissions.rs +567 -0
  132. package/crates/team-agent/src/model/routing.rs +340 -0
  133. package/crates/team-agent/src/model/spec.rs +680 -0
  134. package/crates/team-agent/src/model/task_graph.rs +380 -0
  135. package/crates/team-agent/src/model/testdata/fuzz.golden.yaml +43 -0
  136. package/crates/team-agent/src/model/testdata/fuzz.yaml +43 -0
  137. package/crates/team-agent/src/model/testdata/spec_invalid_a.yaml +207 -0
  138. package/crates/team-agent/src/model/testdata/team.spec.golden.yaml +206 -0
  139. package/crates/team-agent/src/model/testdata/team.spec.yaml +206 -0
  140. package/crates/team-agent/src/model/yaml/tests.rs +288 -0
  141. package/crates/team-agent/src/model/yaml.rs +800 -0
  142. package/crates/team-agent/src/packaging/install.rs +305 -0
  143. package/crates/team-agent/src/packaging/migrate.rs +30 -0
  144. package/crates/team-agent/src/packaging/mod.rs +82 -0
  145. package/crates/team-agent/src/packaging/repair.rs +24 -0
  146. package/crates/team-agent/src/packaging/tests.rs +829 -0
  147. package/crates/team-agent/src/packaging/types.rs +369 -0
  148. package/crates/team-agent/src/provider/adapter.rs +801 -0
  149. package/crates/team-agent/src/provider/approvals/mod.rs +2 -0
  150. package/crates/team-agent/src/provider/approvals/parsing.rs +452 -0
  151. package/crates/team-agent/src/provider/approvals/runtime_prompts.rs +163 -0
  152. package/crates/team-agent/src/provider/classify.rs +456 -0
  153. package/crates/team-agent/src/provider/faults.rs +136 -0
  154. package/crates/team-agent/src/provider/helpers.rs +41 -0
  155. package/crates/team-agent/src/provider/mod.rs +53 -0
  156. package/crates/team-agent/src/provider/startup_prompt.rs +423 -0
  157. package/crates/team-agent/src/provider/tests/adapter.rs +239 -0
  158. package/crates/team-agent/src/provider/tests/classify.rs +240 -0
  159. package/crates/team-agent/src/provider/tests/faults.rs +120 -0
  160. package/crates/team-agent/src/provider/tests/idle.rs +208 -0
  161. package/crates/team-agent/src/provider/tests/wire.rs +213 -0
  162. package/crates/team-agent/src/provider/tests.rs +31 -0
  163. package/crates/team-agent/src/provider/types.rs +424 -0
  164. package/crates/team-agent/src/state/identity.rs +656 -0
  165. package/crates/team-agent/src/state/mod.rs +58 -0
  166. package/crates/team-agent/src/state/owner_gate.rs +423 -0
  167. package/crates/team-agent/src/state/persist.rs +712 -0
  168. package/crates/team-agent/src/state/projection.rs +657 -0
  169. package/crates/team-agent/src/state/selector.rs +105 -0
  170. package/crates/team-agent/src/state/testdata/state-rich.canonical.json +133 -0
  171. package/crates/team-agent/src/tmux_backend/tests.rs +586 -0
  172. package/crates/team-agent/src/tmux_backend.rs +758 -0
  173. package/crates/team-agent/src/transport/test_support.rs +252 -0
  174. package/crates/team-agent/src/transport/tests/behavior.rs +327 -0
  175. package/crates/team-agent/src/transport/tests/mod.rs +199 -0
  176. package/crates/team-agent/src/transport/tests/wire.rs +527 -0
  177. package/crates/team-agent/src/transport.rs +774 -0
  178. package/npm/install.mjs +90 -106
  179. package/package.json +15 -13
  180. package/crates/team-agent-core/Cargo.toml +0 -12
  181. package/crates/team-agent-core/src/lib.rs +0 -332
  182. package/crates/team-agent-core/src/main.rs +0 -152
  183. package/pyproject.toml +0 -18
  184. package/scripts/install.py +0 -88
  185. package/scripts/run_regression_tests.py +0 -83
  186. package/src/team_agent/__init__.py +0 -3
  187. package/src/team_agent/__main__.py +0 -5
  188. package/src/team_agent/_legacy_pane_discovery.py +0 -186
  189. package/src/team_agent/abnormal_track.py +0 -253
  190. package/src/team_agent/approvals/__init__.py +0 -65
  191. package/src/team_agent/approvals/constants.py +0 -6
  192. package/src/team_agent/approvals/parsing.py +0 -176
  193. package/src/team_agent/approvals/runtime_prompts.py +0 -171
  194. package/src/team_agent/approvals/status.py +0 -176
  195. package/src/team_agent/cli/__init__.py +0 -137
  196. package/src/team_agent/cli/commands.py +0 -481
  197. package/src/team_agent/cli/e2e.py +0 -202
  198. package/src/team_agent/cli/helpers.py +0 -226
  199. package/src/team_agent/cli/parser.py +0 -540
  200. package/src/team_agent/compiler.py +0 -334
  201. package/src/team_agent/coordinator/__init__.py +0 -53
  202. package/src/team_agent/coordinator/__main__.py +0 -83
  203. package/src/team_agent/coordinator/lifecycle.py +0 -363
  204. package/src/team_agent/coordinator/metadata.py +0 -61
  205. package/src/team_agent/coordinator/paths.py +0 -17
  206. package/src/team_agent/diagnose/__init__.py +0 -48
  207. package/src/team_agent/diagnose/checks.py +0 -101
  208. package/src/team_agent/diagnose/comms.py +0 -213
  209. package/src/team_agent/diagnose/health.py +0 -241
  210. package/src/team_agent/diagnose/orphan_cleanup.py +0 -364
  211. package/src/team_agent/diagnose/preflight.py +0 -194
  212. package/src/team_agent/diagnose/quick_start.py +0 -324
  213. package/src/team_agent/display/__init__.py +0 -92
  214. package/src/team_agent/display/adaptive.py +0 -511
  215. package/src/team_agent/display/backend.py +0 -46
  216. package/src/team_agent/display/close.py +0 -154
  217. package/src/team_agent/display/ghostty.py +0 -77
  218. package/src/team_agent/display/rebuild.py +0 -102
  219. package/src/team_agent/display/tiling.py +0 -156
  220. package/src/team_agent/display/worker_window.py +0 -114
  221. package/src/team_agent/display/workspace.py +0 -382
  222. package/src/team_agent/errors.py +0 -10
  223. package/src/team_agent/events.py +0 -84
  224. package/src/team_agent/fake_worker.py +0 -80
  225. package/src/team_agent/idle_predicate.py +0 -200
  226. package/src/team_agent/idle_takeover.py +0 -59
  227. package/src/team_agent/idle_takeover_wiring.py +0 -111
  228. package/src/team_agent/launch/__init__.py +0 -41
  229. package/src/team_agent/launch/bootstrap.py +0 -85
  230. package/src/team_agent/launch/config.py +0 -106
  231. package/src/team_agent/launch/core.py +0 -301
  232. package/src/team_agent/launch/requirements.py +0 -57
  233. package/src/team_agent/leader/__init__.py +0 -926
  234. package/src/team_agent/leader_binding.py +0 -183
  235. package/src/team_agent/lifecycle/__init__.py +0 -5
  236. package/src/team_agent/lifecycle/agents.py +0 -278
  237. package/src/team_agent/lifecycle/operations.py +0 -411
  238. package/src/team_agent/lifecycle/paste_buffer_hygiene.py +0 -39
  239. package/src/team_agent/lifecycle/start.py +0 -363
  240. package/src/team_agent/mcp_server/__init__.py +0 -42
  241. package/src/team_agent/mcp_server/__main__.py +0 -7
  242. package/src/team_agent/mcp_server/contracts.py +0 -148
  243. package/src/team_agent/mcp_server/normalize.py +0 -257
  244. package/src/team_agent/mcp_server/server.py +0 -150
  245. package/src/team_agent/mcp_server/tools.py +0 -352
  246. package/src/team_agent/message_store/__init__.py +0 -23
  247. package/src/team_agent/message_store/agent_health.py +0 -113
  248. package/src/team_agent/message_store/core.py +0 -497
  249. package/src/team_agent/message_store/leader_notification_log.py +0 -198
  250. package/src/team_agent/message_store/result_watchers.py +0 -251
  251. package/src/team_agent/message_store/schema.py +0 -308
  252. package/src/team_agent/message_store/schema_migration.py +0 -448
  253. package/src/team_agent/messaging/__init__.py +0 -1
  254. package/src/team_agent/messaging/activity_detector.py +0 -254
  255. package/src/team_agent/messaging/delivery.py +0 -473
  256. package/src/team_agent/messaging/deps.py +0 -247
  257. package/src/team_agent/messaging/idle_alerts.py +0 -423
  258. package/src/team_agent/messaging/internal_delivery.py +0 -46
  259. package/src/team_agent/messaging/leader.py +0 -497
  260. package/src/team_agent/messaging/leader_api_errors.py +0 -216
  261. package/src/team_agent/messaging/leader_panes.py +0 -673
  262. package/src/team_agent/messaging/owner_bypass.py +0 -29
  263. package/src/team_agent/messaging/result_delivery.py +0 -539
  264. package/src/team_agent/messaging/results.py +0 -447
  265. package/src/team_agent/messaging/scheduler.py +0 -450
  266. package/src/team_agent/messaging/send.py +0 -532
  267. package/src/team_agent/messaging/session_drift.py +0 -94
  268. package/src/team_agent/messaging/tmux_io.py +0 -506
  269. package/src/team_agent/messaging/tmux_prompt.py +0 -338
  270. package/src/team_agent/messaging/trust_auto_answer.py +0 -52
  271. package/src/team_agent/orchestrator/__init__.py +0 -376
  272. package/src/team_agent/orchestrator/plan.py +0 -122
  273. package/src/team_agent/orchestrator/state.py +0 -128
  274. package/src/team_agent/paths.py +0 -45
  275. package/src/team_agent/permissions.py +0 -123
  276. package/src/team_agent/profiles/__init__.py +0 -82
  277. package/src/team_agent/profiles/constants.py +0 -19
  278. package/src/team_agent/profiles/core.py +0 -407
  279. package/src/team_agent/profiles/helpers.py +0 -69
  280. package/src/team_agent/profiles/provider_env.py +0 -188
  281. package/src/team_agent/profiles/smoke.py +0 -201
  282. package/src/team_agent/provider_cli/__init__.py +0 -43
  283. package/src/team_agent/provider_cli/adapter.py +0 -172
  284. package/src/team_agent/provider_cli/base.py +0 -48
  285. package/src/team_agent/provider_cli/claude.py +0 -457
  286. package/src/team_agent/provider_cli/codex.py +0 -336
  287. package/src/team_agent/provider_cli/copilot.py +0 -8
  288. package/src/team_agent/provider_cli/fake.py +0 -39
  289. package/src/team_agent/provider_cli/gemini.py +0 -95
  290. package/src/team_agent/provider_cli/opencode.py +0 -8
  291. package/src/team_agent/provider_cli/prompt.py +0 -62
  292. package/src/team_agent/provider_cli/registry.py +0 -18
  293. package/src/team_agent/provider_cli/unsupported.py +0 -32
  294. package/src/team_agent/provider_state/README.md +0 -78
  295. package/src/team_agent/provider_state/__init__.py +0 -86
  296. package/src/team_agent/provider_state/claude.py +0 -86
  297. package/src/team_agent/provider_state/codex.py +0 -84
  298. package/src/team_agent/provider_state/common.py +0 -207
  299. package/src/team_agent/provider_state/registry.py +0 -118
  300. package/src/team_agent/providers.py +0 -163
  301. package/src/team_agent/quality_gates.py +0 -104
  302. package/src/team_agent/restart/__init__.py +0 -34
  303. package/src/team_agent/restart/orchestration.py +0 -554
  304. package/src/team_agent/restart/selection.py +0 -89
  305. package/src/team_agent/restart/snapshot.py +0 -70
  306. package/src/team_agent/routing.py +0 -84
  307. package/src/team_agent/runtime.py +0 -1239
  308. package/src/team_agent/rust_core.py +0 -327
  309. package/src/team_agent/sessions/__init__.py +0 -25
  310. package/src/team_agent/sessions/capture.py +0 -143
  311. package/src/team_agent/sessions/inventory.py +0 -44
  312. package/src/team_agent/sessions/resume.py +0 -135
  313. package/src/team_agent/simple_yaml.py +0 -236
  314. package/src/team_agent/spec.py +0 -370
  315. package/src/team_agent/state.py +0 -602
  316. package/src/team_agent/status/__init__.py +0 -63
  317. package/src/team_agent/status/approvals.py +0 -52
  318. package/src/team_agent/status/compact.py +0 -158
  319. package/src/team_agent/status/constants.py +0 -18
  320. package/src/team_agent/status/inbox.py +0 -58
  321. package/src/team_agent/status/peek.py +0 -117
  322. package/src/team_agent/status/queries.py +0 -199
  323. package/src/team_agent/task_graph.py +0 -80
  324. package/src/team_agent/terminal.py +0 -57
  325. package/src/team_agent/wake.py +0 -58
  326. package/src/team_agent/watch/__init__.py +0 -145
@@ -0,0 +1,584 @@
1
+ //! coordinator 共享数据面:常量 / newtype / 穷尽 enum / metadata / schema health /
2
+ //! report 结构 / CoordinatorEvent / abnormal-track 数据型 / WatchCursor / cross-dep 占位。
3
+
4
+ use std::collections::BTreeSet;
5
+ use std::path::{Path, PathBuf};
6
+
7
+ use serde::{Deserialize, Serialize};
8
+ use serde_json::Value;
9
+ use thiserror::Error;
10
+
11
+ // ── REUSE — committed model types(不重定义)──────────────────────────────────
12
+ use crate::model::enums::{AuthMode, Provider};
13
+ // AuthMode/PaneLiveness 经 provider/transport 间接复用;此处只点名直接用到的。
14
+
15
+ // ── REUSE — step 8 provider(经 trait,MUST-NOT-13:绝不依赖 provider client crate)──
16
+ use crate::provider::{ProcessLiveness, ProviderAdapter, RolloutPath, TurnId, TurnState};
17
+
18
+ // ===========================================================================
19
+ // CONSTANTS(metadata.py:13 / __main__.py:101)
20
+ // ===========================================================================
21
+
22
+ /// `COORDINATOR_PROTOCOL_VERSION = 2`(`metadata.py:13`)。bump 即触发
23
+ /// `coordinator.restart_incompatible`。健康判定的三元之一。
24
+ pub const PROTOCOL_VERSION: u32 = 2;
25
+
26
+ /// `DEFAULT_TICK_INTERVAL_SEC = 5.0`(`__main__.py:101`;Gap 36c 从 2.0 提到 5.0,2.5x 省 CPU)。
27
+ pub const DEFAULT_TICK_INTERVAL_SEC: f64 = 5.0;
28
+
29
+ /// 指数退避封顶(`__main__.py:65` `min(.., 60.0)`)。bug-084 崩溃循环防护。
30
+ pub const BACKOFF_MAX_SEC: f64 = 60.0;
31
+
32
+ /// watch log rotation marker(`watch.py:22`,字节级一致 —— 测试钉死)。
33
+ pub const ROTATION_MARKER: &str =
34
+ "[watch] log rotated; archived segment events.jsonl.1 not replayed — historical replay deferred to a future --replay flag";
35
+
36
+ // ===========================================================================
37
+ // NEWTYPES(§3:Pid / WorkspacePath 不与裸 int/PathBuf 混传)
38
+ // ===========================================================================
39
+
40
+ /// OS pid(`metadata.py` / `pid_is_running` / stop)。避免与其他 int id 混传。
41
+ #[derive(Debug, Clone, Copy, PartialEq, Eq, Hash, PartialOrd, Ord, Serialize, Deserialize)]
42
+ #[serde(transparent)]
43
+ pub struct Pid(pub u32);
44
+
45
+ impl Pid {
46
+ pub fn new(pid: u32) -> Self {
47
+ Self(pid)
48
+ }
49
+ pub fn get(self) -> u32 {
50
+ self.0
51
+ }
52
+ }
53
+
54
+ impl std::fmt::Display for Pid {
55
+ fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
56
+ write!(f, "{}", self.0)
57
+ }
58
+ }
59
+
60
+ /// resolve()'d workspace 路径(`Path(args.workspace).resolve()`,`__main__.py:31`)。
61
+ /// tick/health/start/stop 全以它为 key —— 不与裸 `PathBuf` 混。
62
+ #[derive(Debug, Clone, PartialEq, Eq, Hash, PartialOrd, Ord)]
63
+ pub struct WorkspacePath(pub PathBuf);
64
+
65
+ impl WorkspacePath {
66
+ pub fn new(p: impl Into<PathBuf>) -> Self {
67
+ Self(p.into())
68
+ }
69
+ pub fn as_path(&self) -> &Path {
70
+ &self.0
71
+ }
72
+ }
73
+
74
+ // ===========================================================================
75
+ // §19 散字符串态 → 穷尽 enum
76
+ // ===========================================================================
77
+
78
+ /// metadata `source`(`__main__.py:34` boot / `lifecycle.py:119` start)。仅两调用点 → enum。
79
+ #[derive(Debug, Clone, Copy, PartialEq, Eq, Hash, Serialize, Deserialize)]
80
+ #[serde(rename_all = "snake_case")]
81
+ pub enum MetadataSource {
82
+ Boot,
83
+ Start,
84
+ }
85
+
86
+ /// health dict `status`(`lifecycle.py:30,34,38-46`)。
87
+ /// **ADJUDICATION**:与 `crate::provider::HealthStatus`(agent health label,大写)**不同概念** ——
88
+ /// 那是 worker agent 健康标签,本 enum 是 *coordinator daemon* 进程健康态 → 命名 `CoordinatorHealthStatus` 避撞。
89
+ /// `ok` 由 `running ∧ metadata_ok ∧ schema_ok` 三者合取得出(`lifecycle.py:38`),不在此 enum 内。
90
+ #[derive(Debug, Clone, Copy, PartialEq, Eq, Hash, Serialize, Deserialize)]
91
+ #[serde(rename_all = "snake_case")]
92
+ pub enum CoordinatorHealthStatus {
93
+ /// pid 文件不存在(`lifecycle.py:30`)。
94
+ Missing,
95
+ /// pid 文件存在但非整数(`lifecycle.py:34`)。
96
+ InvalidPid,
97
+ /// pid 存活(`lifecycle.py:41`)。
98
+ Running,
99
+ /// pid 文件存在但进程已死(`lifecycle.py:41`)。
100
+ Stale,
101
+ }
102
+
103
+ /// `start_coordinator` 结果 status(`lifecycle.py:54,73,89,121`)。
104
+ #[derive(Debug, Clone, Copy, PartialEq, Eq, Hash, Serialize, Deserialize)]
105
+ #[serde(rename_all = "snake_case")]
106
+ pub enum StartOutcome {
107
+ /// 已健康 → no-op(`lifecycle.py:54`)。
108
+ AlreadyRunning,
109
+ /// metadata 不兼容,先 stop 但 stop 失败(`lifecycle.py:73`)。
110
+ RestartIncompatibleStopFailed,
111
+ /// schema 不兼容,拒启并给修复 hint(`lifecycle.py:89`)。
112
+ SchemaIncompatible,
113
+ /// 正常 spawn(`lifecycle.py:121`)。
114
+ Started,
115
+ }
116
+
117
+ /// `stop_coordinator` 结果 status(`lifecycle.py:232,238,243,247`)。
118
+ #[derive(Debug, Clone, Copy, PartialEq, Eq, Hash, Serialize, Deserialize)]
119
+ #[serde(rename_all = "snake_case")]
120
+ pub enum StopOutcome {
121
+ /// pid 文件不存在(`lifecycle.py:232`)。
122
+ Missing,
123
+ /// pid 非整数 → 清文件返回(`lifecycle.py:238`)。
124
+ InvalidPidRemoved,
125
+ /// SIGTERM 失败(`lifecycle.py:243`)。
126
+ KillFailed,
127
+ /// SIGTERM + 清 pid/meta 成功(`lifecycle.py:247`)。
128
+ Stopped,
129
+ }
130
+
131
+ /// tick degraded/stop 的 `reason`(`lifecycle.py:279,357`)。§19 散字符串 → enum。
132
+ #[derive(Debug, Clone, Copy, PartialEq, Eq, Hash, Serialize, Deserialize)]
133
+ #[serde(rename_all = "snake_case")]
134
+ pub enum TickStopReason {
135
+ /// tmux session 不在 → `stop:true` 触发主循环退出(`lifecycle.py:279`)。
136
+ TmuxSessionMissing,
137
+ /// bug-084:tick-end save_runtime_state 失败,`stop:false`(`lifecycle.py:357`)。
138
+ PersistenceDegraded,
139
+ }
140
+
141
+ /// 孤儿分类 reason(`orphan_cleanup.py:87-100`)。携带 hint 数据 → enum(非散字符串)。
142
+ /// **ADJUDICATION**:orphan_cleanup 的完整 SIGTERM/SIGKILL 升级逻辑归 step 14 诊断面;
143
+ /// 本 step 拥有 reason 分类 enum 是因为 daemon 自终止(Gap 37b)与诊断共享它(card §35)。
144
+ #[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)]
145
+ #[serde(tag = "reason", rename_all = "snake_case")]
146
+ pub enum OrphanReason {
147
+ /// workspace 目录已不存在(`orphan_cleanup.py`)。
148
+ WorkspacePathMissing,
149
+ /// 临时目录模式命中(携带 hint,如 `/var/folders/...team-agent-watcher-dedupe-*`)。
150
+ EphemeralTempdirPattern { hint: String },
151
+ /// workspace 仍在 → 不是孤儿。
152
+ WorkspaceAlive,
153
+ /// 无法解析 cmdline → 无法判定 workspace。
154
+ CmdlineUnparsed,
155
+ }
156
+
157
+ // ===========================================================================
158
+ // CoordinatorMetadata(metadata.py:50-57)
159
+ // ===========================================================================
160
+
161
+ /// `coordinator.json` 内容(`metadata.py:50-57`)。serde 字段名锁死稳定 JSON 契约。
162
+ /// 健康判定需三元全等:`pid == 实际 ∧ protocol_version == PROTOCOL_VERSION ∧
163
+ /// message_store_schema_version == SCHEMA_VERSION`(`metadata.py:37-43`)。
164
+ #[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)]
165
+ pub struct CoordinatorMetadata {
166
+ pub pid: Pid,
167
+ pub protocol_version: u32,
168
+ pub message_store_schema_version: i64,
169
+ pub source: MetadataSource,
170
+ /// ISO8601(`datetime.now(timezone.utc).isoformat()`,`metadata.py:56`)。
171
+ pub updated_at: String,
172
+ }
173
+
174
+ // ===========================================================================
175
+ // SchemaHealth(lifecycle.py:197-226)
176
+ // ===========================================================================
177
+
178
+ /// message-store schema 兼容门结果(`message_store_schema_health`,`lifecycle.py:197`)。
179
+ /// 用穷尽 enum 表 mismatch(card 表:`SchemaHealth { ok, error: Option<SchemaError> }`)。
180
+ #[derive(Debug, Clone, PartialEq, Eq)]
181
+ pub struct SchemaHealth {
182
+ /// `schema_ok`(`lifecycle.py:222/201`)。
183
+ pub ok: bool,
184
+ /// 当前 `MessageStore::SCHEMA_VERSION`(`lifecycle.py:198`)。
185
+ pub schema_version: i64,
186
+ /// `None` ⇔ `ok == true`。
187
+ pub error: Option<SchemaError>,
188
+ /// 修复 hint(`_SCHEMA_ACTION_HINT`,`lifecycle.py:131-135`);仅 error 时填。
189
+ pub action: Option<String>,
190
+ }
191
+
192
+ /// schema mismatch 的穷尽分类(`_diagnose_schema_mismatch`,`lifecycle.py:164-194`)。
193
+ /// 区分「pre-init 必需列缺失」(拒启)vs「migratable 列缺失」(可迁移)——card §89 铁律。
194
+ #[derive(Debug, Clone, PartialEq, Eq)]
195
+ pub enum SchemaError {
196
+ /// pragma table_info vs expected 列集不符(`lifecycle.py:185-191`)。携带定位字段。
197
+ SchemaMismatch {
198
+ table: String,
199
+ expected_columns: Vec<String>,
200
+ actual_columns: Vec<String>,
201
+ missing_columns: Vec<String>,
202
+ /// pre-init 必需列(true)vs migratable(false)——决定拒启 vs 可迁移(card §89)。
203
+ pre_init_required: bool,
204
+ },
205
+ /// `MessageStore(workspace)` 构造抛异常(`lifecycle.py:213`),携带原文。
206
+ InitFailed { message: String },
207
+ }
208
+
209
+ // ===========================================================================
210
+ // health / start / stop report 结构(lifecycle.py:39-247 typed 版)
211
+ // ===========================================================================
212
+
213
+ /// `start_coordinator` 错误(spawn 子进程 / ensure dirs 失败)。lib 边界 thiserror(§12)。
214
+ #[derive(Debug, Error)]
215
+ pub enum StartError {
216
+ #[error("io: {0}")]
217
+ Io(#[from] std::io::Error),
218
+ #[error("event log: {0}")]
219
+ EventLog(#[from] crate::event_log::EventLogError),
220
+ #[error("message store: {0}")]
221
+ MessageStore(#[from] crate::message_store::MessageStoreError),
222
+ }
223
+
224
+ /// `stop_coordinator` 错误。
225
+ #[derive(Debug, Error)]
226
+ pub enum StopError {
227
+ #[error("io: {0}")]
228
+ Io(#[from] std::io::Error),
229
+ #[error("event log: {0}")]
230
+ EventLog(#[from] crate::event_log::EventLogError),
231
+ }
232
+
233
+ /// `coordinator_health` 结果(`lifecycle.py:39-46` typed 版)。
234
+ #[derive(Debug, Clone, PartialEq, Eq)]
235
+ pub struct HealthReport {
236
+ /// `running ∧ metadata_ok ∧ schema_ok`(`lifecycle.py:38`)。
237
+ pub ok: bool,
238
+ pub status: CoordinatorHealthStatus,
239
+ pub pid: Option<Pid>,
240
+ pub metadata: Option<CoordinatorMetadata>,
241
+ /// 三元全等(`coordinator_metadata_ok`,`metadata.py:37-43`)。
242
+ pub metadata_ok: bool,
243
+ pub schema: SchemaHealth,
244
+ }
245
+
246
+ /// `start_coordinator` 结果(`lifecycle.py:54/86/121` typed 版)。
247
+ #[derive(Debug, Clone, PartialEq, Eq)]
248
+ pub struct StartReport {
249
+ pub ok: bool,
250
+ pub pid: Option<Pid>,
251
+ pub status: StartOutcome,
252
+ /// coordinator.log 路径(成功路径,`lifecycle.py:54/121`)。
253
+ pub log: Option<PathBuf>,
254
+ /// schema_incompatible 时的修复 hint / 失败原因。
255
+ pub schema_error: Option<SchemaError>,
256
+ pub action: Option<String>,
257
+ }
258
+
259
+ /// `stop_coordinator` 结果(`lifecycle.py:232-247` typed 版)。
260
+ #[derive(Debug, Clone, PartialEq, Eq)]
261
+ pub struct StopReport {
262
+ pub ok: bool,
263
+ pub status: StopOutcome,
264
+ pub pid: Option<Pid>,
265
+ }
266
+
267
+ // ===========================================================================
268
+ // CoordinatorEvent(§3/§22:typed event enum,serde tag 与 Python 字节级一致)
269
+ // ===========================================================================
270
+
271
+ /// 本 step 发出的事件(card 表整列;事件名稳定契约由 step 4 EventLog 拥有,本卡只点名
272
+ /// coordinator 发的那批)。serde `tag = "event"` + 精确 rename 锁死字节(与 events.jsonl 一致)。
273
+ /// 渲染(`watch::render_event_line`)是它的 `Display` 投影。
274
+ #[derive(Debug, Clone, PartialEq, Serialize, Deserialize)] // 无 Eq:某变体含 f64
275
+ #[serde(tag = "event")]
276
+ pub enum CoordinatorEvent {
277
+ #[serde(rename = "coordinator.boot")]
278
+ Boot { workspace: String, once: bool },
279
+ #[serde(rename = "coordinator.started")]
280
+ Started { pid: Pid, log: String },
281
+ #[serde(rename = "coordinator.stopped")]
282
+ Stopped { pid: Pid },
283
+ #[serde(rename = "coordinator.exit")]
284
+ Exit { stop: bool },
285
+ #[serde(rename = "coordinator.session_missing")]
286
+ SessionMissing { session: String },
287
+ #[serde(rename = "coordinator.orphan_self_terminate")]
288
+ OrphanSelfTerminate {
289
+ initial_ppid: u32,
290
+ current_ppid: u32,
291
+ workspace: String,
292
+ },
293
+ #[serde(rename = "coordinator.tick_error")]
294
+ TickError {
295
+ error: String,
296
+ exc_type: String,
297
+ consecutive_failures: u32,
298
+ next_sleep_sec: f64,
299
+ },
300
+ #[serde(rename = "coordinator.tick_error.suppressed")]
301
+ TickErrorSuppressed {
302
+ consecutive_failures: u32,
303
+ next_sleep_sec: f64,
304
+ },
305
+ #[serde(rename = "coordinator.tick_recovered")]
306
+ TickRecovered { consecutive_failures: u32 },
307
+ #[serde(rename = "coordinator.restart_incompatible")]
308
+ RestartIncompatible {
309
+ pid: Option<Pid>,
310
+ expected_protocol: u32,
311
+ expected_schema: i64,
312
+ },
313
+ #[serde(rename = "coordinator.restart_incompatible_stop_failed")]
314
+ RestartIncompatibleStopFailed { pid: Option<Pid> },
315
+ #[serde(rename = "coordinator.schema_incompatible")]
316
+ SchemaIncompatible {
317
+ table: Option<String>,
318
+ missing_columns: Vec<String>,
319
+ },
320
+ #[serde(rename = "idle_takeover.unknown_persistent")]
321
+ IdleTakeoverUnknownPersistent {
322
+ node_id: String,
323
+ provider: Option<Provider>,
324
+ auth_mode: Option<AuthMode>,
325
+ consecutive_ticks: u32,
326
+ rollout_path: Option<RolloutPath>,
327
+ },
328
+ #[serde(rename = "abnormal.notify")]
329
+ AbnormalNotify {
330
+ signature: String,
331
+ turn_id: Option<TurnId>,
332
+ decision: AbnormalDecision,
333
+ },
334
+ #[serde(rename = "worker.abnormal_exit")]
335
+ WorkerAbnormalExit {
336
+ team_id: String,
337
+ agent_id: String,
338
+ provider: Provider,
339
+ path: String,
340
+ provider_process_dead: bool,
341
+ latest_explicit_error: bool,
342
+ signature: String,
343
+ turn_id: Option<TurnId>,
344
+ process_liveness: ProcessLiveness,
345
+ },
346
+ #[serde(rename = "worker.abnormal_exit.check")]
347
+ WorkerAbnormalExitCheck {
348
+ team_id: String,
349
+ agent_id: String,
350
+ provider: Provider,
351
+ path: String,
352
+ provider_process_dead: bool,
353
+ latest_explicit_error: bool,
354
+ notification: bool,
355
+ suppressed_reason: Option<String>,
356
+ },
357
+ #[serde(rename = "abnormal_exit.single_signal_suppressed")]
358
+ AbnormalExitSingleSignalSuppressed {
359
+ team_id: String,
360
+ agent_id: String,
361
+ provider: Provider,
362
+ path: String,
363
+ reason: String,
364
+ provider_process_dead: bool,
365
+ dead_process: bool,
366
+ latest_explicit_error: bool,
367
+ },
368
+ #[serde(rename = "abnormal.whole_team_gone")]
369
+ AbnormalWholeTeamGone { classification: WholeTeamGoneClass },
370
+ #[serde(rename = "leader_notification.log_pruned")]
371
+ LeaderNotificationLogPruned { removed: u64 },
372
+ #[serde(rename = "leader_notification.prune_failed")]
373
+ LeaderNotificationPruneFailed { error: String },
374
+ #[serde(rename = "runtime.state.save_failed")]
375
+ RuntimeStateSaveFailed {
376
+ phase: String,
377
+ error: String,
378
+ exc_type: String,
379
+ },
380
+ }
381
+
382
+ // ===========================================================================
383
+ // 异常轨 abnormal_track(abnormal_track.py)—— provider-neutral 数据型
384
+ // ===========================================================================
385
+
386
+ /// `_classify` 决策(`abnormal_track.py:198-204`)。whitelist > blacklist > default(C9 catch-bias)。
387
+ #[derive(Debug, Clone, Copy, PartialEq, Eq, Hash, Serialize, Deserialize)]
388
+ #[serde(rename_all = "snake_case")]
389
+ pub enum AbnormalDecision {
390
+ /// whitelist 命中 → 不通知(`abnormal_track.py:201`)。
391
+ Skip,
392
+ /// blacklist 命中 → 通知(`abnormal_track.py:203`)。
393
+ NotifyBlacklist,
394
+ /// 结构化 fault 默认通知(C9 catch-bias,`abnormal_track.py:204`)。
395
+ NotifyDefault,
396
+ }
397
+
398
+ /// `detect_whole_team_gone` 分类(`abnormal_track.py:130/132/143`)。
399
+ #[derive(Debug, Clone, Copy, PartialEq, Eq, Hash, Serialize, Deserialize)]
400
+ #[serde(rename_all = "snake_case")]
401
+ pub enum WholeTeamGoneClass {
402
+ Alive,
403
+ /// clean shutdown → 静默(`abnormal_track.py:130`)。
404
+ CleanShutdown,
405
+ /// restart 进行中 → 静默(`abnormal_track.py:132`)。
406
+ RestartInProgress,
407
+ /// 闪退 → durable marker + deferred escalation(`abnormal_track.py:143`)。
408
+ UnexpectedExit,
409
+ }
410
+
411
+ /// `process_abnormal_records` 单条通知(`abnormal_track.py:70-79`)。
412
+ /// dedup key = `(signature, turn_id|fingerprint)`(C8,`abnormal_track.py:64-66`):turn_id 缺失退化为
413
+ /// per-record content fingerprint 桶,**绝不**把不同 fault 折叠进一个全局桶。
414
+ #[derive(Debug, Clone, PartialEq, Eq)]
415
+ pub struct AbnormalNotification {
416
+ pub signature: String,
417
+ pub turn_id: Option<TurnId>,
418
+ /// `kind == "approval"` → blocked_on_human,否则 abnormal(`abnormal_track.py:74`)。
419
+ pub state: TurnState,
420
+ pub decision: AbnormalDecision,
421
+ pub provider: Option<Provider>,
422
+ /// 原始 fault fact(provider reader 产出的结构化记录;本 module 不读屏不命名 provider)。
423
+ pub raw: Value,
424
+ }
425
+
426
+ /// `process_abnormal_records` 返回(`abnormal_track.py:83-88` typed 版)。
427
+ #[derive(Debug, Clone, PartialEq, Eq)]
428
+ pub struct AbnormalProcessOutput {
429
+ pub notifications: Vec<AbnormalNotification>,
430
+ /// 更新后的去重状态(`seen` 集合,`abnormal_track.py:82`)——caller 回存。
431
+ pub notification_state: AbnormalNotificationState,
432
+ }
433
+
434
+ /// abnormal 去重状态(`abnormal_track.py:31-32,82`)。`seen` = `signature\0bucket` key 集合。
435
+ #[derive(Debug, Clone, Default, PartialEq, Eq, Serialize, Deserialize)]
436
+ pub struct AbnormalNotificationState {
437
+ pub seen: BTreeSet<String>,
438
+ }
439
+
440
+ /// `detect_whole_team_gone` 返回(`abnormal_track.py:140-147` typed 版)。
441
+ #[derive(Debug, Clone, PartialEq, Eq)]
442
+ pub struct WholeTeamGoneReport {
443
+ pub whole_team_gone: bool,
444
+ pub classification: WholeTeamGoneClass,
445
+ pub notify: bool,
446
+ /// 仅 unexpected exit 时 true(`abnormal_track.py:145`):延迟到下条 leader 命令再 escalate。
447
+ pub escalate_user_on_next_leader_command: bool,
448
+ pub marker_written: bool,
449
+ }
450
+
451
+ /// 整队存活快照(`detect_whole_team_gone` 的 snapshot 入参,`abnormal_track.py:105-116`)。
452
+ /// coordinator-independent:不依赖 coordinator 活着也能判。
453
+ #[derive(Debug, Clone, PartialEq, Eq)]
454
+ pub struct TeamPresenceSnapshot {
455
+ pub coordinator_alive: bool,
456
+ pub leader_alive: bool,
457
+ /// 每 worker 进程存活(`provider_state` liveness;`ProcessLiveness::Alive` 才算活)。
458
+ pub provider_processes_alive: Vec<bool>,
459
+ pub tmux_sessions_present: bool,
460
+ pub clean_shutdown: bool,
461
+ pub restart_in_progress: bool,
462
+ }
463
+
464
+ /// abnormal track 错误(provider reader 翻译 fault facts 失败)。
465
+ #[derive(Debug, Error)]
466
+ pub enum AbnormalError {
467
+ #[error("provider: {0}")]
468
+ Provider(#[from] crate::provider::ProviderError),
469
+ }
470
+
471
+ // ===========================================================================
472
+ // WatchCursor(watch/__init__.py)
473
+ // ===========================================================================
474
+
475
+ /// watch tail 游标(`watch.py:14-19`)。rotation 检测靠 `archive_signature` 变化 + `offset > size`
476
+ /// (`watch.py:73-83`)。`archive_signature = Some((size, mtime_ns))`。
477
+ #[derive(Debug, Clone, Default, PartialEq, Eq)]
478
+ pub struct WatchCursor {
479
+ pub event_offset: u64,
480
+ pub seen_result_ids: BTreeSet<String>,
481
+ pub initialized: bool,
482
+ /// `(size, mtime_ns)`;`mtime_ns: i128`(防溢出)。
483
+ pub archive_signature: Option<(u64, i128)>,
484
+ }
485
+
486
+ // ===========================================================================
487
+ // CROSS-DEP placeholders(其他并行 lane 拥有真名;leader 集成时 reconcile)
488
+ // ===========================================================================
489
+ // 下列类型/trait 是 tick 编排与异常轨命名到的、由 OTHER 10-15 子系统(step 8 provider、
490
+ // step 11 messaging、step 5 state projection)拥有的面。本 lane 给最小本地占位让 coordinator
491
+ // 的签名编得过;leader 集成时把它们换成真名(见 cross_deps_or_placeholders 清单)。
492
+
493
+ /// agent id(step 2/5 拥有 newtype;tick stuck 列表 / idle node 用)。
494
+ /// **PLACEHOLDER**:与 `crate::model::ids::AgentId` 同名同义,但 ids.rs 已定义 —— 集成时直接
495
+ /// `use crate::model::ids::AgentId` 替换本地别名。此处用本地 type alias 避免重定义冲突。
496
+ pub use crate::model::ids::AgentId;
497
+
498
+ /// provider adapter 解析器(`get_provider_registry` / `ADAPTERS` map 的 trait 版,step 8 拥有真名)。
499
+ /// **PLACEHOLDER**:step 8 provider lane 会给真正的 registry 类型;本 trait 是 coordinator 注入点
500
+ /// (MUST-NOT-13:经 trait 调,绝不依赖 provider client crate)。
501
+ pub trait ProviderRegistry {
502
+ /// 拿某 provider 的 adapter(`providers.get_adapter`)。
503
+ fn adapter_for(&self, provider: Provider) -> Box<dyn ProviderAdapter>;
504
+ /// 该 provider 的 error 黑白名单(`get_provider_registry(provider)["error_lists"]`,abnormal_track 用)。
505
+ fn error_lists(&self, provider: Provider) -> ErrorLists;
506
+ }
507
+
508
+ /// provider error 黑白名单(`abnormal_track.py:184-195`)。**PLACEHOLDER**(step 8 拥有)。
509
+ #[derive(Debug, Clone, Default, PartialEq, Eq)]
510
+ pub struct ErrorLists {
511
+ pub whitelist: Vec<String>,
512
+ pub blacklist: Vec<String>,
513
+ }
514
+
515
+ /// idle take-over 候选 node(`idle_takeover_wiring.build_idle_nodes`,step 8/11 拥有真名)。
516
+ /// **PLACEHOLDER**:bug-085 关键 —— `state` 是穷尽 `TurnState`,`rollout_path` 是 `Option`
517
+ /// (None 漏穿曾误判 unknown→idle)。
518
+ #[derive(Debug, Clone, PartialEq, Eq)]
519
+ pub struct IdleNode {
520
+ pub node_id: AgentId,
521
+ pub state: TurnState,
522
+ pub provider: Option<Provider>,
523
+ pub rollout_path: Option<RolloutPath>,
524
+ }
525
+
526
+ /// idle take-over 提醒(`lifecycle.py:304-307`)。**PLACEHOLDER**(step 11 messaging 拥有 alert 形状)。
527
+ #[derive(Debug, Clone, PartialEq, Eq)]
528
+ pub struct IdleAlert {
529
+ pub message: Option<String>,
530
+ pub reason: Option<String>,
531
+ pub interrupted: Vec<AgentId>,
532
+ }
533
+
534
+ /// `_deliver_pending_messages` 投递记录(`delivery.py:484`,step 11 拥有)。**PLACEHOLDER**。
535
+ #[derive(Debug, Clone, PartialEq, Eq)]
536
+ pub struct DeliveredMessage {
537
+ pub message_id: String,
538
+ }
539
+
540
+ /// `_fire_due_scheduled_events` 触发记录(`scheduler.py:41`,step 11 拥有)。**PLACEHOLDER**。
541
+ #[derive(Debug, Clone, PartialEq, Eq)]
542
+ pub struct FiredScheduledEvent {
543
+ pub id: i64,
544
+ }
545
+
546
+ /// `detect_cross_worker_deadlocks` 告警(`messaging/idle_alerts.py`,step 11 拥有)。**PLACEHOLDER**。
547
+ #[derive(Debug, Clone, PartialEq, Eq)]
548
+ pub struct DeadlockAlert {
549
+ pub raw: Value,
550
+ }
551
+
552
+ /// `detect_compaction_degradation` 结果(`messaging/activity_detector.py`,step 11 拥有)。**PLACEHOLDER**。
553
+ #[derive(Debug, Clone, PartialEq, Eq)]
554
+ pub struct CompactionResult {
555
+ pub agent_id: AgentId,
556
+ pub raw: Value,
557
+ }
558
+
559
+ /// `detect_session_drift` 结果(`messaging/session_drift.py`,step 11 拥有)。**PLACEHOLDER**。
560
+ #[derive(Debug, Clone, PartialEq, Eq)]
561
+ pub struct SessionDriftResult {
562
+ pub agent_id: AgentId,
563
+ pub raw: Value,
564
+ }
565
+
566
+ /// `detect_leader_api_errors` 结果(`messaging/leader_api_errors.py`,step 11 拥有)。**PLACEHOLDER**。
567
+ #[derive(Debug, Clone, PartialEq, Eq)]
568
+ pub struct LeaderApiError {
569
+ pub raw: Value,
570
+ }
571
+
572
+ /// `_collect_results_and_notify_watchers` 结果(`results.py:430`,step 11 拥有)。**PLACEHOLDER**。
573
+ #[derive(Debug, Clone, PartialEq, Eq)]
574
+ pub struct CollectedResult {
575
+ pub result_id: String,
576
+ }
577
+
578
+ /// durable marker store(`detect_whole_team_gone` 的 marker_store 入参,`abnormal_track.py:226-239`)。
579
+ /// **PLACEHOLDER**:step 5 state / step 7 message_store 可能拥有真正的 marker 存储面;
580
+ /// 本 trait 是 abnormal track 的注入点(写 `whole_team_gone` durable marker)。
581
+ pub trait MarkerStore {
582
+ /// 写一个命名 marker;返回是否落盘成功(`abnormal_track.py:232-238`)。
583
+ fn set_marker(&mut self, name: &str, value: Value) -> bool;
584
+ }