@team-agent/installer 0.5.60 → 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 (265) hide show
  1. package/Cargo.lock +1 -1
  2. package/Cargo.toml +1 -1
  3. package/crates/team-agent/src/cli/adapters.rs +49 -3
  4. package/crates/team-agent/src/cli/attach_app_server_leader.rs +1 -0
  5. package/crates/team-agent/src/cli/diagnose.rs +184 -0
  6. package/crates/team-agent/src/cli/emit.rs +104 -21
  7. package/crates/team-agent/src/cli/helpers.rs +1 -0
  8. package/crates/team-agent/src/cli/leader.rs +14 -2
  9. package/crates/team-agent/src/cli/leaders.rs +2 -0
  10. package/crates/team-agent/src/cli/mod.rs +296 -8
  11. package/crates/team-agent/src/cli/named_address.rs +26 -2
  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 +3 -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 +5 -1
  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/status_port/store.rs +7 -3
  25. package/crates/team-agent/src/cli/tests/named_address.rs +65 -0
  26. package/crates/team-agent/src/cli/tests/verb_profile.rs +38 -0
  27. package/crates/team-agent/src/cli/types.rs +36 -2
  28. package/crates/team-agent/src/communication_mode/mod.rs +54 -0
  29. package/crates/team-agent/src/compiler/tests.rs +5 -5
  30. package/crates/team-agent/src/compiler.rs +54 -1
  31. package/crates/team-agent/src/conpty/backend.rs +1 -0
  32. package/crates/team-agent/src/conpty/mod.rs +1 -0
  33. package/crates/team-agent/src/coordinator/backoff.rs +5 -8
  34. package/crates/team-agent/src/coordinator/conpty_shim.rs +3 -2
  35. package/crates/team-agent/src/coordinator/health.rs +1 -0
  36. package/crates/team-agent/src/coordinator/mod.rs +2 -2
  37. package/crates/team-agent/src/coordinator/orphan.rs +4 -116
  38. package/crates/team-agent/src/coordinator/runtime_detectors.rs +1 -0
  39. package/crates/team-agent/src/coordinator/runtime_observation.rs +1 -0
  40. package/crates/team-agent/src/coordinator/steps/abnormal.rs +6 -5
  41. package/crates/team-agent/src/coordinator/steps/delivery.rs +1 -0
  42. package/crates/team-agent/src/coordinator/steps/health_sync.rs +1 -0
  43. package/crates/team-agent/src/coordinator/steps/mod.rs +2 -0
  44. package/crates/team-agent/src/coordinator/steps/persist.rs +1 -0
  45. package/crates/team-agent/src/coordinator/steps/runtime_prompts.rs +1 -0
  46. package/crates/team-agent/src/coordinator/steps/session_gate.rs +1 -0
  47. package/crates/team-agent/src/coordinator/tests/abnormal.rs +0 -174
  48. package/crates/team-agent/src/coordinator/tests/api_error_recovery.rs +0 -9
  49. package/crates/team-agent/src/coordinator/tests/basics.rs +0 -184
  50. package/crates/team-agent/src/coordinator/tests/mod.rs +2 -17
  51. package/crates/team-agent/src/coordinator/tests/tick_core.rs +0 -42
  52. package/crates/team-agent/src/coordinator/tick.rs +24 -28
  53. package/crates/team-agent/src/coordinator/types.rs +3 -176
  54. package/crates/team-agent/src/db/agent_health_capture.rs +1 -0
  55. package/crates/team-agent/src/db/message_store.rs +47 -2
  56. package/crates/team-agent/src/db/migration.rs +5 -4
  57. package/crates/team-agent/src/db/mod.rs +1 -0
  58. package/crates/team-agent/src/db/schema.rs +1 -0
  59. package/crates/team-agent/src/diagnose/comms.rs +2 -1
  60. package/crates/team-agent/src/diagnose/mod.rs +1 -0
  61. package/crates/team-agent/src/diagnose/orphans.rs +1 -0
  62. package/crates/team-agent/src/fake_worker.rs +21 -1
  63. package/crates/team-agent/src/layout/manager.rs +3 -7
  64. package/crates/team-agent/src/layout/mod.rs +2 -2
  65. package/crates/team-agent/src/layout/overlay.rs +6 -1
  66. package/crates/team-agent/src/layout/placement.rs +1 -0
  67. package/crates/team-agent/src/layout/recovery.rs +3 -0
  68. package/crates/team-agent/src/layout/runtime_sessions.rs +8 -3
  69. package/crates/team-agent/src/layout/sessions.rs +8 -1
  70. package/crates/team-agent/src/layout/tmux_endpoint.rs +3 -0
  71. package/crates/team-agent/src/layout/worker_env.rs +3 -0
  72. package/crates/team-agent/src/layout/worker_window_helpers.rs +2 -0
  73. package/crates/team-agent/src/leader/helpers.rs +1 -0
  74. package/crates/team-agent/src/leader/incident.rs +1 -0
  75. package/crates/team-agent/src/leader/lease.rs +27 -22
  76. package/crates/team-agent/src/leader/mod.rs +2 -3
  77. package/crates/team-agent/src/leader/owner_bind.rs +13 -3
  78. package/crates/team-agent/src/leader/provider_attribution.rs +1 -0
  79. package/crates/team-agent/src/leader/rediscover.rs +4 -17
  80. package/crates/team-agent/src/leader/registry.rs +3 -15
  81. package/crates/team-agent/src/leader/start.rs +1072 -186
  82. package/crates/team-agent/src/leader/takeover.rs +10 -232
  83. package/crates/team-agent/src/leader/tests/claim_leader_mailbox_flush_contract.rs +544 -0
  84. package/crates/team-agent/src/leader/tests/historical_inventory_upgrade_gate_red.rs +624 -0
  85. package/crates/team-agent/src/leader/tests/identity.rs +71 -59
  86. package/crates/team-agent/src/leader/tests/identity_session_names.rs +42 -0
  87. package/crates/team-agent/src/leader/tests/idle.rs +0 -193
  88. package/crates/team-agent/src/leader/tests/lease_api.rs +0 -45
  89. package/crates/team-agent/src/leader/tests/mod.rs +4 -41
  90. package/crates/team-agent/src/leader/tests/rehomed_env.rs +83 -0
  91. package/crates/team-agent/src/leader/tests/team_in_team_state_scope_red.rs +1273 -0
  92. package/crates/team-agent/src/leader/tests/terminal_and_replay_vs_rerender_invariants_red.rs +417 -0
  93. package/crates/team-agent/src/leader/tests/wake_start_owner.rs +22 -103
  94. package/crates/team-agent/src/leader/types.rs +1 -28
  95. package/crates/team-agent/src/lib.rs +7 -0
  96. package/crates/team-agent/src/lifecycle/display.rs +7 -1
  97. package/crates/team-agent/src/lifecycle/helpers.rs +3 -1
  98. package/crates/team-agent/src/lifecycle/launch/add_agent.rs +2 -2
  99. package/crates/team-agent/src/lifecycle/launch/fork_agent/completion.rs +1 -0
  100. package/crates/team-agent/src/lifecycle/launch/fork_agent.rs +1 -1
  101. package/crates/team-agent/src/lifecycle/launch/fork_entry.rs +1 -0
  102. package/crates/team-agent/src/lifecycle/launch/fork_finalize.rs +1 -0
  103. package/crates/team-agent/src/lifecycle/launch/plan.rs +2 -2
  104. package/crates/team-agent/src/lifecycle/launch/quick_start.rs +4 -26
  105. package/crates/team-agent/src/lifecycle/launch/readiness.rs +0 -27
  106. package/crates/team-agent/src/lifecycle/launch/spawn.rs +2 -28
  107. package/crates/team-agent/src/lifecycle/launch/spec_state.rs +4 -32
  108. package/crates/team-agent/src/lifecycle/launch/state_projection.rs +1 -0
  109. package/crates/team-agent/src/lifecycle/launch.rs +11 -12
  110. package/crates/team-agent/src/lifecycle/mod.rs +2 -1
  111. package/crates/team-agent/src/lifecycle/restart/agent.rs +4 -4
  112. package/crates/team-agent/src/lifecycle/restart/common.rs +1 -1
  113. package/crates/team-agent/src/lifecycle/restart/orchestrator.rs +2 -2
  114. package/crates/team-agent/src/lifecycle/restart/rebuild.rs +13 -5
  115. package/crates/team-agent/src/lifecycle/restart/remove.rs +1 -1
  116. package/crates/team-agent/src/lifecycle/restart/selection.rs +3 -3
  117. package/crates/team-agent/src/lifecycle/restart.rs +13 -11
  118. package/crates/team-agent/src/lifecycle/tests/acceptance_b_batch_red.rs +1007 -0
  119. package/crates/team-agent/src/lifecycle/tests/b0_legacy_snapshot_nonauthority_contract.rs +265 -0
  120. package/crates/team-agent/src/lifecycle/tests/b0_reader_hideone_audit_contract.rs +459 -0
  121. package/crates/team-agent/src/lifecycle/tests/behavioral_diff_264_red.rs +849 -0
  122. package/crates/team-agent/src/lifecycle/tests/claude_compatible_config_red.rs +323 -0
  123. package/crates/team-agent/src/lifecycle/tests/claude_profile_launch_red.rs +423 -0
  124. package/crates/team-agent/src/lifecycle/tests/clone_fork_copilot_perms_red.rs +737 -0
  125. package/crates/team-agent/src/lifecycle/tests/codex_mcp_approval_inheritance_red.rs +1187 -0
  126. package/crates/team-agent/src/lifecycle/tests/codex_weak_window_attribution_red.rs +683 -0
  127. package/crates/team-agent/src/lifecycle/tests/communication_mode_runtime_contract_red.rs +394 -0
  128. package/crates/team-agent/src/lifecycle/tests/copilot_provider_red.rs +1856 -0
  129. package/crates/team-agent/src/lifecycle/tests/core_034_real_red.rs +917 -0
  130. package/crates/team-agent/src/lifecycle/tests/display_adaptive_red.rs +481 -0
  131. package/crates/team-agent/src/lifecycle/tests/f032_startup_prompt_best_effort_red.rs +301 -0
  132. package/crates/team-agent/src/lifecycle/tests/harvest2_a_batch_red.rs +516 -0
  133. package/crates/team-agent/src/lifecycle/tests/host_cotenant_death_p0_contract.rs +986 -0
  134. package/crates/team-agent/src/lifecycle/tests/lifecycle_rollback_red.rs +651 -0
  135. package/crates/team-agent/src/lifecycle/tests/main_preserved.rs +2 -0
  136. package/crates/team-agent/src/lifecycle/tests/quick_start_worker_readiness_red.rs +332 -0
  137. package/crates/team-agent/src/lifecycle/tests/realmachine_clusters_1_6_red.rs +846 -0
  138. package/crates/team-agent/src/lifecycle/tests/realmachine_residual_g1_g4_red.rs +648 -0
  139. package/crates/team-agent/src/lifecycle/tests/restart_build_before_destroy_0540_contract.rs +910 -0
  140. package/crates/team-agent/src/lifecycle/tests/restart_liveness_red.rs +630 -0
  141. package/crates/team-agent/src/lifecycle/tests/restart_rebind_hotfix_252_red.rs +1083 -0
  142. package/crates/team-agent/src/lifecycle/tests/restart_session_capture_red.rs +1677 -0
  143. package/crates/team-agent/src/lifecycle/tests/resume_recover_red.rs +410 -0
  144. package/crates/team-agent/src/lifecycle/tests/stale_team_saveconflict_contract.rs +428 -0
  145. package/crates/team-agent/src/lifecycle/tests/startup_latency_contract.rs +1032 -0
  146. package/crates/team-agent/src/lifecycle/tests/status_credential_redaction_contract.rs +869 -0
  147. package/crates/team-agent/src/lifecycle/tests/subprep_codex_trust_roundtrip_red.rs +1249 -0
  148. package/crates/team-agent/src/lifecycle/tests/swallow_batch4_semantics_red.rs +342 -0
  149. package/crates/team-agent/src/lifecycle/tests/team_in_team_identity_scope_red.rs +542 -0
  150. package/crates/team-agent/src/lifecycle/tests/team_in_team_sibling_quick_start_red.rs +1103 -0
  151. package/crates/team-agent/src/lifecycle/tests/team_in_team_state_scope_red.rs +1276 -0
  152. package/crates/team-agent/src/lifecycle/tests/team_key_retirement_roster_red.rs +145 -0
  153. package/crates/team-agent/src/lifecycle/tests/team_key_retirement_txn_red.rs +603 -0
  154. package/crates/team-agent/src/lifecycle/tests/test_isolation_escape_contract.rs +837 -0
  155. package/crates/team-agent/src/lifecycle/tests/upgrade_compat_0211_red.rs +928 -0
  156. package/crates/team-agent/src/lifecycle/tests/verify_rs031_window_consistency_red.rs +951 -0
  157. package/crates/team-agent/src/lifecycle/tests/worker_dangerous_bypass_argv_red.rs +327 -0
  158. package/crates/team-agent/src/lifecycle/tests/worker_spawn_env_red.rs +760 -0
  159. package/crates/team-agent/src/lifecycle/tests.rs +59 -0
  160. package/crates/team-agent/src/lifecycle/types.rs +0 -9
  161. package/crates/team-agent/src/lifecycle/worker_command_context.rs +29 -11
  162. package/crates/team-agent/src/mcp_server/helpers.rs +1 -0
  163. package/crates/team-agent/src/mcp_server/lifecycle_tools/mod.rs +1 -0
  164. package/crates/team-agent/src/mcp_server/lifecycle_tools/state_status.rs +1 -0
  165. package/crates/team-agent/src/mcp_server/mod.rs +1 -0
  166. package/crates/team-agent/src/mcp_server/normalize.rs +5 -3
  167. package/crates/team-agent/src/mcp_server/tests/send.rs +26 -0
  168. package/crates/team-agent/src/mcp_server/tests/wire.rs +1 -1
  169. package/crates/team-agent/src/mcp_server/tools.rs +101 -66
  170. package/crates/team-agent/src/mcp_server/types.rs +6 -18
  171. package/crates/team-agent/src/mcp_server/wire.rs +32 -26
  172. package/crates/team-agent/src/messaging/activity.rs +1 -0
  173. package/crates/team-agent/src/messaging/address.rs +1 -0
  174. package/crates/team-agent/src/messaging/delivery.rs +109 -41
  175. package/crates/team-agent/src/messaging/helpers.rs +2 -1
  176. package/crates/team-agent/src/messaging/leader_channel.rs +34 -10
  177. package/crates/team-agent/src/messaging/leader_receiver.rs +42 -24
  178. package/crates/team-agent/src/messaging/mod.rs +10 -14
  179. package/crates/team-agent/src/messaging/peers.rs +2 -0
  180. package/crates/team-agent/src/messaging/persist.rs +3 -1
  181. package/crates/team-agent/src/messaging/presentation.rs +111 -1
  182. package/crates/team-agent/src/messaging/results.rs +166 -17
  183. package/crates/team-agent/src/messaging/scheduler.rs +1 -0
  184. package/crates/team-agent/src/messaging/selftest.rs +1 -1
  185. package/crates/team-agent/src/messaging/send.rs +135 -89
  186. package/crates/team-agent/src/messaging/tests/leader_channel.rs +6 -6
  187. package/crates/team-agent/src/messaging/tests/leader_inject_acceptance.rs +187 -0
  188. package/crates/team-agent/src/messaging/tests/mod.rs +5 -0
  189. package/crates/team-agent/src/messaging/tests/runtime.rs +13 -6
  190. package/crates/team-agent/src/messaging/types.rs +7 -2
  191. package/crates/team-agent/src/messaging/watchers.rs +24 -13
  192. package/crates/team-agent/src/model/enums.rs +1 -0
  193. package/crates/team-agent/src/model/errors.rs +1 -0
  194. package/crates/team-agent/src/model/ids.rs +1 -0
  195. package/crates/team-agent/src/model/mod.rs +2 -0
  196. package/crates/team-agent/src/model/name_similarity.rs +1 -0
  197. package/crates/team-agent/src/model/pane_authority_refusal.rs +359 -0
  198. package/crates/team-agent/src/model/paths.rs +1 -0
  199. package/crates/team-agent/src/model/permissions.rs +3 -2
  200. package/crates/team-agent/src/model/routing.rs +1 -0
  201. package/crates/team-agent/src/model/spec.rs +17 -0
  202. package/crates/team-agent/src/model/task_graph.rs +1 -0
  203. package/crates/team-agent/src/model/yaml/tests.rs +1 -0
  204. package/crates/team-agent/src/model/yaml.rs +1 -0
  205. package/crates/team-agent/src/packaging/install.rs +9 -147
  206. package/crates/team-agent/src/packaging/migrate.rs +2 -0
  207. package/crates/team-agent/src/packaging/mod.rs +1 -0
  208. package/crates/team-agent/src/packaging/repair.rs +2 -0
  209. package/crates/team-agent/src/packaging/tests.rs +29 -218
  210. package/crates/team-agent/src/packaging/types.rs +8 -15
  211. package/crates/team-agent/src/platform/argv.rs +4 -0
  212. package/crates/team-agent/src/platform/errors.rs +10 -1
  213. package/crates/team-agent/src/platform/file_lock.rs +4 -157
  214. package/crates/team-agent/src/platform/mod.rs +0 -61
  215. package/crates/team-agent/src/platform/process.rs +1 -0
  216. package/crates/team-agent/src/provider/adapter.rs +1 -0
  217. package/crates/team-agent/src/provider/adapters/claude.rs +1 -0
  218. package/crates/team-agent/src/provider/adapters/claude_fork.rs +1 -0
  219. package/crates/team-agent/src/provider/adapters/codex.rs +1 -0
  220. package/crates/team-agent/src/provider/adapters/copilot.rs +1 -0
  221. package/crates/team-agent/src/provider/adapters/copilot_fork.rs +1 -0
  222. package/crates/team-agent/src/provider/adapters/fake.rs +1 -0
  223. package/crates/team-agent/src/provider/adapters/mod.rs +1 -0
  224. package/crates/team-agent/src/provider/approvals/mod.rs +1 -0
  225. package/crates/team-agent/src/provider/approvals/parsing.rs +2 -5
  226. package/crates/team-agent/src/provider/approvals/runtime_prompts.rs +6 -5
  227. package/crates/team-agent/src/provider/classify.rs +1 -0
  228. package/crates/team-agent/src/provider/faults.rs +1 -26
  229. package/crates/team-agent/src/provider/helpers.rs +1 -0
  230. package/crates/team-agent/src/provider/mod.rs +1 -1
  231. package/crates/team-agent/src/provider/session/capture.rs +41 -22
  232. package/crates/team-agent/src/provider/session/context_fork/claude.rs +1 -0
  233. package/crates/team-agent/src/provider/session/context_fork/codex.rs +1 -0
  234. package/crates/team-agent/src/provider/session/context_fork/outcome.rs +1 -0
  235. package/crates/team-agent/src/provider/session/context_fork.rs +1 -0
  236. package/crates/team-agent/src/provider/session/mod.rs +2 -4
  237. package/crates/team-agent/src/provider/session/resume.rs +2 -209
  238. package/crates/team-agent/src/provider/session_scan/claude.rs +93 -3
  239. package/crates/team-agent/src/provider/session_scan/codex.rs +1 -0
  240. package/crates/team-agent/src/provider/session_scan/common.rs +24 -7
  241. package/crates/team-agent/src/provider/session_scan/copilot.rs +1 -0
  242. package/crates/team-agent/src/provider/session_scan.rs +6 -42
  243. package/crates/team-agent/src/provider/startup_prompt.rs +1 -0
  244. package/crates/team-agent/src/provider/types.rs +1 -0
  245. package/crates/team-agent/src/provider/wire.rs +1 -0
  246. package/crates/team-agent/src/state/identity.rs +16 -5
  247. package/crates/team-agent/src/state/identity_keys.rs +1 -0
  248. package/crates/team-agent/src/state/mod.rs +2 -0
  249. package/crates/team-agent/src/state/owner_gate.rs +5 -0
  250. package/crates/team-agent/src/state/ownership.rs +10 -4
  251. package/crates/team-agent/src/state/paths.rs +12 -0
  252. package/crates/team-agent/src/state/persist.rs +9 -3
  253. package/crates/team-agent/src/state/projection.rs +15 -2
  254. package/crates/team-agent/src/state/repository/intent.rs +1 -0
  255. package/crates/team-agent/src/state/repository/tests.rs +1 -0
  256. package/crates/team-agent/src/state/repository.rs +7 -0
  257. package/crates/team-agent/src/state/selector.rs +1 -0
  258. package/crates/team-agent/src/tmux_backend/tests.rs +39 -0
  259. package/crates/team-agent/src/tmux_backend.rs +63 -0
  260. package/crates/team-agent/src/topology.rs +3 -0
  261. package/crates/team-agent/src/transport.rs +15 -0
  262. package/package.json +4 -4
  263. package/skills/team-agent/command-coverage.json +379 -0
  264. package/crates/team-agent/src/leader/inject.rs +0 -33
  265. package/crates/team-agent/src/provider/command.rs +0 -80
