@team-agent/installer 0.5.61 → 0.5.62

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 (250) hide show
  1. package/Cargo.lock +1 -1
  2. package/Cargo.toml +1 -1
  3. package/crates/team-agent/src/cli/adapters.rs +5 -2
  4. package/crates/team-agent/src/cli/attach_app_server_leader.rs +1 -0
  5. package/crates/team-agent/src/cli/diagnose.rs +1 -0
  6. package/crates/team-agent/src/cli/emit.rs +41 -7
  7. package/crates/team-agent/src/cli/helpers.rs +1 -0
  8. package/crates/team-agent/src/cli/leader.rs +6 -1
  9. package/crates/team-agent/src/cli/leaders.rs +2 -0
  10. package/crates/team-agent/src/cli/mod.rs +33 -3
  11. package/crates/team-agent/src/cli/named_address.rs +8 -1
  12. package/crates/team-agent/src/cli/profile.rs +2 -1
  13. package/crates/team-agent/src/cli/send/coordinator.rs +1 -0
  14. package/crates/team-agent/src/cli/send/mailbox.rs +3 -0
  15. package/crates/team-agent/src/cli/send/persist.rs +1 -0
  16. package/crates/team-agent/src/cli/send/presentation.rs +1 -0
  17. package/crates/team-agent/src/cli/send/resolve.rs +206 -1
  18. package/crates/team-agent/src/cli/send.rs +2 -1
  19. package/crates/team-agent/src/cli/spec.rs +1 -0
  20. package/crates/team-agent/src/cli/status.rs +2 -1
  21. package/crates/team-agent/src/cli/status_port/compact.rs +1 -0
  22. package/crates/team-agent/src/cli/status_port/format.rs +1 -0
  23. package/crates/team-agent/src/cli/status_port/inbox.rs +1 -0
  24. package/crates/team-agent/src/cli/tests/verb_profile.rs +38 -0
  25. package/crates/team-agent/src/cli/types.rs +3 -2
  26. package/crates/team-agent/src/communication_mode/mod.rs +1 -0
  27. package/crates/team-agent/src/compiler.rs +1 -0
  28. package/crates/team-agent/src/conpty/backend.rs +1 -0
  29. package/crates/team-agent/src/conpty/mod.rs +1 -0
  30. package/crates/team-agent/src/coordinator/backoff.rs +5 -8
  31. package/crates/team-agent/src/coordinator/conpty_shim.rs +3 -2
  32. package/crates/team-agent/src/coordinator/health.rs +1 -0
  33. package/crates/team-agent/src/coordinator/mod.rs +2 -2
  34. package/crates/team-agent/src/coordinator/orphan.rs +4 -116
  35. package/crates/team-agent/src/coordinator/runtime_detectors.rs +1 -0
  36. package/crates/team-agent/src/coordinator/runtime_observation.rs +1 -0
  37. package/crates/team-agent/src/coordinator/steps/abnormal.rs +6 -5
  38. package/crates/team-agent/src/coordinator/steps/delivery.rs +1 -0
  39. package/crates/team-agent/src/coordinator/steps/health_sync.rs +1 -0
  40. package/crates/team-agent/src/coordinator/steps/mod.rs +2 -0
  41. package/crates/team-agent/src/coordinator/steps/persist.rs +1 -0
  42. package/crates/team-agent/src/coordinator/steps/runtime_prompts.rs +1 -0
  43. package/crates/team-agent/src/coordinator/steps/session_gate.rs +1 -0
  44. package/crates/team-agent/src/coordinator/tests/abnormal.rs +0 -174
  45. package/crates/team-agent/src/coordinator/tests/api_error_recovery.rs +0 -9
  46. package/crates/team-agent/src/coordinator/tests/basics.rs +0 -184
  47. package/crates/team-agent/src/coordinator/tests/mod.rs +2 -17
  48. package/crates/team-agent/src/coordinator/tests/tick_core.rs +0 -42
  49. package/crates/team-agent/src/coordinator/tick.rs +24 -28
  50. package/crates/team-agent/src/coordinator/types.rs +3 -176
  51. package/crates/team-agent/src/db/agent_health_capture.rs +1 -0
  52. package/crates/team-agent/src/db/message_store.rs +2 -1
  53. package/crates/team-agent/src/db/migration.rs +5 -4
  54. package/crates/team-agent/src/db/mod.rs +1 -0
  55. package/crates/team-agent/src/db/schema.rs +1 -0
  56. package/crates/team-agent/src/diagnose/comms.rs +2 -1
  57. package/crates/team-agent/src/diagnose/mod.rs +1 -0
  58. package/crates/team-agent/src/diagnose/orphans.rs +1 -0
  59. package/crates/team-agent/src/layout/manager.rs +3 -7
  60. package/crates/team-agent/src/layout/mod.rs +2 -2
  61. package/crates/team-agent/src/layout/overlay.rs +6 -1
  62. package/crates/team-agent/src/layout/placement.rs +1 -0
  63. package/crates/team-agent/src/layout/recovery.rs +3 -0
  64. package/crates/team-agent/src/layout/runtime_sessions.rs +8 -3
  65. package/crates/team-agent/src/layout/sessions.rs +8 -1
  66. package/crates/team-agent/src/layout/tmux_endpoint.rs +3 -0
  67. package/crates/team-agent/src/layout/worker_env.rs +3 -0
  68. package/crates/team-agent/src/layout/worker_window_helpers.rs +2 -0
  69. package/crates/team-agent/src/leader/helpers.rs +1 -0
  70. package/crates/team-agent/src/leader/incident.rs +1 -0
  71. package/crates/team-agent/src/leader/lease.rs +27 -22
  72. package/crates/team-agent/src/leader/mod.rs +2 -3
  73. package/crates/team-agent/src/leader/owner_bind.rs +13 -3
  74. package/crates/team-agent/src/leader/provider_attribution.rs +1 -0
  75. package/crates/team-agent/src/leader/rediscover.rs +4 -17
  76. package/crates/team-agent/src/leader/registry.rs +3 -15
  77. package/crates/team-agent/src/leader/start.rs +373 -125
  78. package/crates/team-agent/src/leader/takeover.rs +10 -232
  79. package/crates/team-agent/src/leader/tests/claim_leader_mailbox_flush_contract.rs +544 -0
  80. package/crates/team-agent/src/leader/tests/historical_inventory_upgrade_gate_red.rs +624 -0
  81. package/crates/team-agent/src/leader/tests/identity.rs +7 -2
  82. package/crates/team-agent/src/leader/tests/idle.rs +0 -193
  83. package/crates/team-agent/src/leader/tests/lease_api.rs +0 -45
  84. package/crates/team-agent/src/leader/tests/mod.rs +4 -41
  85. package/crates/team-agent/src/leader/tests/rehomed_env.rs +83 -0
  86. package/crates/team-agent/src/leader/tests/team_in_team_state_scope_red.rs +1273 -0
  87. package/crates/team-agent/src/leader/tests/terminal_and_replay_vs_rerender_invariants_red.rs +417 -0
  88. package/crates/team-agent/src/leader/tests/wake_start_owner.rs +22 -103
  89. package/crates/team-agent/src/leader/types.rs +1 -28
  90. package/crates/team-agent/src/lib.rs +3 -0
  91. package/crates/team-agent/src/lifecycle/display.rs +7 -1
  92. package/crates/team-agent/src/lifecycle/helpers.rs +3 -1
  93. package/crates/team-agent/src/lifecycle/launch/add_agent.rs +2 -2
  94. package/crates/team-agent/src/lifecycle/launch/fork_agent/completion.rs +1 -0
  95. package/crates/team-agent/src/lifecycle/launch/fork_entry.rs +1 -0
  96. package/crates/team-agent/src/lifecycle/launch/fork_finalize.rs +1 -0
  97. package/crates/team-agent/src/lifecycle/launch/plan.rs +2 -2
  98. package/crates/team-agent/src/lifecycle/launch/quick_start.rs +4 -26
  99. package/crates/team-agent/src/lifecycle/launch/readiness.rs +0 -27
  100. package/crates/team-agent/src/lifecycle/launch/spawn.rs +1 -27
  101. package/crates/team-agent/src/lifecycle/launch/spec_state.rs +4 -32
  102. package/crates/team-agent/src/lifecycle/launch/state_projection.rs +1 -0
  103. package/crates/team-agent/src/lifecycle/launch.rs +11 -12
  104. package/crates/team-agent/src/lifecycle/mod.rs +2 -1
  105. package/crates/team-agent/src/lifecycle/restart/agent.rs +3 -3
  106. package/crates/team-agent/src/lifecycle/restart/orchestrator.rs +2 -2
  107. package/crates/team-agent/src/lifecycle/restart/rebuild.rs +13 -5
  108. package/crates/team-agent/src/lifecycle/restart/remove.rs +1 -1
  109. package/crates/team-agent/src/lifecycle/restart/selection.rs +3 -3
  110. package/crates/team-agent/src/lifecycle/restart.rs +13 -11
  111. package/crates/team-agent/src/lifecycle/tests/acceptance_b_batch_red.rs +1007 -0
  112. package/crates/team-agent/src/lifecycle/tests/b0_legacy_snapshot_nonauthority_contract.rs +265 -0
  113. package/crates/team-agent/src/lifecycle/tests/b0_reader_hideone_audit_contract.rs +459 -0
  114. package/crates/team-agent/src/lifecycle/tests/behavioral_diff_264_red.rs +849 -0
  115. package/crates/team-agent/src/lifecycle/tests/claude_compatible_config_red.rs +323 -0
  116. package/crates/team-agent/src/lifecycle/tests/claude_profile_launch_red.rs +423 -0
  117. package/crates/team-agent/src/lifecycle/tests/clone_fork_copilot_perms_red.rs +737 -0
  118. package/crates/team-agent/src/lifecycle/tests/codex_mcp_approval_inheritance_red.rs +1187 -0
  119. package/crates/team-agent/src/lifecycle/tests/codex_weak_window_attribution_red.rs +683 -0
  120. package/crates/team-agent/src/lifecycle/tests/communication_mode_runtime_contract_red.rs +394 -0
  121. package/crates/team-agent/src/lifecycle/tests/copilot_provider_red.rs +1856 -0
  122. package/crates/team-agent/src/lifecycle/tests/core_034_real_red.rs +917 -0
  123. package/crates/team-agent/src/lifecycle/tests/display_adaptive_red.rs +481 -0
  124. package/crates/team-agent/src/lifecycle/tests/f032_startup_prompt_best_effort_red.rs +301 -0
  125. package/crates/team-agent/src/lifecycle/tests/harvest2_a_batch_red.rs +516 -0
  126. package/crates/team-agent/src/lifecycle/tests/host_cotenant_death_p0_contract.rs +986 -0
  127. package/crates/team-agent/src/lifecycle/tests/lifecycle_rollback_red.rs +651 -0
  128. package/crates/team-agent/src/lifecycle/tests/main_preserved.rs +2 -0
  129. package/crates/team-agent/src/lifecycle/tests/quick_start_worker_readiness_red.rs +332 -0
  130. package/crates/team-agent/src/lifecycle/tests/realmachine_clusters_1_6_red.rs +846 -0
  131. package/crates/team-agent/src/lifecycle/tests/realmachine_residual_g1_g4_red.rs +648 -0
  132. package/crates/team-agent/src/lifecycle/tests/restart_build_before_destroy_0540_contract.rs +910 -0
  133. package/crates/team-agent/src/lifecycle/tests/restart_liveness_red.rs +630 -0
  134. package/crates/team-agent/src/lifecycle/tests/restart_rebind_hotfix_252_red.rs +1083 -0
  135. package/crates/team-agent/src/lifecycle/tests/restart_session_capture_red.rs +1677 -0
  136. package/crates/team-agent/src/lifecycle/tests/resume_recover_red.rs +410 -0
  137. package/crates/team-agent/src/lifecycle/tests/stale_team_saveconflict_contract.rs +428 -0
  138. package/crates/team-agent/src/lifecycle/tests/startup_latency_contract.rs +1032 -0
  139. package/crates/team-agent/src/lifecycle/tests/status_credential_redaction_contract.rs +869 -0
  140. package/crates/team-agent/src/lifecycle/tests/subprep_codex_trust_roundtrip_red.rs +1249 -0
  141. package/crates/team-agent/src/lifecycle/tests/swallow_batch4_semantics_red.rs +342 -0
  142. package/crates/team-agent/src/lifecycle/tests/team_in_team_identity_scope_red.rs +542 -0
  143. package/crates/team-agent/src/lifecycle/tests/team_in_team_sibling_quick_start_red.rs +1103 -0
  144. package/crates/team-agent/src/lifecycle/tests/team_in_team_state_scope_red.rs +1276 -0
  145. package/crates/team-agent/src/lifecycle/tests/team_key_retirement_roster_red.rs +145 -0
  146. package/crates/team-agent/src/lifecycle/tests/team_key_retirement_txn_red.rs +603 -0
  147. package/crates/team-agent/src/lifecycle/tests/test_isolation_escape_contract.rs +837 -0
  148. package/crates/team-agent/src/lifecycle/tests/upgrade_compat_0211_red.rs +928 -0
  149. package/crates/team-agent/src/lifecycle/tests/verify_rs031_window_consistency_red.rs +951 -0
  150. package/crates/team-agent/src/lifecycle/tests/worker_dangerous_bypass_argv_red.rs +327 -0
  151. package/crates/team-agent/src/lifecycle/tests/worker_spawn_env_red.rs +760 -0
  152. package/crates/team-agent/src/lifecycle/tests.rs +59 -0
  153. package/crates/team-agent/src/lifecycle/types.rs +0 -9
  154. package/crates/team-agent/src/mcp_server/helpers.rs +1 -0
  155. package/crates/team-agent/src/mcp_server/lifecycle_tools/mod.rs +1 -0
  156. package/crates/team-agent/src/mcp_server/lifecycle_tools/state_status.rs +1 -0
  157. package/crates/team-agent/src/mcp_server/mod.rs +1 -0
  158. package/crates/team-agent/src/mcp_server/normalize.rs +4 -3
  159. package/crates/team-agent/src/mcp_server/tools.rs +1 -0
  160. package/crates/team-agent/src/mcp_server/types.rs +1 -18
  161. package/crates/team-agent/src/mcp_server/wire.rs +5 -5
  162. package/crates/team-agent/src/messaging/activity.rs +1 -0
  163. package/crates/team-agent/src/messaging/address.rs +1 -0
  164. package/crates/team-agent/src/messaging/delivery.rs +4 -3
  165. package/crates/team-agent/src/messaging/helpers.rs +2 -1
  166. package/crates/team-agent/src/messaging/leader_channel.rs +1 -0
  167. package/crates/team-agent/src/messaging/leader_receiver.rs +2 -1
  168. package/crates/team-agent/src/messaging/mod.rs +10 -14
  169. package/crates/team-agent/src/messaging/peers.rs +2 -0
  170. package/crates/team-agent/src/messaging/persist.rs +3 -1
  171. package/crates/team-agent/src/messaging/presentation.rs +2 -1
  172. package/crates/team-agent/src/messaging/results.rs +1 -0
  173. package/crates/team-agent/src/messaging/scheduler.rs +1 -0
  174. package/crates/team-agent/src/messaging/selftest.rs +1 -1
  175. package/crates/team-agent/src/messaging/send.rs +41 -8
  176. package/crates/team-agent/src/messaging/tests/mod.rs +5 -0
  177. package/crates/team-agent/src/messaging/types.rs +2 -2
  178. package/crates/team-agent/src/messaging/watchers.rs +19 -13
  179. package/crates/team-agent/src/model/enums.rs +1 -0
  180. package/crates/team-agent/src/model/errors.rs +1 -0
  181. package/crates/team-agent/src/model/ids.rs +1 -0
  182. package/crates/team-agent/src/model/mod.rs +1 -0
  183. package/crates/team-agent/src/model/name_similarity.rs +1 -0
  184. package/crates/team-agent/src/model/pane_authority_refusal.rs +1 -0
  185. package/crates/team-agent/src/model/paths.rs +1 -0
  186. package/crates/team-agent/src/model/permissions.rs +3 -2
  187. package/crates/team-agent/src/model/routing.rs +1 -0
  188. package/crates/team-agent/src/model/spec.rs +1 -0
  189. package/crates/team-agent/src/model/task_graph.rs +1 -0
  190. package/crates/team-agent/src/model/yaml/tests.rs +1 -0
  191. package/crates/team-agent/src/model/yaml.rs +1 -0
  192. package/crates/team-agent/src/packaging/install.rs +9 -147
  193. package/crates/team-agent/src/packaging/migrate.rs +2 -0
  194. package/crates/team-agent/src/packaging/mod.rs +1 -0
  195. package/crates/team-agent/src/packaging/repair.rs +2 -0
  196. package/crates/team-agent/src/packaging/tests.rs +29 -218
  197. package/crates/team-agent/src/packaging/types.rs +8 -15
  198. package/crates/team-agent/src/platform/argv.rs +4 -0
  199. package/crates/team-agent/src/platform/errors.rs +10 -1
  200. package/crates/team-agent/src/platform/file_lock.rs +4 -157
  201. package/crates/team-agent/src/platform/mod.rs +0 -61
  202. package/crates/team-agent/src/platform/process.rs +1 -0
  203. package/crates/team-agent/src/provider/adapter.rs +1 -0
  204. package/crates/team-agent/src/provider/adapters/claude.rs +1 -0
  205. package/crates/team-agent/src/provider/adapters/claude_fork.rs +1 -0
  206. package/crates/team-agent/src/provider/adapters/codex.rs +1 -0
  207. package/crates/team-agent/src/provider/adapters/copilot.rs +1 -0
  208. package/crates/team-agent/src/provider/adapters/copilot_fork.rs +1 -0
  209. package/crates/team-agent/src/provider/adapters/fake.rs +1 -0
  210. package/crates/team-agent/src/provider/adapters/mod.rs +1 -0
  211. package/crates/team-agent/src/provider/approvals/mod.rs +1 -0
  212. package/crates/team-agent/src/provider/approvals/parsing.rs +2 -5
  213. package/crates/team-agent/src/provider/approvals/runtime_prompts.rs +6 -5
  214. package/crates/team-agent/src/provider/classify.rs +1 -0
  215. package/crates/team-agent/src/provider/faults.rs +1 -26
  216. package/crates/team-agent/src/provider/helpers.rs +1 -0
  217. package/crates/team-agent/src/provider/mod.rs +1 -1
  218. package/crates/team-agent/src/provider/session/capture.rs +1 -4
  219. package/crates/team-agent/src/provider/session/context_fork/claude.rs +1 -0
  220. package/crates/team-agent/src/provider/session/context_fork/codex.rs +1 -0
  221. package/crates/team-agent/src/provider/session/context_fork/outcome.rs +1 -0
  222. package/crates/team-agent/src/provider/session/context_fork.rs +1 -0
  223. package/crates/team-agent/src/provider/session/mod.rs +2 -4
  224. package/crates/team-agent/src/provider/session/resume.rs +2 -209
  225. package/crates/team-agent/src/provider/session_scan/claude.rs +1 -0
  226. package/crates/team-agent/src/provider/session_scan/codex.rs +1 -0
  227. package/crates/team-agent/src/provider/session_scan/common.rs +1 -0
  228. package/crates/team-agent/src/provider/session_scan/copilot.rs +1 -0
  229. package/crates/team-agent/src/provider/session_scan.rs +1 -42
  230. package/crates/team-agent/src/provider/startup_prompt.rs +1 -0
  231. package/crates/team-agent/src/provider/types.rs +1 -0
  232. package/crates/team-agent/src/provider/wire.rs +1 -0
  233. package/crates/team-agent/src/state/identity.rs +16 -5
  234. package/crates/team-agent/src/state/identity_keys.rs +1 -0
  235. package/crates/team-agent/src/state/mod.rs +2 -0
  236. package/crates/team-agent/src/state/owner_gate.rs +5 -0
  237. package/crates/team-agent/src/state/ownership.rs +10 -4
  238. package/crates/team-agent/src/state/paths.rs +12 -0
  239. package/crates/team-agent/src/state/persist.rs +9 -3
  240. package/crates/team-agent/src/state/projection.rs +15 -2
  241. package/crates/team-agent/src/state/repository/intent.rs +1 -0
  242. package/crates/team-agent/src/state/repository/tests.rs +1 -0
  243. package/crates/team-agent/src/state/repository.rs +7 -0
  244. package/crates/team-agent/src/state/selector.rs +1 -0
  245. package/crates/team-agent/src/tmux_backend/tests.rs +39 -0
  246. package/crates/team-agent/src/tmux_backend.rs +63 -0
  247. package/crates/team-agent/src/transport.rs +15 -0
  248. package/package.json +4 -4
  249. package/crates/team-agent/src/leader/inject.rs +0 -33
  250. package/crates/team-agent/src/provider/command.rs +0 -80
