@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
  //! step 14a · mcp_server::wire — stdio loop + JSON-RPC route + tool dispatch + contracts.
2
3
 
3
4
  use std::io::{BufRead, Write};
@@ -9,7 +10,6 @@ use crate::event_log::EventLog;
9
10
  use crate::messaging::MessageTarget;
10
11
 
11
12
  use super::helpers::{json_dumps_default, object_fields};
12
- use super::normalize::normalize_result_status;
13
13
  use super::tools::TeamOrchestratorTools;
14
14
  use super::types::{
15
15
  McpError, McpTool, RpcError, RpcId, RpcMethod, RpcResponse, Scope, SendOutcome,
@@ -87,16 +87,15 @@ pub fn dispatch(tools: &TeamOrchestratorTools, request: &Value) -> ToolResult {
87
87
  /// `handle_mcp(tools, request)` (`server.py:46-91`): the JSON-RPC router.
88
88
  /// - `initialize` → serverInfo `team_orchestrator` v0.1.4 + echoed protocolVersion.
89
89
  /// - `tools/list` → `{tools: TOOLS}`.
90
- /// - `tools/call` → run [`dispatch`], wrap into [`ToolCallResult`] (`isError` =
91
- /// dispatch returned `Err`); the arg-vs-runtime exception split (`server.py:
92
- /// 69-72`) classifies a caught failure into `InvalidToolArguments` vs
93
- /// `InternalRuntimeError`.
90
+ /// - `tools/call` → run [`dispatch`], wrap through the live
91
+ /// `tool_call_result_value` path (`isError` = dispatch returned `Err`); the
92
+ /// arg-vs-runtime exception split (`server.py:69-72`) classifies a caught
93
+ /// failure into `InvalidToolArguments` vs `InternalRuntimeError`.
94
94
  /// - `notifications/*` → `Ok(None)` (no frame; **must not** emit to stdout).
95
95
  /// - unknown method → `-32601` error frame.
96
96
  /// Returns `Ok(None)` only for the notifications path; every other branch yields a
97
97
  /// frame.
98
98
  ///
99
- /// [`ToolCallResult`]: super::ToolCallResult
100
99
  pub fn handle_mcp(
101
100
  tools: &TeamOrchestratorTools,
102
101
  request: &Value,
@@ -369,7 +368,7 @@ fn python_repr(value: &str) -> String {
369
368
  fn tool_contract(tool: McpTool) -> Value {
370
369
  let (description, required) = match tool {
371
370
  McpTool::SendMessage => (
372
- "Send a message to a teammate, the leader, or '*' for all other team members. Team Agent fills identity and delivery metadata; optional presentation routing is durable and never drops the message.",
371
+ "Send a message to a teammate, the leader, or '*' for all other team members. mailbox=true stores durably without live injection; the default is live delivery.",
373
372
  vec!["to", "content"],
374
373
  ),
375
374
  McpTool::AssignTask => ("Assign or update a task in the team graph and deliver it to its assignee.", vec!["task"]),
@@ -404,11 +403,7 @@ fn tool_properties(tool: McpTool) -> serde_json::Map<String, Value> {
404
403
  let mut properties = serde_json::Map::new();
405
404
  match tool {
406
405
  McpTool::AssignTask => {
407
- insert_property(
408
- &mut properties,
409
- "task",
410
- object_property("Task object to add or update."),
411
- );
406
+ insert_property(&mut properties, "task", task_property());
412
407
  insert_property(
413
408
  &mut properties,
414
409
  "message",
@@ -424,8 +419,10 @@ fn tool_properties(tool: McpTool) -> serde_json::Map<String, Value> {
424
419
  insert_property(&mut properties, "content", string_property("Message body."));
425
420
  insert_property(
426
421
  &mut properties,
427
- "presentation",
428
- presentation_property("Optional durable presentation routing."),
422
+ "mailbox",
423
+ boolean_property(
424
+ "Set true to store durably without live injection; omit for default live delivery.",
425
+ ),
429
426
  );
430
427
  }
431
428
  McpTool::ReportResult => {
@@ -603,6 +600,25 @@ fn object_property(description: &str) -> Value {
603
600
  serde_json::json!({"type": "object", "description": description, "additionalProperties": true})
604
601
  }
605
602
 
603
+ fn task_property() -> Value {
604
+ serde_json::json!({
605
+ "type": "object",
606
+ "description": "Task object to add or update.",
607
+ "properties": {
608
+ "result_route": {
609
+ "type": "string",
610
+ "enum": crate::messaging::results::ResultRoute::ALL
611
+ .iter()
612
+ .map(|route| route.as_str())
613
+ .collect::<Vec<_>>(),
614
+ "default": crate::messaging::results::ResultRoute::default().as_str(),
615
+ "description": "Result destination chosen by the task assigner."
616
+ }
617
+ },
618
+ "additionalProperties": true
619
+ })
620
+ }
621
+
606
622
  fn presentation_property(description: &str) -> Value {
607
623
  serde_json::json!({
608
624
  "type": "object",
@@ -646,6 +662,7 @@ pub(crate) fn dispatch_tool(
646
662
  None,
647
663
  None,
648
664
  None,
665
+ args.get("mailbox"),
649
666
  args.get("presentation"),
650
667
  )?;
651
668
  match outcome {
@@ -658,18 +675,7 @@ pub(crate) fn dispatch_tool(
658
675
  McpTool::ReportResult => tools.report_result_with_presentation(
659
676
  args.get("envelope"),
660
677
  args.get("summary").and_then(Value::as_str),
661
- // cr verdict (T3-1 refined): an unknown status literal normalizes to
662
- // Partial and is OBSERVABLE at this ingestion boundary, never silent.
663
- {
664
- let (status, unknown) =
665
- crate::mcp_server::normalize::normalize_result_status_observed(
666
- args.get("status").and_then(Value::as_str),
667
- );
668
- if let Some(raw) = unknown {
669
- tools.note_unknown_result_status(&raw);
670
- }
671
- status
672
- },
678
+ args.get("status").and_then(Value::as_str),
673
679
  args.get("changes")
674
680
  .and_then(Value::as_array)
675
681
  .map(Vec::as_slice),
@@ -1,3 +1,4 @@
1
+ //!
1
2
  //! idle_alerts.py — idle/deadlock 检测 (team-scoped 抑制 + last-fire 节流;card §23) +
2
3
  //! activity_detector.py — classifier 产物 (card §24)。
3
4
  //! §11 IRON LAW (bug-071/077/085):无信号 → Uncertain,绝不 Idle。
@@ -1,3 +1,4 @@
1
+ //!
1
2
  //! Pure logical-address grammar shared by public entry-point adapters.
2
3
 
3
4
  use std::path::PathBuf;
@@ -1,3 +1,4 @@
1
+ //!
1
2
  //! internal_delivery.py + delivery.py — coordinator/调度器侧 thin wrapper + 单条 tmux 注入投递
2
3
  //! + trust 有界重试 + turn-open arm (card §16/§65)。
3
4
 
@@ -93,7 +94,7 @@ pub fn deliver_persisted_message(
93
94
 
94
95
  /// `_tmux_pane_width` (`delivery.py:20`):查询 pane 列宽。**fail-safe** (bug-064/082):失败
95
96
  /// 返回 [`PaneWidthQuery::Failed`],**绝不**给默认宽度。借 step 9 transport 的 query。
96
- pub fn tmux_pane_width(transport: &dyn Transport, target: &Target) -> PaneWidthQuery {
97
+ pub(crate) fn tmux_pane_width(transport: &dyn Transport, target: &Target) -> PaneWidthQuery {
97
98
  let queried = std::panic::catch_unwind(std::panic::AssertUnwindSafe(|| {
98
99
  transport.query(target, crate::transport::PaneField::PaneWidth)
99
100
  }));
@@ -220,7 +221,12 @@ pub fn deliver_pending_message(
220
221
  }
221
222
  _ => state,
222
223
  };
223
- if message.recipient == "leader" && message.status == "submitted_pending_acceptance" {
224
+ if message.recipient == "leader"
225
+ && matches!(
226
+ message.status.as_str(),
227
+ "submitted_pending_acceptance" | "injected_awaiting_receipt"
228
+ )
229
+ {
224
230
  return observe_pending_leader_acceptance(store, event_log, state, message_id);
225
231
  }
226
232
  if message.recipient == "leader" && message.status == "queued_until_leader_attach" {
@@ -341,6 +347,12 @@ pub fn deliver_pending_message(
341
347
  .get("status")
342
348
  .and_then(serde_json::Value::as_str)
343
349
  .unwrap_or("unbound");
350
+ let refusal = match &reason {
351
+ crate::messaging::LeaderChannelUnbound::PaneWorkspaceMismatch(_) => {
352
+ DeliveryRefusal::PaneWorkspaceMismatch
353
+ }
354
+ _ => DeliveryRefusal::LeaderNotAttached,
355
+ };
344
356
  store.mark(message_id, "failed", Some("leader_not_attached"))?;
345
357
  event_log.write(
346
358
  "leader_receiver.delivery_blocked",
@@ -349,7 +361,7 @@ pub fn deliver_pending_message(
349
361
  "sender": message.sender,
350
362
  "reason": "leader_receiver_not_attached",
351
363
  "error": "leader_not_attached",
352
- "channel_reason": format!("{reason:?}"),
364
+ "channel_reason": reason.reason_code(),
353
365
  "channel": "rebind_required",
354
366
  "action": "run team-agent attach-leader or team-agent takeover",
355
367
  "status": receiver_status,
@@ -364,7 +376,7 @@ pub fn deliver_pending_message(
364
376
  "run team-agent attach-leader or team-agent takeover".to_string(),
365
377
  ),
366
378
  stage: None,
367
- reason: Some(DeliveryRefusal::LeaderNotAttached),
379
+ reason: Some(refusal),
368
380
  channel: Some("rebind_required".to_string()),
369
381
  });
370
382
  }
@@ -711,19 +723,30 @@ pub fn deliver_pending_message(
711
723
  }
712
724
  if is_leader_recipient {
713
725
  store.record_delivery_submission(message_id, readback_verified)?;
714
- if !leader_transcript_has_token(state, message_id) {
715
- store.mark(message_id, "submitted_pending_acceptance", None)?;
716
- event_log.write(
717
- "leader_receiver.acceptance_pending",
718
- serde_json::json!({
719
- "message_id": message_id,
720
- "reason": "provider_receipt_not_observed",
721
- }),
722
- )?;
723
- return Ok(leader_acceptance_pending_outcome(
724
- message_id,
725
- "submitted_pending_acceptance",
726
- ));
726
+ match observe_leader_receipt(state, message_id) {
727
+ LeaderReceiptObservation::SourceUnavailable => {
728
+ store.mark_injected_awaiting_receipt(message_id)?;
729
+ event_log.write(
730
+ "leader_receiver.receipt_source_unavailable",
731
+ serde_json::json!({"message_id": message_id}),
732
+ )?;
733
+ return Ok(leader_receipt_source_unavailable_outcome(message_id));
734
+ }
735
+ LeaderReceiptObservation::TokenAbsent => {
736
+ store.mark(message_id, "submitted_pending_acceptance", None)?;
737
+ event_log.write(
738
+ "leader_receiver.acceptance_pending",
739
+ serde_json::json!({
740
+ "message_id": message_id,
741
+ "reason": "provider_receipt_not_observed",
742
+ }),
743
+ )?;
744
+ return Ok(leader_acceptance_pending_outcome(
745
+ message_id,
746
+ "submitted_pending_acceptance",
747
+ ));
748
+ }
749
+ LeaderReceiptObservation::TokenObserved => {}
727
750
  }
728
751
  store.mark_delivered_with_receipt(message_id)?;
729
752
  } else {
@@ -2041,15 +2064,36 @@ fn leader_rollout_path(state: &serde_json::Value) -> Option<std::path::PathBuf>
2041
2064
  .map(std::path::PathBuf::from)
2042
2065
  }
2043
2066
 
2044
- pub(crate) fn leader_transcript_has_token(state: &serde_json::Value, message_id: &str) -> bool {
2067
+ #[derive(Debug, Clone, Copy, PartialEq, Eq)]
2068
+ pub(crate) enum LeaderReceiptObservation {
2069
+ SourceUnavailable,
2070
+ TokenAbsent,
2071
+ TokenObserved,
2072
+ }
2073
+
2074
+ pub(crate) fn observe_leader_receipt(
2075
+ state: &serde_json::Value,
2076
+ message_id: &str,
2077
+ ) -> LeaderReceiptObservation {
2045
2078
  let Some(path) = leader_rollout_path(state) else {
2046
- return false;
2079
+ return LeaderReceiptObservation::SourceUnavailable;
2047
2080
  };
2048
- rollout_tail_contains(
2081
+ let Ok(observed) = rollout_tail_contains_result(
2049
2082
  &path,
2050
2083
  &format!("[team-agent-token:{message_id}]"),
2051
2084
  64 * 1024,
2052
- )
2085
+ ) else {
2086
+ return LeaderReceiptObservation::SourceUnavailable;
2087
+ };
2088
+ if observed {
2089
+ LeaderReceiptObservation::TokenObserved
2090
+ } else {
2091
+ LeaderReceiptObservation::TokenAbsent
2092
+ }
2093
+ }
2094
+
2095
+ pub(crate) fn leader_transcript_has_token(state: &serde_json::Value, message_id: &str) -> bool {
2096
+ observe_leader_receipt(state, message_id) == LeaderReceiptObservation::TokenObserved
2053
2097
  }
2054
2098
 
2055
2099
  fn leader_acceptance_pending_outcome(message_id: &str, status: &str) -> DeliveryOutcome {
@@ -2065,17 +2109,41 @@ fn leader_acceptance_pending_outcome(message_id: &str, status: &str) -> Delivery
2065
2109
  }
2066
2110
  }
2067
2111
 
2112
+ pub(crate) fn leader_receipt_source_unavailable_outcome(message_id: &str) -> DeliveryOutcome {
2113
+ DeliveryOutcome {
2114
+ ok: true,
2115
+ status: DeliveryStatus::Blocked,
2116
+ message_status: MessageStatusShadow("injected_awaiting_receipt".to_string()),
2117
+ message_id: Some(message_id.to_string()),
2118
+ verification: Some("leader_receipt_source_unavailable".to_string()),
2119
+ stage: Some(DeliveryStage::Submit),
2120
+ reason: None,
2121
+ channel: Some("leader_receipt_source_unavailable".to_string()),
2122
+ }
2123
+ }
2124
+
2068
2125
  fn observe_pending_leader_acceptance(
2069
2126
  store: &MessageStore,
2070
2127
  event_log: &EventLog,
2071
2128
  state: &serde_json::Value,
2072
2129
  message_id: &str,
2073
2130
  ) -> Result<DeliveryOutcome, MessagingError> {
2074
- if !leader_transcript_has_token(state, message_id) {
2075
- return Ok(leader_acceptance_pending_outcome(
2076
- message_id,
2077
- "submitted_pending_acceptance",
2078
- ));
2131
+ match observe_leader_receipt(state, message_id) {
2132
+ LeaderReceiptObservation::SourceUnavailable => {
2133
+ store.mark_injected_awaiting_receipt(message_id)?;
2134
+ event_log.write(
2135
+ "leader_receiver.receipt_source_unavailable",
2136
+ serde_json::json!({"message_id": message_id}),
2137
+ )?;
2138
+ return Ok(leader_receipt_source_unavailable_outcome(message_id));
2139
+ }
2140
+ LeaderReceiptObservation::TokenAbsent => {
2141
+ return Ok(leader_acceptance_pending_outcome(
2142
+ message_id,
2143
+ "submitted_pending_acceptance",
2144
+ ));
2145
+ }
2146
+ LeaderReceiptObservation::TokenObserved => {}
2079
2147
  }
2080
2148
  store.mark_delivered_with_receipt(message_id)?;
2081
2149
  event_log.write(
@@ -2187,7 +2255,7 @@ pub fn execute_trust_retry(
2187
2255
 
2188
2256
  /// `_record_turn_open_if_leader_to_worker` (`delivery.py:430`):**take-over arm 来自真实投递**
2189
2257
  /// (card §121) —— 仅 leader→worker 注入/投递成功后才 arm,绝不凭空 arm。
2190
- pub fn record_turn_open_if_leader_to_worker(
2258
+ pub(crate) fn record_turn_open_if_leader_to_worker(
2191
2259
  workspace: &Path,
2192
2260
  state: &serde_json::Value,
2193
2261
  sender: &str,
@@ -2346,7 +2414,7 @@ fn arm_turn_open(state: &mut serde_json::Value, recipient: &str, message_id: &Op
2346
2414
 
2347
2415
  /// `_stamp_first_send_at_if_leader_to_worker` (`delivery.py:380`):首次 leader→worker 投递戳
2348
2416
  /// `first_send_at` (step 13 restart Route B atomicity 决策读它)。
2349
- pub fn stamp_first_send_at_if_leader_to_worker(
2417
+ pub(crate) fn stamp_first_send_at_if_leader_to_worker(
2350
2418
  workspace: &Path,
2351
2419
  state: &serde_json::Value,
2352
2420
  sender: &str,
@@ -2744,22 +2812,22 @@ fn claude_recipient_rollout(
2744
2812
  /// Silent on read errors — callers treat missing/unreadable as "token not
2745
2813
  /// present" which forces the unverified path.
2746
2814
  fn rollout_tail_contains(path: &std::path::Path, needle: &str, tail_bytes: u64) -> bool {
2815
+ rollout_tail_contains_result(path, needle, tail_bytes).unwrap_or(false)
2816
+ }
2817
+
2818
+ fn rollout_tail_contains_result(
2819
+ path: &std::path::Path,
2820
+ needle: &str,
2821
+ tail_bytes: u64,
2822
+ ) -> std::io::Result<bool> {
2747
2823
  use std::io::{Read, Seek, SeekFrom};
2748
- let Ok(mut file) = std::fs::File::open(path) else {
2749
- return false;
2750
- };
2751
- let Ok(metadata) = file.metadata() else {
2752
- return false;
2753
- };
2824
+ let mut file = std::fs::File::open(path)?;
2825
+ let metadata = file.metadata()?;
2754
2826
  let len = metadata.len();
2755
2827
  let start = len.saturating_sub(tail_bytes);
2756
- if file.seek(SeekFrom::Start(start)).is_err() {
2757
- return false;
2758
- }
2828
+ file.seek(SeekFrom::Start(start))?;
2759
2829
  let mut buf = Vec::with_capacity(tail_bytes.min(len) as usize);
2760
- if file.take(tail_bytes).read_to_end(&mut buf).is_err() {
2761
- return false;
2762
- }
2830
+ file.take(tail_bytes).read_to_end(&mut buf)?;
2763
2831
  let haystack = String::from_utf8_lossy(&buf);
2764
- haystack.contains(needle)
2832
+ Ok(haystack.contains(needle))
2765
2833
  }
@@ -1,3 +1,4 @@
1
+ //!
1
2
  //! 私有内部 helpers (status wire / envelope 校验 / scheduled kind 解析 / activity 信号
2
3
  //! 解析 / id 生成 / MessageStatusShadow 占位)。跨子模块/测试可见者升 `pub(crate)`。
3
4
 
@@ -268,7 +269,7 @@ fn idle_activity() -> AgentActivity {
268
269
  /// outcome **不被视为 success**(I-3 反向断言要求 `leader_receiver.rs` 源文件不得含
269
270
  /// `DeliveryStatus::FallbackLog` 或 `fallback_inbox` 字面量,所以本函数从 `leader_receiver.rs`
270
271
  /// 搬到本 helpers 模块,字面量在此被允许)。
271
- pub fn fail_leader_delivery(
272
+ pub(crate) fn fail_leader_delivery(
272
273
  workspace: &std::path::Path,
273
274
  payload: &serde_json::Value,
274
275
  reason: DeliveryRefusal,
@@ -1,8 +1,10 @@
1
+ //!
1
2
  use std::path::Path;
2
3
 
3
4
  use serde_json::Value;
4
5
 
5
6
  use crate::codex_app_server::AppServerBinding;
7
+ use crate::model::pane_authority_refusal::PaneWorkspaceMismatchFacts;
6
8
  use crate::transport::{PaneInfo, Transport};
7
9
 
8
10
  #[derive(Debug, Clone, PartialEq, Eq)]
@@ -26,7 +28,7 @@ pub enum LeaderChannelResolution {
26
28
  ProbeFailed(String),
27
29
  }
28
30
 
29
- #[derive(Debug, Clone, Copy, PartialEq, Eq)]
31
+ #[derive(Debug, Clone, PartialEq, Eq)]
30
32
  pub enum LeaderChannelUnbound {
31
33
  ReceiverNotAttached,
32
34
  TransportConflict,
@@ -34,10 +36,25 @@ pub enum LeaderChannelUnbound {
34
36
  NonCanonicalTmuxSocket,
35
37
  EndpointMismatch,
36
38
  PaneNotLive,
37
- PaneWorkspaceMismatch,
39
+ PaneWorkspaceMismatch(PaneWorkspaceMismatchFacts),
38
40
  AppServerBindingInvalid,
39
41
  }
40
42
 
43
+ impl LeaderChannelUnbound {
44
+ pub const fn reason_code(&self) -> &'static str {
45
+ match self {
46
+ Self::ReceiverNotAttached => "ReceiverNotAttached",
47
+ Self::TransportConflict => "TransportConflict",
48
+ Self::MissingPaneId => "MissingPaneId",
49
+ Self::NonCanonicalTmuxSocket => "NonCanonicalTmuxSocket",
50
+ Self::EndpointMismatch => "EndpointMismatch",
51
+ Self::PaneNotLive => "PaneNotLive",
52
+ Self::PaneWorkspaceMismatch(_) => "PaneWorkspaceMismatch",
53
+ Self::AppServerBindingInvalid => "AppServerBindingInvalid",
54
+ }
55
+ }
56
+ }
57
+
41
58
  /// Resolve the canonical receiver's live physical channel without mutating
42
59
  /// ownership. For direct tmux, `(absolute socket, pane id)` plus an available
43
60
  /// pane cwd inside the target workspace is the authority. Session/window/tty/
@@ -79,11 +96,12 @@ pub fn resolve_live_leader_channel(
79
96
  .get("tmux_socket")
80
97
  .and_then(Value::as_str)
81
98
  .filter(|socket| !socket.is_empty());
99
+ let transport_endpoint = transport.tmux_endpoint();
82
100
  if tmux_socket.is_some_and(|socket| !std::path::Path::new(socket).is_absolute()) {
83
101
  return LeaderChannelResolution::Unbound(LeaderChannelUnbound::NonCanonicalTmuxSocket);
84
102
  }
85
103
  if let Some(expected) = tmux_socket {
86
- if transport.tmux_endpoint().as_deref() != Some(expected) {
104
+ if transport_endpoint.as_deref() != Some(expected) {
87
105
  return LeaderChannelResolution::Unbound(LeaderChannelUnbound::EndpointMismatch);
88
106
  }
89
107
  }
@@ -97,13 +115,19 @@ pub fn resolve_live_leader_channel(
97
115
  else {
98
116
  return LeaderChannelResolution::Unbound(LeaderChannelUnbound::PaneNotLive);
99
117
  };
100
- if observed
101
- .current_path
102
- .as_deref()
103
- .is_some_and(|path| !path_is_in_workspace(path, workspace))
104
- && !explicit_claim_authority_matches(workspace, receiver, &observed)
105
- {
106
- return LeaderChannelResolution::Unbound(LeaderChannelUnbound::PaneWorkspaceMismatch);
118
+ if let Some(observed_pane_workspace) = observed.current_path.clone() {
119
+ if !path_is_in_workspace(&observed_pane_workspace, workspace)
120
+ && !explicit_claim_authority_matches(workspace, receiver, &observed)
121
+ {
122
+ return LeaderChannelResolution::Unbound(LeaderChannelUnbound::PaneWorkspaceMismatch(
123
+ PaneWorkspaceMismatchFacts {
124
+ requested_workspace: canonical_path(workspace),
125
+ observed_pane_id: observed.pane_id.as_str().to_string(),
126
+ observed_pane_workspace,
127
+ endpoint: transport_endpoint.unwrap_or_else(|| "default".to_string()),
128
+ },
129
+ ));
130
+ }
107
131
  }
108
132
  let metadata_drift = receiver_metadata_drift(receiver, &observed);
109
133
  LeaderChannelResolution::Live(LiveLeaderChannel::DirectTmux(DirectTmuxLeaderChannel {
@@ -1,3 +1,4 @@
1
+ //!
1
2
  //! leader.py — leader pane 注入边界 + 恰好一次去重门 (card §21/§72)。
2
3
 
3
4
  use std::path::Path;
@@ -59,7 +60,7 @@ pub fn send_to_leader_receiver(
59
60
  /// stable message id for transport-fallback retries. The public function above
60
61
  /// keeps the existing call surface unchanged.
61
62
  #[allow(clippy::too_many_arguments)]
62
- pub fn send_to_leader_receiver_with_message_id(
63
+ pub(crate) fn send_to_leader_receiver_with_message_id(
63
64
  workspace: &Path,
64
65
  state: &serde_json::Value,
65
66
  leader_id: &str,
@@ -397,29 +398,46 @@ pub fn deliver_to_leader_fallback_pane(
397
398
  let readback_ok = super::delivery::pane_readback_verified(&report);
398
399
  if submit_ok {
399
400
  store.record_delivery_submission(message_id, readback_ok)?;
400
- if !super::delivery::leader_transcript_has_token(state, message_id) {
401
- store.mark(message_id, "submitted_pending_acceptance", None)?;
402
- event_log.write(
403
- "leader_receiver.acceptance_pending",
404
- serde_json::json!({
405
- "message_id": message_id,
406
- "result_id": result_id,
407
- "reason": "provider_receipt_not_observed",
408
- "channel": "fallback_pane",
409
- }),
410
- )?;
411
- return Ok(DeliveryOutcome {
412
- ok: true,
413
- status: DeliveryStatus::RetryScheduled,
414
- message_status: MessageStatusShadow(
415
- "submitted_pending_acceptance".to_string(),
416
- ),
417
- message_id: Some(message_id.to_string()),
418
- verification: Some("provider_receipt_not_observed".to_string()),
419
- stage: Some(DeliveryStage::Submit),
420
- reason: None,
421
- channel: Some("leader_acceptance_pending".to_string()),
422
- });
401
+ match super::delivery::observe_leader_receipt(state, message_id) {
402
+ super::delivery::LeaderReceiptObservation::SourceUnavailable => {
403
+ store.mark_injected_awaiting_receipt(message_id)?;
404
+ event_log.write(
405
+ "leader_receiver.receipt_source_unavailable",
406
+ serde_json::json!({
407
+ "message_id": message_id,
408
+ "result_id": result_id,
409
+ "channel": "fallback_pane",
410
+ }),
411
+ )?;
412
+ return Ok(super::delivery::leader_receipt_source_unavailable_outcome(
413
+ message_id,
414
+ ));
415
+ }
416
+ super::delivery::LeaderReceiptObservation::TokenAbsent => {
417
+ store.mark(message_id, "submitted_pending_acceptance", None)?;
418
+ event_log.write(
419
+ "leader_receiver.acceptance_pending",
420
+ serde_json::json!({
421
+ "message_id": message_id,
422
+ "result_id": result_id,
423
+ "reason": "provider_receipt_not_observed",
424
+ "channel": "fallback_pane",
425
+ }),
426
+ )?;
427
+ return Ok(DeliveryOutcome {
428
+ ok: true,
429
+ status: DeliveryStatus::RetryScheduled,
430
+ message_status: MessageStatusShadow(
431
+ "submitted_pending_acceptance".to_string(),
432
+ ),
433
+ message_id: Some(message_id.to_string()),
434
+ verification: Some("provider_receipt_not_observed".to_string()),
435
+ stage: Some(DeliveryStage::Submit),
436
+ reason: None,
437
+ channel: Some("leader_acceptance_pending".to_string()),
438
+ });
439
+ }
440
+ super::delivery::LeaderReceiptObservation::TokenObserved => {}
423
441
  }
424
442
  store.mark_delivered_with_receipt(message_id)?;
425
443
  event_log.write(
@@ -1,3 +1,4 @@
1
+ //!
1
2
  //! step 11 · messaging — delivery / scheduler / results / collect / report_result /
2
3
  //! watchers / leader-receiver / selftest 编排状态机 (ROUND-0 SKELETON).
3
4
  //!
@@ -83,11 +84,8 @@ pub use address::{parse_logical_address, LogicalAddress, LogicalAddressTarget};
83
84
  pub use delivery::{
84
85
  deliver_pending_message, deliver_pending_messages, deliver_persisted_message,
85
86
  deliver_stored_message, execute_trust_retry, handle_trust_retry_needed,
86
- record_turn_open_if_leader_to_worker,
87
- retry_injection_after_trust_auto_answer, stamp_first_send_at_if_leader_to_worker,
88
- tmux_pane_width,
87
+ retry_injection_after_trust_auto_answer,
89
88
  };
90
- pub use helpers::fail_leader_delivery;
91
89
  pub use leader_channel::{
92
90
  resolve_live_leader_channel, DirectTmuxLeaderChannel, LeaderChannelResolution,
93
91
  LeaderChannelUnbound, LiveLeaderChannel,
@@ -95,7 +93,7 @@ pub use leader_channel::{
95
93
  pub use leader_receiver::{
96
94
  deliver_to_leader_fallback_pane, enqueue_leader_mailbox_until_attach,
97
95
  mirror_peer_message_to_leader, send_to_leader_receiver,
98
- send_to_leader_receiver_with_message_id, send_to_leader_receiver_with_presentation,
96
+ send_to_leader_receiver_with_presentation,
99
97
  };
100
98
  pub use peers::allow_peer_talk;
101
99
  pub use persist::{
@@ -107,24 +105,22 @@ pub use results::{
107
105
  report_result_for_owner_team, report_result_for_owner_team_with_primary_error,
108
106
  };
109
107
  pub use scheduler::{detect_stuck_agents, fire_due_scheduled_events, stuck_cancel, stuck_list};
110
- pub use selftest::{evaluate_idle_behavior, run_comms_selftest, CommsSelftestDriver};
108
+ pub use selftest::{run_comms_selftest, CommsSelftestDriver};
111
109
  pub use send::{
112
- apply_worker_sender_bypass, send_message, session_drift_refusal, MessageTarget, SendOptions,
113
- TrustedSender,
110
+ apply_worker_sender_bypass, send_message, MessageTarget, SendOptions, TrustedSender,
114
111
  };
115
112
  pub use trust::{attempt_trust_auto_answer, TrustAnswerOutcome};
116
113
  pub use types::{
117
- ActivityStatus, AgentActivity, AlertSnapshot, AlertSuppression, AlertType, CheckEvidence,
118
- CheckKind, CheckStatus, ContractSuiteCheck, DeliveryOutcome, DeliveryRefusal, DeliveryStage,
119
- DeliveryStatus, IdleEvaluation, LeaderNotificationKey, LeaderReceiver, PaneWidthQuery,
114
+ ActivityStatus, AgentActivity, AlertType, CheckEvidence, CheckKind, CheckStatus,
115
+ ContractSuiteCheck, DeliveryOutcome, DeliveryRefusal, DeliveryStage, DeliveryStatus,
116
+ IdleEvaluation, LeaderNotificationKey, LeaderReceiver, PaneWidthQuery,
120
117
  ProviderSdkCalls, ReceiverMode, ScheduledKind, SelftestCheck, SelftestReport, SendEventPayload,
121
118
  TrustRetryPayload, WatcherNotice, WorkerRuntimeState, RESULT_DELIVERY_MAX_ATTEMPTS,
122
119
  SEND_RETRY_MAX_ATTEMPTS, TRUST_RETRY_BACKOFF_SECONDS, TRUST_RETRY_MAX_ATTEMPTS,
123
120
  };
124
121
  pub use watchers::{
125
- delivered_result_message, format_result_watcher_notification, notify_result_watchers,
126
- requeue_after_claim_leader, requeue_delivery_exhausted_watchers, result_id_from_text,
127
- retry_result_deliveries,
122
+ format_result_watcher_notification, requeue_after_claim_leader,
123
+ requeue_delivery_exhausted_watchers, result_id_from_text, retry_result_deliveries,
128
124
  };
129
125
 
130
126
  // `MessageStatusShadow` 是 [`DeliveryOutcome::message_status`] 的公有字段类型,原在模块根
@@ -1,3 +1,4 @@
1
+ //!
1
2
  //! peer messaging compatibility helpers.
2
3
 
3
4
  use std::path::Path;
@@ -7,6 +8,7 @@ use crate::message_store::MessageStore;
7
8
 
8
9
  use super::MessagingError;
9
10
 
11
+ ///
10
12
  /// `leader.py:allow_peer_talk`: persist a bidirectional peer allowlist entry.
11
13
  pub fn allow_peer_talk(
12
14
  workspace: &Path,
@@ -1,3 +1,4 @@
1
+ //!
1
2
  //! Durable boundary between resolved logical addressing and delivery/recovery.
2
3
 
3
4
  use std::path::{Path, PathBuf};
@@ -152,6 +153,7 @@ pub enum PersistResolution {
152
153
  Duplicate(String),
153
154
  }
154
155
 
156
+ ///
155
157
  /// The only production entry point that creates a durable message row.
156
158
  pub fn persist_resolved_send(
157
159
  intent: &ResolvedSendIntent,
@@ -168,7 +170,7 @@ pub fn persist_resolved_send(
168
170
  message_id: intent.requested_message_id.as_deref(),
169
171
  owner_team_id: intent.owner_team_id.as_ref().map(TeamKey::as_str),
170
172
  task_id: intent.task_id.as_ref().map(TaskId::as_str),
171
- sender: intent.sender.as_str(),
173
+ sender: intent.sender.display_name(),
172
174
  recipient: intent.recipient.as_str(),
173
175
  reply_to: intent.reply_to.as_deref(),
174
176
  requires_ack: intent.requires_ack,