@@ -1,3 +1,4 @@
1
+ //!
1
2
  //! Cross-platform exclusive file lock primitive.
2
3
  //!
3
4
  //! ## Batch 2 real implementation (leader msg_c833639b61b8)
@@ -26,12 +27,6 @@
26
27
  //! 2. `unlock(&File)` — release the lock. Called from `Drop` in both
27
28
  //! caller sites.
28
29
  //!
29
- //! A high-level `try_lock_exclusive(path, timeout) -> FileLockGuard`
30
- //! wrapper is also provided (uses the same primitives + a bare polling
31
- //! loop) for future callers that don't need the metadata/waiter
32
- //! machinery — but the two existing product callers keep their own
33
- //! loops per this batch's byte-preserving constraint.
34
- //!
35
30
  //! ## Windows implementation
36
31
  //!
37
32
  //! Windows implementation uses `LockFileEx` /
@@ -54,9 +49,8 @@
54
49
 
55
50
  use std::fs::File;
56
51
  use std::io;
57
- use std::path::Path;
58
- use std::time::Duration;
59
52
 
53
+ ///
60
54
  /// Try to acquire an exclusive advisory lock on `file` without
61
55
  /// blocking. Returns `Ok(true)` if the lock was acquired, `Ok(false)`
62
56
  /// if the file is already locked by someone else, `Err(...)` on real