@@ -1,3 +1,4 @@
1
+ //!
1
2
  //! Coordinator core:daemon lifecycle 宿主 + 单次 tick 编排(19 步固定顺序)+ health/start/stop。
2
3
 
3
4
  use std::collections::BTreeMap;
@@ -19,6 +20,7 @@ use super::health::{
19
20
  pid_is_running, read_coordinator_metadata, write_coordinator_metadata,
20
21
  };
21
22
  use super::runtime_observation::{self, CapturedRuntimeFact};
23
+ use super::steps::TickStepGroup;
22
24
  use super::types::{
23
25
  AgentId, CoordinatorHealthStatus, HealthReport, MetadataSource, Pid, ProviderRegistry,
24
26
  SchemaHealth, StartError, StartOutcome, StartReport, StopError, StopOutcome, StopReport,
@@ -225,7 +227,7 @@ impl Coordinator {
225
227
  /// `if let Some(rec) = &self.order_recorder { rec.lock()...push(STEP_NAME) }`(tick
226
228
  /// 副作用 ORDER 测试断言固定序列)。生产两者均 `None`,零开销。
227
229
  pub fn tick(&self) -> Result<TickReport, TickError> {
228
- self.record_step("load_state");
230
+ self.record_step(TickStepGroup::SessionGate, "load_state");
229
231
  let raw_state = crate::state::persist::load_runtime_state(self.workspace.as_path())?;
230
232
  // Issue 2 (Round 3b gate review §6): when the runtime carries
231
233
  // `active_team_key` AND `teams.<key>` exists, project the team-scoped
@@ -246,7 +248,7 @@ impl Coordinator {
246
248
  let event_log = EventLog::new(self.workspace.as_path());
247
249
  increment_coordinator_tick_iteration_count(&self.workspace);
248
250
 
249
- self.record_step("tmux_session_gate");
251
+ self.record_step(TickStepGroup::SessionGate, "tmux_session_gate");
250
252
  if let Some(session_name) = state
251
253
  .get("session_name")
252
254
  .and_then(Value::as_str)
@@ -268,7 +270,7 @@ impl Coordinator {
268
270
  }
269
271
  }
270
272
 
271
- self.record_step("capture_missing");
273
+ self.record_step(TickStepGroup::SessionGate, "capture_missing");
272
274
  let pending_context_fork_audits =
273
275
  match self.capture_missing_sessions(&mut state, &event_log) {
274
276
  Ok(audits) => audits,
@@ -293,10 +295,10 @@ impl Coordinator {
293
295
  .unwrap_or_default();
294
296
  let has_work_obligation = tick_has_work_obligation(&store);
295
297
 
296
- self.record_step("refresh_statuses");
298
+ self.record_step(TickStepGroup::HealthSync, "refresh_statuses");
297
299
  // TODO(spine slice 2b): split lightweight runtime status refresh from health sync.
298
300
 
299
- self.record_step("startup_prompts");
301
+ self.record_step(TickStepGroup::RuntimePrompts, "startup_prompts");
300
302
  self.handle_startup_prompts(&mut state, &event_log, &pane_snapshot, &window_snapshot);
301
303
 
302
304
  // #229 step2-retry: once an agent's `startup_prompts` flipped to `handled`
@@ -318,7 +320,7 @@ impl Coordinator {
318
320
  // 否则 deliver_pending(下行投递主干)够不到,消息卡 accepted。
319
321
  // bug-084 哲学 + A-6 同族:每步独立 try,失败写 `coordinator.tick.<step>_failed`
320
322
  // 事件后继续走下一步;tick 本身仍返 Ok。
321
- self.record_step("runtime_prompts");
323
+ self.record_step(TickStepGroup::RuntimePrompts, "runtime_prompts");
322
324
  if let Err(error) = self.handle_runtime_approval_prompts(
323
325
  &mut state,
324
326
  &event_log,
@@ -331,7 +333,7 @@ impl Coordinator {
331
333
  );
332
334
  }
333
335
 
334
- self.record_step("sync_health");
336
+ self.record_step(TickStepGroup::HealthSync, "sync_health");
335
337
  // P5 (C-P5-1, N3): ONE pane snapshot per tick, shared by sync_health and the
336
338
  // abnormal-exit pass (same-tick reuse only — the snapshot does not outlive
337
339
  // this tick; every tick re-reads).
@@ -365,7 +367,7 @@ impl Coordinator {
365
367
  );
366
368
  }
367
369
 
368
- self.record_step("deliver_pending");
370
+ self.record_step(TickStepGroup::Delivery, "deliver_pending");
369
371
  let delivered = crate::messaging::deliver_pending_messages(
370
372
  self.workspace.as_path(),
371
373
  &state,
@@ -376,7 +378,7 @@ impl Coordinator {
376
378
  .map(|message_id| DeliveredMessage { message_id })
377
379
  .collect::<Vec<_>>();
378
380
 
379
- self.record_step("fire_scheduled");
381
+ self.record_step(TickStepGroup::Delivery, "fire_scheduled");
380
382
  let scheduled = crate::messaging::fire_due_scheduled_events(
381
383
  self.workspace.as_path(),
382
384
  &store,
@@ -394,18 +396,18 @@ impl Coordinator {
394
396
  // (deliver_pending / fire_scheduled / collect_results) above and below this
395
397
  // block continue to flow unchanged. `_state` / `_store` here are intentionally
396
398
  // unused (the lookups they powered were nag inputs only).
397
- self.record_step("detect_stuck");
399
+ self.record_step(TickStepGroup::Abnormal, "detect_stuck");
398
400
  let stuck: Vec<AgentId> = Vec::new();
399
- self.record_step("record_unknown_idle");
400
- self.record_step("evaluate_takeover");
401
+ self.record_step(TickStepGroup::Abnormal, "record_unknown_idle");
402
+ self.record_step(TickStepGroup::Abnormal, "evaluate_takeover");
401
403
  let idle_alerts: Vec<IdleAlert> = Vec::new();
402
- self.record_step("detect_deadlocks");
404
+ self.record_step(TickStepGroup::Abnormal, "detect_deadlocks");
403
405
  let deadlock_alerts: Vec<DeadlockAlert> = Vec::new();
404
406
  let _ = &store;
405
407
 
406
- self.record_step("detect_compaction");
407
- self.record_step("detect_drift");
408
- self.record_step("detect_api_errors");
408
+ self.record_step(TickStepGroup::Abnormal, "detect_compaction");
409
+ self.record_step(TickStepGroup::Abnormal, "detect_drift");
410
+ self.record_step(TickStepGroup::Abnormal, "detect_api_errors");
409
411
  let leader_capture = self.capture_leader_receiver(&state);
410
412
  let observations = runtime_observation::observe(
411
413
  self.workspace.as_path(),
@@ -425,7 +427,7 @@ impl Coordinator {
425
427
  results: Vec::new(),
426
428
  };
427
429
 
428
- self.record_step("atomic_save");
430
+ self.record_step(TickStepGroup::Persist, "atomic_save");
429
431
  let saved = match &self.save_hook {
430
432
  Some(hook) => hook(&self.workspace, &state),
431
433
  None => {
@@ -474,20 +476,20 @@ impl Coordinator {
474
476
  // step, and drives the lifecycle helper. Runs OUTSIDE the pre-save
475
477
  // window so nested lifecycle saves cannot be clobbered by this
476
478
  // tick's final in-memory save (R6 boundary guard).
477
- self.record_step("attempt_api_error_recoveries");
479
+ self.record_step(TickStepGroup::Abnormal, "attempt_api_error_recoveries");
478
480
  crate::coordinator::steps::abnormal::attempt_due_recoveries(
479
481
  self.workspace.as_path(),
480
482
  &event_log,
481
483
  self.transport.as_ref(),
482
484
  );
483
485
 
484
- self.record_step("collect_results");
486
+ self.record_step(TickStepGroup::Delivery, "collect_results");
485
487
  collections.results =
486
488
  collect_results(crate::messaging::collect_results_and_notify_watchers(
487
489
  self.workspace.as_path(),
488
490
  &event_log,
489
491
  )?);
490
- self.record_step("prune_dedupe_log");
492
+ self.record_step(TickStepGroup::Persist, "prune_dedupe_log");
491
493
  Ok(base_tick_report(true, false, None, Some(true), collections))
492
494
  }
493
495
 
@@ -1430,7 +1432,8 @@ impl Coordinator {
1430
1432
  super::health::message_store_schema_health(&self.workspace)
1431
1433
  }
1432
1434
 
1433
- fn record_step(&self, step: &'static str) {
1435
+ fn record_step(&self, group: TickStepGroup, step: &'static str) {
1436
+ debug_assert!(TickStepGroup::ordered().contains(&group));
1434
1437
  if let Some(recorder) = &self.order_recorder {
1435
1438
  if let Ok(mut guard) = recorder.lock() {
1436
1439
  guard.push(step);
@@ -2757,13 +2760,6 @@ mod u1_tests {
2757
2760
  ),
2758
2761
  )
2759
2762
  }
2760
-
2761
- fn error_lists(
2762
- &self,
2763
- _provider: crate::provider::Provider,
2764
- ) -> super::super::types::ErrorLists {
2765
- super::super::types::ErrorLists::default()
2766
- }
2767
2763
  }
2768
2764
 
2769
2765
  #[test]
@@ -1,5 +1,5 @@
1
1
  //! coordinator 共享数据面:常量 / newtype / 穷尽 enum / metadata / schema health /
2
- //! report 结构 / CoordinatorEvent / abnormal-track 数据型 / WatchCursor / cross-dep 占位。
2
+ //! report 结构 / abnormal-track 数据型 / WatchCursor / cross-dep 占位。
3
3
 
4
4
  use std::collections::BTreeSet;
5
5
  use std::path::{Path, PathBuf};
@@ -9,11 +9,10 @@ use serde_json::Value;
9
9
  use thiserror::Error;
10
10
 
11
11
  // ── REUSE — committed model types(不重定义)──────────────────────────────────
12
- use crate::model::enums::{AuthMode, Provider};
13
- // AuthMode/PaneLiveness 经 provider/transport 间接复用;此处只点名直接用到的。
12
+ use crate::model::enums::Provider;
14
13
 
15
14
  // ── REUSE — step 8 provider(经 trait,MUST-NOT-13:绝不依赖 provider client crate)──
16
- use crate::provider::{ProcessLiveness, ProviderAdapter, RolloutPath, TurnId, TurnState};
15
+ use crate::provider::{ProviderAdapter, RolloutPath, TurnState};
17
16
 
18
17
  // ===========================================================================
19
18
  // CONSTANTS(metadata.py:13 / __main__.py:101)
@@ -354,137 +353,10 @@ pub struct StopReport {
354
353
  pub pid: Option<Pid>,
355
354
  }
356
355
 
357
- // ===========================================================================
358
- // CoordinatorEvent(§3/§22:typed event enum,serde tag 与 Python 字节级一致)
359
- // ===========================================================================
360
-
361
- /// 本 step 发出的事件(card 表整列;事件名稳定契约由 step 4 EventLog 拥有,本卡只点名
362
- /// coordinator 发的那批)。serde `tag = "event"` + 精确 rename 锁死字节(与 events.jsonl 一致)。
363
- /// 渲染(`watch::render_event_line`)是它的 `Display` 投影。
364
- #[derive(Debug, Clone, PartialEq, Serialize, Deserialize)] // 无 Eq:某变体含 f64
365
- #[serde(tag = "event")]
366
- pub enum CoordinatorEvent {
367
- #[serde(rename = "coordinator.boot")]
368
- Boot { workspace: String, once: bool },
369
- #[serde(rename = "coordinator.started")]
370
- Started { pid: Pid, log: String },
371
- #[serde(rename = "coordinator.stopped")]
372
- Stopped { pid: Pid },
373
- #[serde(rename = "coordinator.exit")]
374
- Exit { stop: bool },
375
- #[serde(rename = "coordinator.session_missing")]
376
- SessionMissing { session: String },
377
- #[serde(rename = "coordinator.orphan_self_terminate")]
378
- OrphanSelfTerminate {
379
- initial_ppid: u32,
380
- current_ppid: u32,
381
- workspace: String,
382
- },
383
- #[serde(rename = "coordinator.tick_error")]
384
- TickError {
385
- error: String,
386
- exc_type: String,
387
- consecutive_failures: u32,
388
- next_sleep_sec: f64,
389
- },
390
- #[serde(rename = "coordinator.tick_error.suppressed")]
391
- TickErrorSuppressed {
392
- consecutive_failures: u32,
393
- next_sleep_sec: f64,
394
- },
395
- #[serde(rename = "coordinator.tick_recovered")]
396
- TickRecovered { consecutive_failures: u32 },
397
- #[serde(rename = "coordinator.restart_incompatible")]
398
- RestartIncompatible {
399
- pid: Option<Pid>,
400
- expected_protocol: u32,
401
- expected_schema: i64,
402
- },
403
- #[serde(rename = "coordinator.restart_incompatible_stop_failed")]
404
- RestartIncompatibleStopFailed { pid: Option<Pid> },
405
- #[serde(rename = "coordinator.schema_incompatible")]
406
- SchemaIncompatible {
407
- table: Option<String>,
408
- missing_columns: Vec<String>,
409
- },
410
- #[serde(rename = "idle_takeover.unknown_persistent")]
411
- IdleTakeoverUnknownPersistent {
412
- node_id: String,
413
- provider: Option<Provider>,
414
- auth_mode: Option<AuthMode>,
415
- consecutive_ticks: u32,
416
- rollout_path: Option<RolloutPath>,
417
- },
418
- #[serde(rename = "abnormal.notify")]
419
- AbnormalNotify {
420
- signature: String,
421
- turn_id: Option<TurnId>,
422
- decision: AbnormalDecision,
423
- },
424
- #[serde(rename = "worker.abnormal_exit")]
425
- WorkerAbnormalExit {
426
- team_id: String,
427
- agent_id: String,
428
- provider: Provider,
429
- path: String,
430
- provider_process_dead: bool,
431
- latest_explicit_error: bool,
432
- signature: String,
433
- turn_id: Option<TurnId>,
434
- process_liveness: ProcessLiveness,
435
- },
436
- #[serde(rename = "worker.abnormal_exit.check")]
437
- WorkerAbnormalExitCheck {
438
- team_id: String,
439
- agent_id: String,
440
- provider: Provider,
441
- path: String,
442
- provider_process_dead: bool,
443
- latest_explicit_error: bool,
444
- notification: bool,
445
- suppressed_reason: Option<String>,
446
- },
447
- #[serde(rename = "abnormal_exit.single_signal_suppressed")]
448
- AbnormalExitSingleSignalSuppressed {
449
- team_id: String,
450
- agent_id: String,
451
- provider: Provider,
452
- path: String,
453
- reason: String,
454
- provider_process_dead: bool,
455
- dead_process: bool,
456
- latest_explicit_error: bool,
457
- },
458
- #[serde(rename = "abnormal.whole_team_gone")]
459
- AbnormalWholeTeamGone { classification: WholeTeamGoneClass },
460
- #[serde(rename = "leader_notification.log_pruned")]
461
- LeaderNotificationLogPruned { removed: u64 },
462
- #[serde(rename = "leader_notification.prune_failed")]
463
- LeaderNotificationPruneFailed { error: String },
464
- #[serde(rename = "runtime.state.save_failed")]
465
- RuntimeStateSaveFailed {
466
- phase: String,
467
- error: String,
468
- exc_type: String,
469
- },
470
- }
471
-
472
356
  // ===========================================================================
473
357
  // 异常轨 abnormal_track(abnormal_track.py)—— provider-neutral 数据型
474
358
  // ===========================================================================
475
359
 
476
- /// `_classify` 决策(`abnormal_track.py:198-204`)。whitelist > blacklist > default(C9 catch-bias)。
477
- #[derive(Debug, Clone, Copy, PartialEq, Eq, Hash, Serialize, Deserialize)]
478
- #[serde(rename_all = "snake_case")]
479
- pub enum AbnormalDecision {
480
- /// whitelist 命中 → 不通知(`abnormal_track.py:201`)。
481
- Skip,
482
- /// blacklist 命中 → 通知(`abnormal_track.py:203`)。
483
- NotifyBlacklist,
484
- /// 结构化 fault 默认通知(C9 catch-bias,`abnormal_track.py:204`)。
485
- NotifyDefault,
486
- }
487
-
488
360
  /// `detect_whole_team_gone` 分类(`abnormal_track.py:130/132/143`)。
489
361
  #[derive(Debug, Clone, Copy, PartialEq, Eq, Hash, Serialize, Deserialize)]
490
362
  #[serde(rename_all = "snake_case")]
@@ -498,35 +370,6 @@ pub enum WholeTeamGoneClass {
498
370
  UnexpectedExit,
499
371
  }
500
372
 
501
- /// `process_abnormal_records` 单条通知(`abnormal_track.py:70-79`)。
502
- /// dedup key = `(signature, turn_id|fingerprint)`(C8,`abnormal_track.py:64-66`):turn_id 缺失退化为
503
- /// per-record content fingerprint 桶,**绝不**把不同 fault 折叠进一个全局桶。
504
- #[derive(Debug, Clone, PartialEq, Eq)]
505
- pub struct AbnormalNotification {
506
- pub signature: String,
507
- pub turn_id: Option<TurnId>,
508
- /// `kind == "approval"` → blocked_on_human,否则 abnormal(`abnormal_track.py:74`)。
509
- pub state: TurnState,
510
- pub decision: AbnormalDecision,
511
- pub provider: Option<Provider>,
512
- /// 原始 fault fact(provider reader 产出的结构化记录;本 module 不读屏不命名 provider)。
513
- pub raw: Value,
514
- }
515
-
516
- /// `process_abnormal_records` 返回(`abnormal_track.py:83-88` typed 版)。
517
- #[derive(Debug, Clone, PartialEq, Eq)]
518
- pub struct AbnormalProcessOutput {
519
- pub notifications: Vec<AbnormalNotification>,
520
- /// 更新后的去重状态(`seen` 集合,`abnormal_track.py:82`)——caller 回存。
521
- pub notification_state: AbnormalNotificationState,
522
- }
523
-
524
- /// abnormal 去重状态(`abnormal_track.py:31-32,82`)。`seen` = `signature\0bucket` key 集合。
525
- #[derive(Debug, Clone, Default, PartialEq, Eq, Serialize, Deserialize)]
526
- pub struct AbnormalNotificationState {
527
- pub seen: BTreeSet<String>,
528
- }
529
-
530
373
  /// `detect_whole_team_gone` 返回(`abnormal_track.py:140-147` typed 版)。
531
374
  #[derive(Debug, Clone, PartialEq, Eq)]
532
375
  pub struct WholeTeamGoneReport {
@@ -551,13 +394,6 @@ pub struct TeamPresenceSnapshot {
551
394
  pub restart_in_progress: bool,
552
395
  }
553
396
 
554
- /// abnormal track 错误(provider reader 翻译 fault facts 失败)。
555
- #[derive(Debug, Error)]
556
- pub enum AbnormalError {
557
- #[error("provider: {0}")]
558
- Provider(#[from] crate::provider::ProviderError),
559
- }
560
-
561
397
  // ===========================================================================
562
398
  // WatchCursor(watch/__init__.py)
563
399
  // ===========================================================================
@@ -591,15 +427,6 @@ pub use crate::model::ids::AgentId;
591
427
  pub trait ProviderRegistry {
592
428
  /// 拿某 provider 的 adapter(`providers.get_adapter`)。
593
429
  fn adapter_for(&self, provider: Provider) -> Box<dyn ProviderAdapter>;
594
- /// 该 provider 的 error 黑白名单(`get_provider_registry(provider)["error_lists"]`,abnormal_track 用)。
595
- fn error_lists(&self, provider: Provider) -> ErrorLists;
596
- }
597
-
598
- /// provider error 黑白名单(`abnormal_track.py:184-195`)。**PLACEHOLDER**(step 8 拥有)。
599
- #[derive(Debug, Clone, Default, PartialEq, Eq)]
600
- pub struct ErrorLists {
601
- pub whitelist: Vec<String>,
602
- pub blacklist: Vec<String>,
603
430
  }
604
431
 
605
432
  /// idle take-over 候选 node(`idle_takeover_wiring.build_idle_nodes`,step 8/11 拥有真名)。
@@ -1,3 +1,4 @@
1
+ //!
1
2
  //! Phase-DX E2: `agent_health` row capture/restore for the remove-agent flow.
2
3
  //!
3
4
  //! Extracted from `lifecycle/restart/remove.rs` so the SQL column reference to
@@ -4,6 +4,7 @@
4
4
  // physical relocation (zero behavior change).
5
5
  #![allow(clippy::unwrap_used, clippy::expect_used, clippy::panic)]
6
6
 
7
+ //!
7
8
  //! step 7 · message_store — core message lifecycle over `team.db`.
8
9
  //!
9
10
  //! Truth source (READ-ONLY): `team-agent-public` @ v0.2.11,
@@ -205,7 +206,7 @@ pub struct PersistMessageInput<'a> {
205
206
 
206
207
  /// `leader_notification_log._legacy_epoch_from_uuid` (line 145-147):
207
208
  /// `int(zlib.crc32(str(uuid or "").encode("utf-8")) & 0x7FFFFFFF)`.
208
- pub fn legacy_epoch_from_uuid(leader_session_uuid: Option<&str>) -> i64 {
209
+ fn legacy_epoch_from_uuid(leader_session_uuid: Option<&str>) -> i64 {
209
210
  let mut crc = 0xFFFF_FFFFu32;
210
211
  for byte in leader_session_uuid.unwrap_or("").as_bytes() {
211
212
  crc ^= u32::from(*byte);
@@ -1,3 +1,4 @@
1
+ //!
1
2
  //! `team.db` 列布局迁移(Gap 46;真相源 `message_store/schema_migration.py`)。
2
3
  //!
3
4
  //! 检测**物理列序漂移**(`pragma table_info` 顺序 vs canonical),在**一个原子事务**
@@ -141,7 +142,7 @@ fn create_table_ddl(table: &str, name: &str) -> Option<String> {
141
142
 
142
143
  /// 一张表的布局 diff。
143
144
  #[derive(Debug, Clone)]
144
- pub struct Diff {
145
+ struct Diff {
145
146
  pub table: &'static str,
146
147
  pub expected: Vec<&'static str>,
147
148
  pub actual: Vec<String>,
@@ -187,7 +188,7 @@ fn table_count(conn: &Connection, table: &str) -> Result<i64, DbError> {
187
188
  Ok(conn.query_row(&format!("select count(*) from {table}"), [], |r| r.get(0))?)
188
189
  }
189
190
 
190
- pub fn pragma_user_version(conn: &Connection) -> Result<i64, DbError> {
191
+ fn pragma_user_version(conn: &Connection) -> Result<i64, DbError> {
191
192
  Ok(conn.query_row("pragma user_version", [], |r| r.get(0))?)
192
193
  }
193
194
 
@@ -230,7 +231,7 @@ fn run_version_migrations(conn: &Connection, schema_version: i64) -> Result<(),
230
231
 
231
232
  /// `schema_migration.py:_layout_diffs`:按 `table_info` 物理列序检测漂移。
232
233
  /// 无任何 managed 表存在(fresh DB)→ 空(initialize 随后建表)。
233
- pub fn layout_diffs(conn: &Connection) -> Result<Vec<Diff>, DbError> {
234
+ fn layout_diffs(conn: &Connection) -> Result<Vec<Diff>, DbError> {
234
235
  let mut any = false;
235
236
  for (t, _) in MANAGED_TABLE_LAYOUTS {
236
237
  if table_exists(conn, t)? {
@@ -419,7 +420,7 @@ pub fn ensure_table_layout(
419
420
  }
420
421
 
421
422
  /// `schema_migration.py:schema_diagnosis`:只读判定(不变更 DB)。
422
- pub fn schema_diagnosis(db_path: &Path, schema_version: i64) -> Result<Diagnosis, DbError> {
423
+ fn schema_diagnosis(db_path: &Path, schema_version: i64) -> Result<Diagnosis, DbError> {
423
424
  if !db_path.exists() {
424
425
  // T3-3 cr verdict (A parity lock, 2026-06-10): a missing db is the LEGAL
425
426
  // first-use state — ok:true is layered with the explicit status axis and the
@@ -1,3 +1,4 @@
1
+ //!
1
2
  //! step 3 · db — `team.db`(SQLite)的 schema 与迁移层(真相源 `message_store/schema*.py`)。
2
3
  //!
3
4
  //! §6 step 3:schema/migrations/indexes/WAL+busy-timeout/只读兼容。**消息操作本身(send/
@@ -1,3 +1,4 @@
1
+ //!
1
2
  //! `team.db` schema 初始化(真相源 `message_store/schema.py` + `schema_migration.py`)。
2
3
  //!
3
4
  //! slice 1:fresh DB schema —— 8 表 DDL、6 索引、ALTER 式列迁移、agent_health 重建、
@@ -1,3 +1,4 @@
1
+
1
2
  use std::path::Path;
2
3
 
3
4
  use serde_json::{json, Value};
@@ -212,7 +213,7 @@ fn verifies_json(check: &SelftestCheck) -> Value {
212
213
  serde_json::to_value(check.verifies).unwrap_or_else(|_| json!("unknown"))
213
214
  }
214
215
 
215
- pub fn receiver_binding_mismatches(
216
+ fn receiver_binding_mismatches(
216
217
  owner_pane_id: &Value,
217
218
  caller_pane_id: &Value,
218
219
  pane_id: &Value,
@@ -1,3 +1,4 @@
1
+ //!
1
2
  //! Shared doctor gate seams.
2
3
 
3
4
  use std::path::Path;
@@ -1,3 +1,4 @@
1
+
1
2
  use std::collections::{BTreeMap, BTreeSet};
2
3
  use std::path::{Path, PathBuf};
3
4
  use std::process::Command;
@@ -1,3 +1,4 @@
1
+ //!
1
2
  //! 0.3.28 layout step 2 — leader placement.
2
3
  //!
3
4
  //! Public API for managed-mode leader placement. The runtime calls
@@ -34,6 +35,7 @@ pub enum LeaderPlacement {
34
35
  },
35
36
  }
36
37
 
38
+ ///
37
39
  /// Compute the placement for a leader given its identity, the desired
38
40
  /// `LeaderStartMode`, and the environment (used to detect `$TMUX`).
39
41
  ///
@@ -58,13 +60,6 @@ pub fn leader_placement(
58
60
  }
59
61
  }
60
62
 
61
- /// The leader session name for a given provider + workspace. `LeaderIdentity`
62
- /// in this codebase does not carry the provider field; the caller supplies it
63
- /// explicitly (matches how `leader_session_name` itself is shaped).
64
- pub fn leader_session_for_provider(provider: Provider, workspace: &Path) -> SessionName {
65
- leader_session_name(provider, workspace)
66
- }
67
-
68
63
  #[allow(dead_code)]
69
64
  fn _unused_identity_marker(_id: &LeaderIdentity) {}
70
65
 
@@ -74,6 +69,7 @@ use crate::layout::placement::{WorkerSpawnAction, WorkerSpawnTarget};
74
69
  use crate::model::yaml::Value as YamlValue;
75
70
  use crate::transport::Transport;
76
71
 
72
+ ///
77
73
  /// Compute the spawn target for a worker. Python parity: one window per
78
74
  /// agent in the worker session, named after `agent_id`. First worker
79
75
  /// (= session does not yet exist) → NewSession; otherwise NewWindow.
@@ -1,3 +1,4 @@
1
+ //!
1
2
  //! 0.3.28 — Unified adaptive layout manager.
2
3
  //!
3
4
  //! Single source of truth for tmux topology decisions in the runtime:
@@ -31,6 +32,5 @@ pub mod worker_env;
31
32
  pub mod worker_window_helpers;
32
33
 
33
34
  pub use runtime_sessions::{
34
- LeaderLauncherSession, LeaderLauncherSessionError, RuntimeSessionAnomaly, RuntimeSessions,
35
- WorkerSession, WorkerSessionError,
35
+ LeaderLauncherSession, RuntimeSessionAnomaly, RuntimeSessions, WorkerSession,
36
36
  };
@@ -1,3 +1,4 @@
1
+ //!
1
2
  //! 0.3.28 layout step 8 — display overlay (3-pane tiling).
2
3
  //!
3
4
  //! Python truth source: 3-pane tiling exists ONLY in the display overlay
@@ -15,6 +16,7 @@ use crate::transport::{SessionName, WindowName};
15
16
  /// 3 panes per overlay window — Python parity.
16
17
  pub const OVERLAY_PANES_PER_WINDOW: usize = 3;
17
18
 
19
+ ///
18
20
  /// Overlay window name for a 0-based group index. Index 0 → `overview`;
19
21
  /// N ≥ 1 → `overview-{N+1}`. Names are scoped by `session_tag` so multiple
20
22
  /// teams can coexist on one leader session.
@@ -38,6 +40,7 @@ pub struct OverlayPlacement {
38
40
  pub window: WindowName,
39
41
  }
40
42
 
43
+ ///
41
44
  /// Compute the overlay placements for a list of agent_ids. Deterministic by
42
45
  /// input order: agent `i` → window `i / 3`, slot `i % 3`.
43
46
  pub fn plan_overlay_placements(session_tag: &str, agents: &[&str]) -> Vec<OverlayPlacement> {
@@ -53,9 +56,10 @@ pub fn plan_overlay_placements(session_tag: &str, agents: &[&str]) -> Vec<Overla
53
56
  .collect()
54
57
  }
55
58
 
59
+ ///
56
60
  /// True when a window name belongs to a display overlay (matches
57
61
  /// `team-agent:<...>:overview[-N]`).
58
- pub fn is_overlay_window(name: &WindowName) -> bool {
62
+ fn is_overlay_window(name: &WindowName) -> bool {
59
63
  let n = name.as_str();
60
64
  if !n.starts_with("team-agent:") {
61
65
  return false;
@@ -63,6 +67,7 @@ pub fn is_overlay_window(name: &WindowName) -> bool {
63
67
  n.contains(":overview")
64
68
  }
65
69
 
70
+ ///
66
71
  /// 0.3.28 Step 8 invariant: `spawn_split` may ONLY be called from the
67
72
  /// overlay module. This helper emits a warn-level event when called from
68
73
  /// anywhere else (Step 9 promotes to a hard error / panic gate). The
@@ -1,3 +1,4 @@
1
+ //!
1
2
  //! 0.3.28 layout step 4 — typed worker placement target.
2
3
  //!
3
4
  //! Python parity (`runtime.py:1017-1020`): one window per agent in the
@@ -1,3 +1,4 @@
1
+ //!
1
2
  //! 0.3.28 layout step 7 — leader pane recovery.
2
3
  //!
3
4
  //! Python truth source (`leader/__init__.py:885-887` +
@@ -28,6 +29,7 @@ pub enum RecoveryOutcome {
28
29
  NeedsUserAttach,
29
30
  }
30
31
 
32
+ ///
31
33
  /// Compute the recovery outcome from the current environment.
32
34
  ///
33
35
  /// Reads `TMUX_PANE` from the supplied environment iterator (use
@@ -44,6 +46,7 @@ where
44
46
  RecoveryOutcome::NeedsUserAttach
45
47
  }
46
48
 
49
+ ///
47
50
  /// Emit the canonical `leader_receiver.rebind_required` event when the
48
51
  /// runtime falls through to `NeedsUserAttach`. Logs to stderr so operators
49
52
  /// see the cascade in event logs.
@@ -1,3 +1,4 @@
1
+ //!
1
2
  //! unit-1 (Stage 1) — typed runtime session identity.
2
3
  //!
3
4
  //! Provides two compile-time-distinct newtypes plus a `RuntimeSessions`
@@ -35,7 +36,7 @@ pub struct LeaderLauncherSession(SessionName);
35
36
 
36
37
  /// Why `WorkerSession::new` rejected a name.
37
38
  #[derive(Debug, Clone, PartialEq, Eq)]
38
- pub enum WorkerSessionError {
39
+ enum WorkerSessionError {
39
40
  /// The name is empty.
40
41
  Empty,
41
42
  /// The name carries the leader launcher prefix — must not be a worker
@@ -45,7 +46,7 @@ pub enum WorkerSessionError {
45
46
 
46
47
  /// Why `LeaderLauncherSession::new` rejected a name.
47
48
  #[derive(Debug, Clone, PartialEq, Eq)]
48
- pub enum LeaderLauncherSessionError {
49
+ enum LeaderLauncherSessionError {
49
50
  /// The name is empty.
50
51
  Empty,
51
52
  /// The name does not carry the required leader launcher prefix.
@@ -136,6 +137,7 @@ pub enum RuntimeSessionAnomaly {
136
137
  }
137
138
 
138
139
  impl RuntimeSessions {
140
+ ///
139
141
  /// Read state.json's session-identity fields and wrap them in typed
140
142
  /// values. Never panics on bad state — anomalies are surfaced for
141
143
  /// callers to act on.
@@ -197,11 +199,13 @@ impl RuntimeSessions {
197
199
  }
198
200
  }
199
201
 
202
+ ///
200
203
  /// True if any session-identity anomaly was detected in state.
201
204
  pub fn has_anomalies(&self) -> bool {
202
205
  !self.anomalies.is_empty()
203
206
  }
204
207
 
208
+ ///
205
209
  /// True if a `state.session_name` looked like a leader launcher session
206
210
  /// — the exact 0.3.39 shape unit-3 must refuse before any kill.
207
211
  pub fn worker_session_name_is_leader_prefixed(&self) -> bool {
@@ -214,9 +218,10 @@ impl RuntimeSessions {
214
218
  }
215
219
  }
216
220
 
221
+ ///
217
222
  /// True when `name` is a leader launcher session (mirrors
218
223
  /// `layout::sessions::is_leader_session` on a raw &str).
219
- pub fn name_is_leader_launcher(name: &str) -> bool {
224
+ fn name_is_leader_launcher(name: &str) -> bool {
220
225
  let session = SessionName::new(name);
221
226
  is_leader_session(&session)
222
227
  }