@@ -86,6 +80,7 @@ pub fn try_lock_once_nonblocking(file: &File) -> io::Result<bool> {
86
80
  }
87
81
  }
88
82
 
83
+ ///
89
84
  /// Release the exclusive lock held on `file`. Called from `Drop` in
90
85
  /// caller code so the release runs even on panic.
91
86
  ///
@@ -204,100 +199,7 @@ fn unlock_windows(file: &File) -> io::Result<()> {
204
199
  }
205
200
 
206
201
  // ─────────────────────────────────────────────────────────────────────
207
- // High-level convenience wrapper.
208
- // ─────────────────────────────────────────────────────────────────────
209
-
210
- /// Owns the underlying `File` handle + platform lock. `Drop` unlocks
211
- /// via `unlock(&file)`.
212
- ///
213
- /// Callers that don't need the lifecycle-lock metadata/waiter/held_long
214
- /// event machinery can use `try_lock_exclusive(path, timeout)` directly.
215
- /// The existing product callers (`state/persist.rs`, `lifecycle/lock.rs`)
216
- /// use `try_lock_once_nonblocking` + `unlock` directly and keep their
217
- /// own polling loops for byte-preserving behavior.
218
- pub struct FileLockGuard {
219
- file: Option<File>,
220
- }
221
-
222
- impl std::fmt::Debug for FileLockGuard {
223
- fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
224
- f.debug_struct("FileLockGuard")
225
- .field("held", &self.file.is_some())
226
- .finish()
227
- }
228
- }
229
-
230
- impl FileLockGuard {
231
- /// Test-only accessor for the wrapped file handle.
232
- #[cfg(test)]
233
- fn file(&self) -> &File {
234
- self.file.as_ref().expect("file present until Drop")
235
- }
236
- }
237
-
238
- impl Drop for FileLockGuard {
239
- fn drop(&mut self) {
240
- if let Some(file) = self.file.take() {
241
- // Best-effort unlock. If it fails the OS still releases on
242
- // handle close.
243
- let _ = unlock(&file);
244
- }
245
- }
246
- }
247
-
248
- #[derive(Debug, thiserror::Error)]
249
- pub enum LockError {
250
- #[error("file lock timeout after {timeout_secs:.2}s on {path}")]
251
- Timeout { timeout_secs: f64, path: String },
252
- #[error("file lock io error on {path}: {source}")]
253
- Io {
254
- path: String,
255
- #[source]
256
- source: io::Error,
257
- },
258
- }
259
-
260
- /// High-level: acquire an exclusive lock on `path` within `timeout`,
261
- /// polling every 50ms. Returns a guard that unlocks on `Drop`.
262
- ///
263
- /// Existing product callers do NOT use this — they need their own
264
- /// metadata/waiter/held_long event machinery. This wrapper exists for
265
- /// simple future callers.
266
- pub fn try_lock_exclusive(path: &Path, timeout: Duration) -> Result<FileLockGuard, LockError> {
267
- let file = File::options()
268
- .read(true)
269
- .write(true)
270
- .create(true)
271
- .truncate(false)
272
- .open(path)
273
- .map_err(|e| LockError::Io {
274
- path: path.display().to_string(),
275
- source: e,
276
- })?;
277
- let start = std::time::Instant::now();
278
- loop {
279
- match try_lock_once_nonblocking(&file) {
280
- Ok(true) => return Ok(FileLockGuard { file: Some(file) }),
281
- Ok(false) => {}
282
- Err(e) => {
283
- return Err(LockError::Io {
284
- path: path.display().to_string(),
285
- source: e,
286
- });
287
- }
288
- }
289
- if start.elapsed() >= timeout {
290
- return Err(LockError::Timeout {
291
- timeout_secs: timeout.as_secs_f64(),
292
- path: path.display().to_string(),
293
- });
294
- }
295
- std::thread::sleep(Duration::from_millis(50));
296
- }
297
- }
298
-
299
- // ─────────────────────────────────────────────────────────────────────
300
- // Tests: primitive + convenience wrapper on the host platform.
202
+ // Tests: primitives on the host platform.
301
203
  // Both branches (unix + windows) exercise the same trait shape via
302
204
  // the top-level `try_lock_once_nonblocking` / `unlock` functions —
303
205
  // the test source is cfg-free.
@@ -334,24 +236,6 @@ mod tests {
334
236
  let _ = std::fs::remove_file(&path);
335
237
  }
336
238
 
337
- #[test]
338
- fn convenience_try_lock_exclusive_acquires_and_drop_releases() {
339
- // The high-level convenience wrapper is what future callers
340
- // will use. Verify the drop-releases-lock invariant.
341
- let dir = std::env::temp_dir().join("ta-b2-convenience");
342
- std::fs::create_dir_all(&dir).unwrap();
343
- let path = dir.join("convenience-lock.tmp");
344
- {
345
- let guard = try_lock_exclusive(&path, Duration::from_secs(1))
346
- .expect("first acquire must succeed");
347
- let _ = guard.file();
348
- }
349
- let guard2 = try_lock_exclusive(&path, Duration::from_secs(1))
350
- .expect("post-drop reacquire must succeed");
351
- drop(guard2);
352
- let _ = std::fs::remove_file(&path);
353
- }
354
-
355
239
  #[test]
356
240
  fn second_acquire_blocks_until_first_releases() {
357
241
  // C-6 N38 anchor: the primitive returns `Ok(false)` for the
@@ -392,41 +276,4 @@ mod tests {
392
276
  unlock(&file2).unwrap();
393
277
  let _ = std::fs::remove_file(&path);
394
278
  }
395
-
396
- #[test]
397
- fn timeout_error_carries_path_and_seconds() {
398
- // Convenience wrapper's timeout error shape.
399
- //
400
- // 0.5.43 debt-sweep (§6.2): the pre-0.5.43 fixed
401
- // `ta-b2-timeout/timeout-lock.tmp` path let parallel test
402
- // workers race for the same file across cargo threads. Each
403
- // run now allocates a per-process + monotonic-atomic dir so
404
- // `--test-threads=2` cannot false-fail. Timeout shape and
405
- // `timeout-lock.tmp` basename are preserved so downstream
406
- // guards keep firing.
407
- static N: std::sync::atomic::AtomicU64 = std::sync::atomic::AtomicU64::new(0);
408
- let dir = std::env::temp_dir().join(format!(
409
- "ta-b2-timeout-{}-{}",
410
- std::process::id(),
411
- N.fetch_add(1, std::sync::atomic::Ordering::Relaxed)
412
- ));
413
- std::fs::create_dir_all(&dir).unwrap();
414
- let path = dir.join("timeout-lock.tmp");
415
- let _hold =
416
- try_lock_exclusive(&path, Duration::from_secs(1)).expect("first acquire must succeed");
417
- let err = try_lock_exclusive(&path, Duration::from_millis(150))
418
- .expect_err("second acquire must timeout");
419
- match err {
420
- LockError::Timeout {
421
- timeout_secs,
422
- path: p,
423
- } => {
424
- assert!(timeout_secs > 0.0);
425
- assert!(p.ends_with("timeout-lock.tmp"), "path suffix: {p}");
426
- }
427
- other => panic!("expected Timeout, got {other:?}"),
428
- }
429
- let _ = std::fs::remove_file(&path);
430
- let _ = std::fs::remove_dir_all(&dir);
431
- }
432
279
  }
@@ -1,64 +1,3 @@
1
- //! 0.5.x Windows portability Batch 0: platform abstraction layer.
2
- //!
3
- //! Truth sources (READ-ONLY):
4
- //! - Design: `.team/artifacts/0.5.x-windows-portability-survey-design.md`
5
- //! (§Target Design + §Ordered Migration Plan)
6
- //! - CR verdict: `.team/artifacts/0.5.x-windows-portability-cr-verdict.md`
7
- //! (6 constraints; C-1 through C-6 anchor into this module)
8
- //!
9
- //! ## Scope of Batch 0 (this commit)
10
- //!
11
- //! - Add the `platform` module scaffold + Unix-side implementations
12
- //! populated from the current inline `libc`/`std::os::unix` code
13
- //! (byte-equivalent behavior on macOS/Linux).
14
- //! - No caller migration yet — the three legacy fallback sites
15
- //! (`mcp_server/wire.rs`, `lifecycle/restart/agent.rs`,
16
- //! `state/persist.rs`) stay in place with `FIXME(portability)`
17
- //! comments pointing at this design. Batch 2/3 replaces them.
18
- //! - Windows side is empty stubs today; every fn is `unimplemented!()`
19
- //! with a `# Safety:` / `# Windows:` doc note explaining what
20
- //! Batch 2/3/4 will supply.
21
- //! - CI adds a Windows compile-only gate (`cargo check --target
22
- //! x86_64-pc-windows-msvc`), reporting RED as the burn-down baseline
23
- //! for Batches 1-4. The Windows job uses `continue-on-error: true`
24
- //! so it does not block the Ubuntu/macOS/Windows-binaries jobs.
25
- //!
26
- //! ## CR anchors
27
- //!
28
- //! - **C-1**: `packaging/types.rs::WindowsX8664 → PlatformSupport::Native`
29
- //! claim is FALSE while `cargo check --target x86_64-pc-windows-msvc`
30
- //! is RED. Downgraded to `PreviewCompileOnly` in this batch; will be
31
- //! promoted back to `Native` only after Batch 6/7 real-machine gates.
32
- //! - **C-2**: three legacy non-Unix fallbacks
33
- //! (`wire.rs::parent_pid=0`, `restart/agent.rs::pid_is_alive=true`,
34
- //! `persist.rs::runtime_lock=not_implemented`) get
35
- //! `FIXME(portability)` comments referencing this design. Batch 2
36
- //! removes the persist.rs one; Batch 3 removes the wire.rs +
37
- //! restart/agent.rs ones. Grep guards verify no reintroduction.
38
- //! - **C-4**: `platform::process` is NOT importable from
39
- //! `messaging/` (team-worker liveness must go through the backend
40
- //! `Transport`, not a shell-out process snapshot). Grep guard test
41
- //! walks the source tree.
42
- //! - **C-6**: hard-terminate on Windows lacks Unix grace semantics —
43
- //! the `terminate_pid`/`terminate_group` signatures include a
44
- //! `SignalKind` enum + a caller-visible `TerminationOutcome` so
45
- //! Windows callers can emit a `platform.terminate_force_only` event
46
- //! when they downgrade from `TerminateGraceful` to `TerminateForce`.
47
- //!
48
- //! ## Module layout
49
- //!
50
- //! - `process` — process lifecycle + snapshot + termination
51
- //! - `file_lock` — cross-platform exclusive file lock
52
- //! - `errors` — retryable error classifier + os_error_name
53
- //! - `argv` — process argv/environ query (Batch 4)
54
- //!
55
- //! Every submodule follows the same pattern: a `unix.rs` file with the
56
- //! current libc code, a `windows.rs` file with `unimplemented!()`
57
- //! stubs + Windows API sketch, and a `mod.rs` that re-exports the
58
- //! platform-appropriate impl via `cfg`.
59
- //!
60
- //! Callers see a single `crate::platform::process::pid_liveness(pid)`
61
- //! (etc.) with no `cfg` at the callsite.
62
1
 
63
2
  pub mod argv;
64
3
  pub mod errors;
@@ -1,3 +1,4 @@
1
+ //!
1
2
  //! Process lifecycle + snapshot + termination platform primitives.
2
3
  //!
3
4
  //! Batch 0 provides:
@@ -1,3 +1,4 @@
1
+ //!
1
2
  //! ProviderAdapter trait(per-provider 命令构造 + 能力面)+ registry facade + 占位实现。
2
3
 
3
4
  use std::path::{Path, PathBuf};
@@ -1,3 +1,4 @@
1
+ //!
1
2
  //! Claude / ClaudeCode provider-local command builders + permission helpers.
2
3
  //!
3
4
  //! Extracted from `provider/adapter.rs` (0.4.x decoupling step 2). Pure
@@ -1,3 +1,4 @@
1
+ //!
1
2
  use std::path::{Path, PathBuf};
2
3
 
3
4
  use crate::provider::{ProviderError, SessionId};
@@ -1,3 +1,4 @@
1
+ //!
1
2
  //! Codex provider-local command builder + permission/sandbox helpers.
2
3
  //!
3
4
  //! Extracted from `provider/adapter.rs` (0.4.x decoupling step 2). Pure
@@ -1,3 +1,4 @@
1
+ //!
1
2
  //! Copilot provider-local command builders + permission helpers.
2
3
  //!
3
4
  //! Extracted from `provider/adapter.rs` (0.4.x decoupling step 2). Pure
@@ -1,3 +1,4 @@
1
+ //!
1
2
  use std::path::{Path, PathBuf};
2
3
 
3
4
  use rusqlite::{params, Connection};
@@ -1,3 +1,4 @@
1
+ //!
1
2
  //! Fake provider — scripted worker built into the team-agent CLI itself.
2
3
  //! Extracted from `provider/adapter.rs` (0.4.x decoupling step 2).
3
4
 
@@ -1,3 +1,4 @@
1
+ //!
1
2
  //! Provider-local adapter implementations. Split from the monolithic
2
3
  //! `provider/adapter.rs` as 0.4.x decoupling step 2. Each file owns its
3
4
  //! provider's command builders, permission/sandbox/auth helpers, and
@@ -1,2 +1,3 @@
1
+ //!
1
2
  pub mod parsing;
2
3
  pub mod runtime_prompts;
@@ -1,3 +1,4 @@
1
+ //!
1
2
  use serde::{Deserialize, Serialize};
2
3
 
3
4
  use crate::provider::ApprovalKind;
@@ -38,11 +39,7 @@ impl ApprovalPrompt {
38
39
  }
39
40
  }
40
41
 
41
- pub fn capture_has_approval_prompt(capture: &str) -> bool {
42
- extract_approval_prompt("agent", capture).is_some()
43
- }
44
-
45
- pub fn active_approval_control_index(lines: &[&str]) -> Option<usize> {
42
+ fn active_approval_control_index(lines: &[&str]) -> Option<usize> {
46
43
  let idx = lines
47
44
  .iter()
48
45
  .enumerate()
@@ -1,3 +1,4 @@
1
+ //!
1
2
  //! Runtime approval prompt decisions shared by coordinator hooks.
2
3
 
3
4
  use serde::{Deserialize, Serialize};
@@ -7,11 +8,11 @@ use crate::provider::{ApprovalFingerprint, ApprovalKind, ApprovalPrompt};
7
8
 
8
9
  pub const RUNTIME_MCP_APPROVAL_SERVER: &str = "team_orchestrator";
9
10
 
10
- pub fn runtime_mcp_tool_allowlisted(tool: &str) -> bool {
11
+ fn runtime_mcp_tool_allowlisted(tool: &str) -> bool {
11
12
  !tool.trim().is_empty()
12
13
  }
13
14
 
14
- pub fn runtime_mcp_prompt_allowlisted(prompt: &ApprovalPrompt) -> bool {
15
+ fn runtime_mcp_prompt_allowlisted(prompt: &ApprovalPrompt) -> bool {
15
16
  prompt.server.as_deref() == Some(RUNTIME_MCP_APPROVAL_SERVER)
16
17
  && prompt
17
18
  .tool
@@ -34,7 +35,7 @@ pub fn runtime_mcp_prompt_allowlisted(prompt: &ApprovalPrompt) -> bool {
34
35
  /// reporting status to leader through the message bus is the same
35
36
  /// architectural layer as `report_result` and is harmless. New tools
36
37
  /// join only after explicit product decision (per architect note).
37
- pub fn runtime_mcp_tool_is_internal_control_plane(prompt: &ApprovalPrompt) -> bool {
38
+ fn runtime_mcp_tool_is_internal_control_plane(prompt: &ApprovalPrompt) -> bool {
38
39
  if prompt.server.as_deref() != Some(RUNTIME_MCP_APPROVAL_SERVER) {
39
40
  return false;
40
41
  }
@@ -129,7 +130,7 @@ pub fn awaiting_human_confirm_reason(
129
130
  }
130
131
  }
131
132
 
132
- pub fn approval_prompt_fingerprint(
133
+ fn approval_prompt_fingerprint(
133
134
  team: &str,
134
135
  agent_id: &str,
135
136
  prompt: &ApprovalPrompt,
@@ -163,7 +164,7 @@ pub fn approval_prompt_fingerprint(
163
164
  ApprovalFingerprint::new(fingerprint)
164
165
  }
165
166
 
166
- pub fn awaiting_human_confirm_dedupe_key(
167
+ fn awaiting_human_confirm_dedupe_key(
167
168
  team: &str,
168
169
  agent_id: &str,
169
170
  fingerprint: &ApprovalFingerprint,
@@ -1,3 +1,4 @@
1
+ //!
1
2
  //! JSONL→neutral turn-state 翻译 + idle take-over predicate(`provider_state.common` +
2
3
  //! `idle_predicate` 的 Rust 等价)。leader 经注入的 TurnStateClassifier 调到这里。
3
4
 
@@ -1,3 +1,4 @@
1
+ //!
1
2
  //! abnormal track 消费的 fault/approval facts 抽取(`provider_state.read_fault_facts`)。
2
3
 
3
4
  use super::types::{FactKind, FaultFact, Signature, TurnId};
@@ -13,15 +14,6 @@ pub fn read_fault_facts(records: &[serde_json::Value], provider: Provider) -> Ve
13
14
  .collect()
14
15
  }
15
16
 
16
- pub fn explicit_error_fact(record: &serde_json::Value, provider: Provider) -> Option<FaultFact> {
17
- match provider {
18
- Provider::Codex => codex_explicit_error_fact(record),
19
- Provider::Claude | Provider::ClaudeCode => claude_explicit_error_fact(record),
20
- // copilot 一期不接 jsonl 真相源(C-3-5)。
21
- Provider::Copilot | Provider::GeminiCli | Provider::Fake => None,
22
- }
23
- }
24
-
25
17
  pub(crate) fn claude_explicit_error_fact(record: &serde_json::Value) -> Option<FaultFact> {
26
18
  if claude_record_is_system_api_error(record) {
27
19
  return Some(FaultFact::new(
@@ -50,23 +42,6 @@ pub(crate) fn claude_explicit_error_fact(record: &serde_json::Value) -> Option<F
50
42
  None
51
43
  }
52
44
 
53
- fn codex_explicit_error_fact(record: &serde_json::Value) -> Option<FaultFact> {
54
- if record.get("method").and_then(serde_json::Value::as_str) != Some("turn/completed") {
55
- return None;
56
- }
57
- let turn = record.get("params").and_then(|p| p.get("turn"))?;
58
- if turn.get("status").and_then(serde_json::Value::as_str) != Some("failed") {
59
- return None;
60
- }
61
- Some(FaultFact::new(
62
- Signature::new("turn_failed"),
63
- turn.get("id")
64
- .and_then(serde_json::Value::as_str)
65
- .map(TurnId::new),
66
- FactKind::Failed,
67
- ))
68
- }
69
-
70
45
  fn fault_fact(provider: Provider, record: &serde_json::Value) -> Option<FaultFact> {
71
46
  match provider {
72
47
  Provider::Claude | Provider::ClaudeCode => claude_fault_fact(record),
@@ -1,3 +1,4 @@
1
+ //!
1
2
  //! provider 跨子模块共享 helper:JSONL 解析 / session_id 抽取 / 正则编译。
2
3
 
3
4
  use super::types::{ProviderError, StatusPatterns};
@@ -1,3 +1,4 @@
1
+ //!
1
2
  //! step 8 · provider — type + trait SKELETON (ROUND-0).
2
3
  //!
3
4
  //! Design doc: `docs/phase0/subsystems/08-provider.md`
@@ -37,7 +38,6 @@ pub mod adapter;
37
38
  pub(crate) mod adapters;
38
39
  pub mod approvals;
39
40
  pub mod classify;
40
- pub mod command;
41
41
  pub mod faults;
42
42
  pub mod session;
43
43
  pub mod session_scan;
@@ -1,3 +1,4 @@
1
+ //!
1
2
  use std::collections::{BTreeMap, BTreeSet};
2
3
  use std::path::{Path, PathBuf};
3
4
 
@@ -284,12 +285,22 @@ where
284
285
  .zip(candidate.captured.session_id.as_ref())
285
286
  .is_some_and(|(expected, captured)| expected.as_str() != captured.as_str());
286
287
  if mismatch {
287
- report.ambiguous.push(AmbiguousSessionCapture {
288
- agent_id: item.agent_id.clone(),
289
- spawn_cwd: item.context.spawn_cwd.to_string_lossy().to_string(),
290
- });
288
+ let ambiguity_changed = agent_obj
289
+ .get("attribution_ambiguous")
290
+ .and_then(Value::as_bool)
291
+ != Some(true);
292
+ if !finalize_ambiguous || ambiguity_changed {
293
+ report.ambiguous.push(AmbiguousSessionCapture {
294
+ agent_id: item.agent_id.clone(),
295
+ spawn_cwd: item.context.spawn_cwd.to_string_lossy().to_string(),
296
+ });
297
+ }
291
298
  if finalize_ambiguous {
292
- agent_obj.insert("attribution_ambiguous".to_string(), serde_json::json!(true));
299
+ if ambiguity_changed {
300
+ agent_obj
301
+ .insert("attribution_ambiguous".to_string(), serde_json::json!(true));
302
+ report.changed = true;
303
+ }
293
304
  // 0.4.6 tuple-atomic contract (audit:93): do NOT write
294
305
  // `captured_at` for ambiguity diagnostics. `captured_at`
295
306
  // is part of the authoritative tuple and may only be
@@ -299,7 +310,6 @@ where
299
310
  // "looks captured" rows. Ambiguity diagnostics live in
300
311
  // the `attribution_ambiguous` flag + events; persist
301
312
  // event log for the timestamp.
302
- report.changed = true;
303
313
  }
304
314
  continue;
305
315
  }
@@ -317,19 +327,29 @@ where
317
327
  continue;
318
328
  }
319
329
  if ambiguous_ids.contains(&item.agent_id) {
320
- report.ambiguous.push(AmbiguousSessionCapture {
321
- agent_id: item.agent_id.clone(),
322
- spawn_cwd: item.context.spawn_cwd.to_string_lossy().to_string(),
323
- });
330
+ let ambiguity_changed = agent_obj
331
+ .get("attribution_ambiguous")
332
+ .and_then(Value::as_bool)
333
+ != Some(true)
334
+ || agent_obj.get("capture_state").and_then(Value::as_str)
335
+ != Some("attribution_ambiguous");
336
+ if !finalize_ambiguous || ambiguity_changed {
337
+ report.ambiguous.push(AmbiguousSessionCapture {
338
+ agent_id: item.agent_id.clone(),
339
+ spawn_cwd: item.context.spawn_cwd.to_string_lossy().to_string(),
340
+ });
341
+ }
324
342
  if finalize_ambiguous {
325
- agent_obj.insert("attribution_ambiguous".to_string(), serde_json::json!(true));
326
- agent_obj.insert(
327
- "capture_state".to_string(),
328
- serde_json::json!("attribution_ambiguous"),
329
- );
330
- // 0.4.6 tuple-atomic contract: see comment above. Removed
331
- // `captured_at` ambiguity write.
332
- report.changed = true;
343
+ if ambiguity_changed {
344
+ agent_obj.insert("attribution_ambiguous".to_string(), serde_json::json!(true));
345
+ agent_obj.insert(
346
+ "capture_state".to_string(),
347
+ serde_json::json!("attribution_ambiguous"),
348
+ );
349
+ // 0.4.6 tuple-atomic contract: see comment above. Removed
350
+ // `captured_at` ambiguity write.
351
+ report.changed = true;
352
+ }
333
353
  }
334
354
  continue;
335
355
  }
@@ -515,10 +535,6 @@ pub fn incomplete_resumable_agent_ids(state: &Value) -> Vec<String> {
515
535
  out
516
536
  }
517
537
 
518
- pub fn session_capture_complete(state: &Value) -> bool {
519
- incomplete_resumable_agent_ids(state).is_empty()
520
- }
521
-
522
538
  pub fn recover_resume_session_from_events(
523
539
  workspace: &Path,
524
540
  agent_id: &str,
@@ -666,6 +682,9 @@ fn pending_session_capture<F>(
666
682
  where
667
683
  F: FnMut(Provider) -> Box<dyn ProviderAdapter>,
668
684
  {
685
+ if agent.get("capture_state").and_then(Value::as_str) == Some("attribution_ambiguous") {
686
+ return None;
687
+ }
669
688
  let provider = incomplete_resumable_provider(agent, adapter_for)?;
670
689
  let spawn_cwd = agent
671
690
  .get("spawn_cwd")
@@ -1,3 +1,4 @@
1
+ //!
1
2
  use super::*;
2
3
 
3
4
  pub(super) fn verify_claude_fork(
@@ -1,3 +1,4 @@
1
+ //!
1
2
  use super::*;
2
3
  use std::collections::BTreeSet;
3
4
  use std::fs::{File, OpenOptions};
@@ -1,3 +1,4 @@
1
+ //!
1
2
  use super::*;
2
3
 
3
4
  #[derive(Debug, Clone)]
@@ -1,3 +1,4 @@
1
+ //!
1
2
  use std::collections::BTreeMap;
2
3
  use std::path::{Path, PathBuf};
3
4
  use std::time::{Duration, SystemTime};
@@ -1,3 +1,4 @@
1
+ //!
1
2
  //! unit-6 (Stage 2) — provider session namespace.
2
3
  //!
3
4
  //! Houses session-specific provider concerns: resume preflight,
@@ -15,7 +16,4 @@ pub(crate) use context_fork::{
15
16
  PendingContextFork,
16
17
  };
17
18
 
18
- pub use resume::{
19
- ProviderBackingCheck, RecoveryHint, ResumeDecisionDetail, ResumePreflight,
20
- ResumePreflightOutcome, ResumeRefusalReason,
21
- };
19
+ pub use resume::{RecoveryHint, ResumeRefusalReason};