@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.
- package/Cargo.lock +1 -1
- package/Cargo.toml +1 -1
- package/crates/team-agent/src/cli/adapters.rs +5 -2
- package/crates/team-agent/src/cli/attach_app_server_leader.rs +1 -0
- package/crates/team-agent/src/cli/diagnose.rs +1 -0
- package/crates/team-agent/src/cli/emit.rs +41 -7
- package/crates/team-agent/src/cli/helpers.rs +1 -0
- package/crates/team-agent/src/cli/leader.rs +6 -1
- package/crates/team-agent/src/cli/leaders.rs +2 -0
- package/crates/team-agent/src/cli/mod.rs +33 -3
- package/crates/team-agent/src/cli/named_address.rs +8 -1
- package/crates/team-agent/src/cli/profile.rs +2 -1
- package/crates/team-agent/src/cli/send/coordinator.rs +1 -0
- package/crates/team-agent/src/cli/send/mailbox.rs +3 -0
- package/crates/team-agent/src/cli/send/persist.rs +1 -0
- package/crates/team-agent/src/cli/send/presentation.rs +1 -0
- package/crates/team-agent/src/cli/send/resolve.rs +206 -1
- package/crates/team-agent/src/cli/send.rs +2 -1
- package/crates/team-agent/src/cli/spec.rs +1 -0
- package/crates/team-agent/src/cli/status.rs +2 -1
- package/crates/team-agent/src/cli/status_port/compact.rs +1 -0
- package/crates/team-agent/src/cli/status_port/format.rs +1 -0
- package/crates/team-agent/src/cli/status_port/inbox.rs +1 -0
- package/crates/team-agent/src/cli/tests/verb_profile.rs +38 -0
- package/crates/team-agent/src/cli/types.rs +3 -2
- package/crates/team-agent/src/communication_mode/mod.rs +1 -0
- package/crates/team-agent/src/compiler.rs +1 -0
- package/crates/team-agent/src/conpty/backend.rs +1 -0
- package/crates/team-agent/src/conpty/mod.rs +1 -0
- package/crates/team-agent/src/coordinator/backoff.rs +5 -8
- package/crates/team-agent/src/coordinator/conpty_shim.rs +3 -2
- package/crates/team-agent/src/coordinator/health.rs +1 -0
- package/crates/team-agent/src/coordinator/mod.rs +2 -2
- package/crates/team-agent/src/coordinator/orphan.rs +4 -116
- package/crates/team-agent/src/coordinator/runtime_detectors.rs +1 -0
- package/crates/team-agent/src/coordinator/runtime_observation.rs +1 -0
- package/crates/team-agent/src/coordinator/steps/abnormal.rs +6 -5
- package/crates/team-agent/src/coordinator/steps/delivery.rs +1 -0
- package/crates/team-agent/src/coordinator/steps/health_sync.rs +1 -0
- package/crates/team-agent/src/coordinator/steps/mod.rs +2 -0
- package/crates/team-agent/src/coordinator/steps/persist.rs +1 -0
- package/crates/team-agent/src/coordinator/steps/runtime_prompts.rs +1 -0
- package/crates/team-agent/src/coordinator/steps/session_gate.rs +1 -0
- package/crates/team-agent/src/coordinator/tests/abnormal.rs +0 -174
- package/crates/team-agent/src/coordinator/tests/api_error_recovery.rs +0 -9
- package/crates/team-agent/src/coordinator/tests/basics.rs +0 -184
- package/crates/team-agent/src/coordinator/tests/mod.rs +2 -17
- package/crates/team-agent/src/coordinator/tests/tick_core.rs +0 -42
- package/crates/team-agent/src/coordinator/tick.rs +24 -28
- package/crates/team-agent/src/coordinator/types.rs +3 -176
- package/crates/team-agent/src/db/agent_health_capture.rs +1 -0
- package/crates/team-agent/src/db/message_store.rs +2 -1
- package/crates/team-agent/src/db/migration.rs +5 -4
- package/crates/team-agent/src/db/mod.rs +1 -0
- package/crates/team-agent/src/db/schema.rs +1 -0
- package/crates/team-agent/src/diagnose/comms.rs +2 -1
- package/crates/team-agent/src/diagnose/mod.rs +1 -0
- package/crates/team-agent/src/diagnose/orphans.rs +1 -0
- package/crates/team-agent/src/layout/manager.rs +3 -7
- package/crates/team-agent/src/layout/mod.rs +2 -2
- package/crates/team-agent/src/layout/overlay.rs +6 -1
- package/crates/team-agent/src/layout/placement.rs +1 -0
- package/crates/team-agent/src/layout/recovery.rs +3 -0
- package/crates/team-agent/src/layout/runtime_sessions.rs +8 -3
- package/crates/team-agent/src/layout/sessions.rs +8 -1
- package/crates/team-agent/src/layout/tmux_endpoint.rs +3 -0
- package/crates/team-agent/src/layout/worker_env.rs +3 -0
- package/crates/team-agent/src/layout/worker_window_helpers.rs +2 -0
- package/crates/team-agent/src/leader/helpers.rs +1 -0
- package/crates/team-agent/src/leader/incident.rs +1 -0
- package/crates/team-agent/src/leader/lease.rs +27 -22
- package/crates/team-agent/src/leader/mod.rs +2 -3
- package/crates/team-agent/src/leader/owner_bind.rs +13 -3
- package/crates/team-agent/src/leader/provider_attribution.rs +1 -0
- package/crates/team-agent/src/leader/rediscover.rs +4 -17
- package/crates/team-agent/src/leader/registry.rs +3 -15
- package/crates/team-agent/src/leader/start.rs +373 -125
- package/crates/team-agent/src/leader/takeover.rs +10 -232
- package/crates/team-agent/src/leader/tests/claim_leader_mailbox_flush_contract.rs +544 -0
- package/crates/team-agent/src/leader/tests/historical_inventory_upgrade_gate_red.rs +624 -0
- package/crates/team-agent/src/leader/tests/identity.rs +7 -2
- package/crates/team-agent/src/leader/tests/idle.rs +0 -193
- package/crates/team-agent/src/leader/tests/lease_api.rs +0 -45
- package/crates/team-agent/src/leader/tests/mod.rs +4 -41
- package/crates/team-agent/src/leader/tests/rehomed_env.rs +83 -0
- package/crates/team-agent/src/leader/tests/team_in_team_state_scope_red.rs +1273 -0
- package/crates/team-agent/src/leader/tests/terminal_and_replay_vs_rerender_invariants_red.rs +417 -0
- package/crates/team-agent/src/leader/tests/wake_start_owner.rs +22 -103
- package/crates/team-agent/src/leader/types.rs +1 -28
- package/crates/team-agent/src/lib.rs +3 -0
- package/crates/team-agent/src/lifecycle/display.rs +7 -1
- package/crates/team-agent/src/lifecycle/helpers.rs +3 -1
- package/crates/team-agent/src/lifecycle/launch/add_agent.rs +2 -2
- package/crates/team-agent/src/lifecycle/launch/fork_agent/completion.rs +1 -0
- package/crates/team-agent/src/lifecycle/launch/fork_entry.rs +1 -0
- package/crates/team-agent/src/lifecycle/launch/fork_finalize.rs +1 -0
- package/crates/team-agent/src/lifecycle/launch/plan.rs +2 -2
- package/crates/team-agent/src/lifecycle/launch/quick_start.rs +4 -26
- package/crates/team-agent/src/lifecycle/launch/readiness.rs +0 -27
- package/crates/team-agent/src/lifecycle/launch/spawn.rs +1 -27
- package/crates/team-agent/src/lifecycle/launch/spec_state.rs +4 -32
- package/crates/team-agent/src/lifecycle/launch/state_projection.rs +1 -0
- package/crates/team-agent/src/lifecycle/launch.rs +11 -12
- package/crates/team-agent/src/lifecycle/mod.rs +2 -1
- package/crates/team-agent/src/lifecycle/restart/agent.rs +3 -3
- package/crates/team-agent/src/lifecycle/restart/orchestrator.rs +2 -2
- package/crates/team-agent/src/lifecycle/restart/rebuild.rs +13 -5
- package/crates/team-agent/src/lifecycle/restart/remove.rs +1 -1
- package/crates/team-agent/src/lifecycle/restart/selection.rs +3 -3
- package/crates/team-agent/src/lifecycle/restart.rs +13 -11
- package/crates/team-agent/src/lifecycle/tests/acceptance_b_batch_red.rs +1007 -0
- package/crates/team-agent/src/lifecycle/tests/b0_legacy_snapshot_nonauthority_contract.rs +265 -0
- package/crates/team-agent/src/lifecycle/tests/b0_reader_hideone_audit_contract.rs +459 -0
- package/crates/team-agent/src/lifecycle/tests/behavioral_diff_264_red.rs +849 -0
- package/crates/team-agent/src/lifecycle/tests/claude_compatible_config_red.rs +323 -0
- package/crates/team-agent/src/lifecycle/tests/claude_profile_launch_red.rs +423 -0
- package/crates/team-agent/src/lifecycle/tests/clone_fork_copilot_perms_red.rs +737 -0
- package/crates/team-agent/src/lifecycle/tests/codex_mcp_approval_inheritance_red.rs +1187 -0
- package/crates/team-agent/src/lifecycle/tests/codex_weak_window_attribution_red.rs +683 -0
- package/crates/team-agent/src/lifecycle/tests/communication_mode_runtime_contract_red.rs +394 -0
- package/crates/team-agent/src/lifecycle/tests/copilot_provider_red.rs +1856 -0
- package/crates/team-agent/src/lifecycle/tests/core_034_real_red.rs +917 -0
- package/crates/team-agent/src/lifecycle/tests/display_adaptive_red.rs +481 -0
- package/crates/team-agent/src/lifecycle/tests/f032_startup_prompt_best_effort_red.rs +301 -0
- package/crates/team-agent/src/lifecycle/tests/harvest2_a_batch_red.rs +516 -0
- package/crates/team-agent/src/lifecycle/tests/host_cotenant_death_p0_contract.rs +986 -0
- package/crates/team-agent/src/lifecycle/tests/lifecycle_rollback_red.rs +651 -0
- package/crates/team-agent/src/lifecycle/tests/main_preserved.rs +2 -0
- package/crates/team-agent/src/lifecycle/tests/quick_start_worker_readiness_red.rs +332 -0
- package/crates/team-agent/src/lifecycle/tests/realmachine_clusters_1_6_red.rs +846 -0
- package/crates/team-agent/src/lifecycle/tests/realmachine_residual_g1_g4_red.rs +648 -0
- package/crates/team-agent/src/lifecycle/tests/restart_build_before_destroy_0540_contract.rs +910 -0
- package/crates/team-agent/src/lifecycle/tests/restart_liveness_red.rs +630 -0
- package/crates/team-agent/src/lifecycle/tests/restart_rebind_hotfix_252_red.rs +1083 -0
- package/crates/team-agent/src/lifecycle/tests/restart_session_capture_red.rs +1677 -0
- package/crates/team-agent/src/lifecycle/tests/resume_recover_red.rs +410 -0
- package/crates/team-agent/src/lifecycle/tests/stale_team_saveconflict_contract.rs +428 -0
- package/crates/team-agent/src/lifecycle/tests/startup_latency_contract.rs +1032 -0
- package/crates/team-agent/src/lifecycle/tests/status_credential_redaction_contract.rs +869 -0
- package/crates/team-agent/src/lifecycle/tests/subprep_codex_trust_roundtrip_red.rs +1249 -0
- package/crates/team-agent/src/lifecycle/tests/swallow_batch4_semantics_red.rs +342 -0
- package/crates/team-agent/src/lifecycle/tests/team_in_team_identity_scope_red.rs +542 -0
- package/crates/team-agent/src/lifecycle/tests/team_in_team_sibling_quick_start_red.rs +1103 -0
- package/crates/team-agent/src/lifecycle/tests/team_in_team_state_scope_red.rs +1276 -0
- package/crates/team-agent/src/lifecycle/tests/team_key_retirement_roster_red.rs +145 -0
- package/crates/team-agent/src/lifecycle/tests/team_key_retirement_txn_red.rs +603 -0
- package/crates/team-agent/src/lifecycle/tests/test_isolation_escape_contract.rs +837 -0
- package/crates/team-agent/src/lifecycle/tests/upgrade_compat_0211_red.rs +928 -0
- package/crates/team-agent/src/lifecycle/tests/verify_rs031_window_consistency_red.rs +951 -0
- package/crates/team-agent/src/lifecycle/tests/worker_dangerous_bypass_argv_red.rs +327 -0
- package/crates/team-agent/src/lifecycle/tests/worker_spawn_env_red.rs +760 -0
- package/crates/team-agent/src/lifecycle/tests.rs +59 -0
- package/crates/team-agent/src/lifecycle/types.rs +0 -9
- package/crates/team-agent/src/mcp_server/helpers.rs +1 -0
- package/crates/team-agent/src/mcp_server/lifecycle_tools/mod.rs +1 -0
- package/crates/team-agent/src/mcp_server/lifecycle_tools/state_status.rs +1 -0
- package/crates/team-agent/src/mcp_server/mod.rs +1 -0
- package/crates/team-agent/src/mcp_server/normalize.rs +4 -3
- package/crates/team-agent/src/mcp_server/tools.rs +1 -0
- package/crates/team-agent/src/mcp_server/types.rs +1 -18
- package/crates/team-agent/src/mcp_server/wire.rs +5 -5
- package/crates/team-agent/src/messaging/activity.rs +1 -0
- package/crates/team-agent/src/messaging/address.rs +1 -0
- package/crates/team-agent/src/messaging/delivery.rs +4 -3
- package/crates/team-agent/src/messaging/helpers.rs +2 -1
- package/crates/team-agent/src/messaging/leader_channel.rs +1 -0
- package/crates/team-agent/src/messaging/leader_receiver.rs +2 -1
- package/crates/team-agent/src/messaging/mod.rs +10 -14
- package/crates/team-agent/src/messaging/peers.rs +2 -0
- package/crates/team-agent/src/messaging/persist.rs +3 -1
- package/crates/team-agent/src/messaging/presentation.rs +2 -1
- package/crates/team-agent/src/messaging/results.rs +1 -0
- package/crates/team-agent/src/messaging/scheduler.rs +1 -0
- package/crates/team-agent/src/messaging/selftest.rs +1 -1
- package/crates/team-agent/src/messaging/send.rs +41 -8
- package/crates/team-agent/src/messaging/tests/mod.rs +5 -0
- package/crates/team-agent/src/messaging/types.rs +2 -2
- package/crates/team-agent/src/messaging/watchers.rs +19 -13
- package/crates/team-agent/src/model/enums.rs +1 -0
- package/crates/team-agent/src/model/errors.rs +1 -0
- package/crates/team-agent/src/model/ids.rs +1 -0
- package/crates/team-agent/src/model/mod.rs +1 -0
- package/crates/team-agent/src/model/name_similarity.rs +1 -0
- package/crates/team-agent/src/model/pane_authority_refusal.rs +1 -0
- package/crates/team-agent/src/model/paths.rs +1 -0
- package/crates/team-agent/src/model/permissions.rs +3 -2
- package/crates/team-agent/src/model/routing.rs +1 -0
- package/crates/team-agent/src/model/spec.rs +1 -0
- package/crates/team-agent/src/model/task_graph.rs +1 -0
- package/crates/team-agent/src/model/yaml/tests.rs +1 -0
- package/crates/team-agent/src/model/yaml.rs +1 -0
- package/crates/team-agent/src/packaging/install.rs +9 -147
- package/crates/team-agent/src/packaging/migrate.rs +2 -0
- package/crates/team-agent/src/packaging/mod.rs +1 -0
- package/crates/team-agent/src/packaging/repair.rs +2 -0
- package/crates/team-agent/src/packaging/tests.rs +29 -218
- package/crates/team-agent/src/packaging/types.rs +8 -15
- package/crates/team-agent/src/platform/argv.rs +4 -0
- package/crates/team-agent/src/platform/errors.rs +10 -1
- package/crates/team-agent/src/platform/file_lock.rs +4 -157
- package/crates/team-agent/src/platform/mod.rs +0 -61
- package/crates/team-agent/src/platform/process.rs +1 -0
- package/crates/team-agent/src/provider/adapter.rs +1 -0
- package/crates/team-agent/src/provider/adapters/claude.rs +1 -0
- package/crates/team-agent/src/provider/adapters/claude_fork.rs +1 -0
- package/crates/team-agent/src/provider/adapters/codex.rs +1 -0
- package/crates/team-agent/src/provider/adapters/copilot.rs +1 -0
- package/crates/team-agent/src/provider/adapters/copilot_fork.rs +1 -0
- package/crates/team-agent/src/provider/adapters/fake.rs +1 -0
- package/crates/team-agent/src/provider/adapters/mod.rs +1 -0
- package/crates/team-agent/src/provider/approvals/mod.rs +1 -0
- package/crates/team-agent/src/provider/approvals/parsing.rs +2 -5
- package/crates/team-agent/src/provider/approvals/runtime_prompts.rs +6 -5
- package/crates/team-agent/src/provider/classify.rs +1 -0
- package/crates/team-agent/src/provider/faults.rs +1 -26
- package/crates/team-agent/src/provider/helpers.rs +1 -0
- package/crates/team-agent/src/provider/mod.rs +1 -1
- package/crates/team-agent/src/provider/session/capture.rs +1 -4
- package/crates/team-agent/src/provider/session/context_fork/claude.rs +1 -0
- package/crates/team-agent/src/provider/session/context_fork/codex.rs +1 -0
- package/crates/team-agent/src/provider/session/context_fork/outcome.rs +1 -0
- package/crates/team-agent/src/provider/session/context_fork.rs +1 -0
- package/crates/team-agent/src/provider/session/mod.rs +2 -4
- package/crates/team-agent/src/provider/session/resume.rs +2 -209
- package/crates/team-agent/src/provider/session_scan/claude.rs +1 -0
- package/crates/team-agent/src/provider/session_scan/codex.rs +1 -0
- package/crates/team-agent/src/provider/session_scan/common.rs +1 -0
- package/crates/team-agent/src/provider/session_scan/copilot.rs +1 -0
- package/crates/team-agent/src/provider/session_scan.rs +1 -42
- package/crates/team-agent/src/provider/startup_prompt.rs +1 -0
- package/crates/team-agent/src/provider/types.rs +1 -0
- package/crates/team-agent/src/provider/wire.rs +1 -0
- package/crates/team-agent/src/state/identity.rs +16 -5
- package/crates/team-agent/src/state/identity_keys.rs +1 -0
- package/crates/team-agent/src/state/mod.rs +2 -0
- package/crates/team-agent/src/state/owner_gate.rs +5 -0
- package/crates/team-agent/src/state/ownership.rs +10 -4
- package/crates/team-agent/src/state/paths.rs +12 -0
- package/crates/team-agent/src/state/persist.rs +9 -3
- package/crates/team-agent/src/state/projection.rs +15 -2
- package/crates/team-agent/src/state/repository/intent.rs +1 -0
- package/crates/team-agent/src/state/repository/tests.rs +1 -0
- package/crates/team-agent/src/state/repository.rs +7 -0
- package/crates/team-agent/src/state/selector.rs +1 -0
- package/crates/team-agent/src/tmux_backend/tests.rs +39 -0
- package/crates/team-agent/src/tmux_backend.rs +63 -0
- package/crates/team-agent/src/transport.rs +15 -0
- package/package.json +4 -4
- package/crates/team-agent/src/leader/inject.rs +0 -33
- package/crates/team-agent/src/provider/command.rs +0 -80
|
@@ -2,6 +2,7 @@
|
|
|
2
2
|
use super::*;
|
|
3
3
|
use serde_json::json;
|
|
4
4
|
use std::sync::atomic::{AtomicU32, Ordering};
|
|
5
|
+
use std::sync::OnceLock;
|
|
5
6
|
|
|
6
7
|
static SEQ: AtomicU32 = AtomicU32::new(0);
|
|
7
8
|
|
|
@@ -20,6 +21,24 @@ fn sess(s: &str) -> SessionName {
|
|
|
20
21
|
SessionName(s.to_string())
|
|
21
22
|
}
|
|
22
23
|
|
|
24
|
+
pub(crate) fn test_binary_path() -> &'static str {
|
|
25
|
+
static PATH: OnceLock<String> = OnceLock::new();
|
|
26
|
+
PATH.get_or_init(|| {
|
|
27
|
+
if let Ok(path) = std::env::var("CARGO_BIN_EXE_team-agent") {
|
|
28
|
+
return path;
|
|
29
|
+
}
|
|
30
|
+
let current = std::env::current_exe().expect("test executable path");
|
|
31
|
+
current
|
|
32
|
+
.parent()
|
|
33
|
+
.and_then(|deps| deps.parent())
|
|
34
|
+
.map(|target| target.join("team-agent"))
|
|
35
|
+
.expect("team-agent test binary path")
|
|
36
|
+
.to_string_lossy()
|
|
37
|
+
.into_owned()
|
|
38
|
+
})
|
|
39
|
+
.as_str()
|
|
40
|
+
}
|
|
41
|
+
|
|
23
42
|
mod agent_ops;
|
|
24
43
|
mod core;
|
|
25
44
|
mod lane_ops;
|
|
@@ -29,3 +48,43 @@ mod main_preserved;
|
|
|
29
48
|
mod phase_b_contracts;
|
|
30
49
|
mod phase_golden;
|
|
31
50
|
mod restart;
|
|
51
|
+
mod b0_legacy_snapshot_nonauthority_contract;
|
|
52
|
+
mod b0_reader_hideone_audit_contract;
|
|
53
|
+
mod behavioral_diff_264_red;
|
|
54
|
+
mod claude_profile_launch_red;
|
|
55
|
+
mod codex_mcp_approval_inheritance_red;
|
|
56
|
+
mod codex_weak_window_attribution_red;
|
|
57
|
+
mod copilot_provider_red;
|
|
58
|
+
mod display_adaptive_red;
|
|
59
|
+
mod core_034_real_red;
|
|
60
|
+
mod f032_startup_prompt_best_effort_red;
|
|
61
|
+
mod harvest2_a_batch_red;
|
|
62
|
+
mod host_cotenant_death_p0_contract;
|
|
63
|
+
mod lifecycle_rollback_red;
|
|
64
|
+
mod quick_start_worker_readiness_red;
|
|
65
|
+
mod realmachine_clusters_1_6_red;
|
|
66
|
+
mod realmachine_residual_g1_g4_red;
|
|
67
|
+
mod restart_build_before_destroy_0540_contract;
|
|
68
|
+
mod restart_liveness_red;
|
|
69
|
+
mod restart_rebind_hotfix_252_red;
|
|
70
|
+
mod restart_session_capture_red;
|
|
71
|
+
mod resume_recover_red;
|
|
72
|
+
mod stale_team_saveconflict_contract;
|
|
73
|
+
mod startup_latency_contract;
|
|
74
|
+
mod status_credential_redaction_contract;
|
|
75
|
+
mod subprep_codex_trust_roundtrip_red;
|
|
76
|
+
mod swallow_batch4_semantics_red;
|
|
77
|
+
mod team_in_team_identity_scope_red;
|
|
78
|
+
mod team_in_team_sibling_quick_start_red;
|
|
79
|
+
mod team_in_team_state_scope_red;
|
|
80
|
+
mod team_key_retirement_roster_red;
|
|
81
|
+
mod team_key_retirement_txn_red;
|
|
82
|
+
mod test_isolation_escape_contract;
|
|
83
|
+
mod upgrade_compat_0211_red;
|
|
84
|
+
mod verify_rs031_window_consistency_red;
|
|
85
|
+
mod worker_dangerous_bypass_argv_red;
|
|
86
|
+
mod worker_spawn_env_red;
|
|
87
|
+
mod acceptance_b_batch_red;
|
|
88
|
+
mod claude_compatible_config_red;
|
|
89
|
+
mod communication_mode_runtime_contract_red;
|
|
90
|
+
mod clone_fork_copilot_perms_red;
|
|
@@ -16,15 +16,6 @@ use super::DisplayBackend;
|
|
|
16
16
|
// CROSS-LANE PLACEHOLDERS(13/14/15 兄弟 lane 尚未交付;leader 集成时 reconcile)
|
|
17
17
|
// ===========================================================================
|
|
18
18
|
|
|
19
|
-
/// step8 provider 还未暴露的 launch/resume/fork 命令构造门面。lifecycle 经它构造
|
|
20
|
-
/// provider 命令字符串(`shell_command_for_agent`/`shell_resume_command_for_agent`/
|
|
21
|
-
/// `shell_fork_command_for_agent`,`runtime` 自由函数)—— provider lane 落地后替换为
|
|
22
|
-
/// 真实 `provider::shell_*` API。**PLACEHOLDER**:仅占位 argv,字段映射由 provider lane 定。
|
|
23
|
-
#[derive(Debug, Clone, PartialEq, Eq)]
|
|
24
|
-
pub struct ShellCommand {
|
|
25
|
-
pub argv: Vec<String>,
|
|
26
|
-
}
|
|
27
|
-
|
|
28
19
|
/// `EventLog` 已在 step4 落地,但 lifecycle 发射的 typed `EventKind` 名集(`lifecycle.*`/
|
|
29
20
|
/// `restart.*`/`display.*`)是 step4 owned 的稳定事件名(JSON 名与 Python 一致)。
|
|
30
21
|
/// **PLACEHOLDER**:此处仅命名 lifecycle 关心的事件名常量集,leader 集成时映射到
|
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
//!
|
|
1
2
|
//! step 14a · mcp_server::normalize — string-alias regularization + result compaction.
|
|
2
3
|
|
|
3
4
|
use serde_json::Value;
|
|
@@ -28,9 +29,9 @@ pub fn normalize_result_status(value: Option<&str>) -> ResultStatus {
|
|
|
28
29
|
normalize_result_status_observed(value).0
|
|
29
30
|
}
|
|
30
31
|
|
|
31
|
-
/// The observed variant: `.1` carries the raw unrecognized literal
|
|
32
|
-
///
|
|
33
|
-
|
|
32
|
+
/// The internal observed variant: `.1` carries the raw unrecognized literal for
|
|
33
|
+
/// callers that need to retain it.
|
|
34
|
+
fn normalize_result_status_observed(value: Option<&str>) -> (ResultStatus, Option<String>) {
|
|
34
35
|
let token = normalize_token(value);
|
|
35
36
|
if token.is_empty() {
|
|
36
37
|
return (ResultStatus::Success, None);
|
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
//!
|
|
1
2
|
//! step 14a · mcp_server::types — wire enums / envelopes / normalized-result carriers.
|
|
2
3
|
|
|
3
4
|
use serde::{Deserialize, Serialize};
|
|
@@ -210,24 +211,6 @@ pub struct RpcError {
|
|
|
210
211
|
pub message: String,
|
|
211
212
|
}
|
|
212
213
|
|
|
213
|
-
/// The `tools/call` result wrapper (`server.py:74-86`): `{content:[{type:"text",
|
|
214
|
-
/// text:<json>}], isError:<bool>}`. `text` is the JSON-encoded [`ToolResult`]; the
|
|
215
|
-
/// `is_error` flag mirrors `result.get("ok") is False`.
|
|
216
|
-
#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
|
|
217
|
-
pub struct ToolCallResult {
|
|
218
|
-
pub content: Vec<ToolCallContent>,
|
|
219
|
-
#[serde(rename = "isError")]
|
|
220
|
-
pub is_error: bool,
|
|
221
|
-
}
|
|
222
|
-
|
|
223
|
-
/// One `content[]` block — always `{type:"text", text:<json>}` here.
|
|
224
|
-
#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)]
|
|
225
|
-
pub struct ToolCallContent {
|
|
226
|
-
#[serde(rename = "type")]
|
|
227
|
-
pub kind: String,
|
|
228
|
-
pub text: String,
|
|
229
|
-
}
|
|
230
|
-
|
|
231
214
|
/// A successful tool result body — the compacted delegate result
|
|
232
215
|
/// (`normalize._compact_tool_result`, `normalize.py:6-64`). The whitelist-key
|
|
233
216
|
/// compaction (ok/error key sets + `fanout_*` extras + `acknowledged_count`) lives
|
|
@@ -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};
|
|
@@ -86,16 +87,15 @@ pub fn dispatch(tools: &TeamOrchestratorTools, request: &Value) -> ToolResult {
|
|
|
86
87
|
/// `handle_mcp(tools, request)` (`server.py:46-91`): the JSON-RPC router.
|
|
87
88
|
/// - `initialize` → serverInfo `team_orchestrator` v0.1.4 + echoed protocolVersion.
|
|
88
89
|
/// - `tools/list` → `{tools: TOOLS}`.
|
|
89
|
-
/// - `tools/call` → run [`dispatch`], wrap
|
|
90
|
-
/// dispatch returned `Err`); the
|
|
91
|
-
/// 69-72`) classifies a caught
|
|
92
|
-
/// `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`.
|
|
93
94
|
/// - `notifications/*` → `Ok(None)` (no frame; **must not** emit to stdout).
|
|
94
95
|
/// - unknown method → `-32601` error frame.
|
|
95
96
|
/// Returns `Ok(None)` only for the notifications path; every other branch yields a
|
|
96
97
|
/// frame.
|
|
97
98
|
///
|
|
98
|
-
/// [`ToolCallResult`]: super::ToolCallResult
|
|
99
99
|
pub fn handle_mcp(
|
|
100
100
|
tools: &TeamOrchestratorTools,
|
|
101
101
|
request: &Value,
|
|
@@ -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
|
}));
|
|
@@ -2254,7 +2255,7 @@ pub fn execute_trust_retry(
|
|
|
2254
2255
|
|
|
2255
2256
|
/// `_record_turn_open_if_leader_to_worker` (`delivery.py:430`):**take-over arm 来自真实投递**
|
|
2256
2257
|
/// (card §121) —— 仅 leader→worker 注入/投递成功后才 arm,绝不凭空 arm。
|
|
2257
|
-
pub fn record_turn_open_if_leader_to_worker(
|
|
2258
|
+
pub(crate) fn record_turn_open_if_leader_to_worker(
|
|
2258
2259
|
workspace: &Path,
|
|
2259
2260
|
state: &serde_json::Value,
|
|
2260
2261
|
sender: &str,
|
|
@@ -2413,7 +2414,7 @@ fn arm_turn_open(state: &mut serde_json::Value, recipient: &str, message_id: &Op
|
|
|
2413
2414
|
|
|
2414
2415
|
/// `_stamp_first_send_at_if_leader_to_worker` (`delivery.py:380`):首次 leader→worker 投递戳
|
|
2415
2416
|
/// `first_send_at` (step 13 restart Route B atomicity 决策读它)。
|
|
2416
|
-
pub fn stamp_first_send_at_if_leader_to_worker(
|
|
2417
|
+
pub(crate) fn stamp_first_send_at_if_leader_to_worker(
|
|
2417
2418
|
workspace: &Path,
|
|
2418
2419
|
state: &serde_json::Value,
|
|
2419
2420
|
sender: &str,
|
|
@@ -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,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,
|
|
@@ -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
|
-
|
|
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
|
-
|
|
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::{
|
|
108
|
+
pub use selftest::{run_comms_selftest, CommsSelftestDriver};
|
|
111
109
|
pub use send::{
|
|
112
|
-
apply_worker_sender_bypass, send_message,
|
|
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,
|
|
118
|
-
|
|
119
|
-
|
|
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
|
-
|
|
126
|
-
|
|
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.
|
|
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,
|
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
//!
|
|
1
2
|
//! Typed presentation metadata shared by message and result ingress.
|
|
2
3
|
|
|
3
4
|
use serde::{Deserialize, Serialize};
|
|
@@ -256,7 +257,7 @@ pub fn normalize_send_presentation(
|
|
|
256
257
|
})
|
|
257
258
|
}
|
|
258
259
|
|
|
259
|
-
pub fn normalize_presentation(value: Option<&Value>) -> (PresentationRequest, Option<String>) {
|
|
260
|
+
pub(crate) fn normalize_presentation(value: Option<&Value>) -> (PresentationRequest, Option<String>) {
|
|
260
261
|
let Some(value) = value else {
|
|
261
262
|
return (PresentationRequest::default(), None);
|
|
262
263
|
};
|
|
@@ -291,7 +291,7 @@ fn message_owner_team(db_path: &Path, message_id: &str) -> Result<Option<String>
|
|
|
291
291
|
}
|
|
292
292
|
|
|
293
293
|
/// `evaluate_idle_behavior` (`diagnose/comms.py:50`):idle 分类准确性评估。零 token,走 driver。
|
|
294
|
-
pub fn evaluate_idle_behavior(
|
|
294
|
+
pub(crate) fn evaluate_idle_behavior(
|
|
295
295
|
workspace: &Path,
|
|
296
296
|
agent_id: &str,
|
|
297
297
|
claimed_status: &str,
|
|
@@ -36,21 +36,54 @@ pub enum MessageTarget {
|
|
|
36
36
|
/// Public CLI/MCP inputs never construct this value from a caller-supplied
|
|
37
37
|
/// string. The wrapper keeps that trust boundary visible throughout delivery
|
|
38
38
|
/// instead of degrading the identity back to an untyped option field.
|
|
39
|
-
#[derive(Debug, Clone, PartialEq, Eq
|
|
40
|
-
|
|
41
|
-
|
|
39
|
+
#[derive(Debug, Clone, PartialEq, Eq)]
|
|
40
|
+
pub struct TrustedSender {
|
|
41
|
+
agent_id: AgentId,
|
|
42
|
+
full_name: Option<String>,
|
|
43
|
+
}
|
|
42
44
|
|
|
43
45
|
impl TrustedSender {
|
|
44
46
|
pub fn from_runtime_identity(agent_id: AgentId) -> Self {
|
|
45
|
-
Self
|
|
47
|
+
Self {
|
|
48
|
+
agent_id,
|
|
49
|
+
full_name: None,
|
|
50
|
+
}
|
|
51
|
+
}
|
|
52
|
+
|
|
53
|
+
pub fn from_runtime_identity_with_source(
|
|
54
|
+
agent_id: AgentId,
|
|
55
|
+
workspace: impl std::fmt::Display,
|
|
56
|
+
team: &str,
|
|
57
|
+
) -> Self {
|
|
58
|
+
let full_name = format!("{}::{}/{}", workspace, team, agent_id.as_str());
|
|
59
|
+
Self {
|
|
60
|
+
agent_id,
|
|
61
|
+
full_name: Some(full_name),
|
|
62
|
+
}
|
|
46
63
|
}
|
|
47
64
|
|
|
48
65
|
pub fn leader() -> Self {
|
|
49
|
-
Self
|
|
66
|
+
Self {
|
|
67
|
+
agent_id: AgentId::new("leader"),
|
|
68
|
+
full_name: None,
|
|
69
|
+
}
|
|
50
70
|
}
|
|
51
71
|
|
|
52
72
|
pub fn as_str(&self) -> &str {
|
|
53
|
-
self.
|
|
73
|
+
self.agent_id.as_str()
|
|
74
|
+
}
|
|
75
|
+
|
|
76
|
+
pub fn display_name(&self) -> &str {
|
|
77
|
+
self.full_name.as_deref().unwrap_or_else(|| self.as_str())
|
|
78
|
+
}
|
|
79
|
+
}
|
|
80
|
+
|
|
81
|
+
impl serde::Serialize for TrustedSender {
|
|
82
|
+
fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
|
|
83
|
+
where
|
|
84
|
+
S: serde::Serializer,
|
|
85
|
+
{
|
|
86
|
+
serializer.serialize_str(self.display_name())
|
|
54
87
|
}
|
|
55
88
|
}
|
|
56
89
|
|
|
@@ -141,7 +174,7 @@ pub fn send_message(
|
|
|
141
174
|
"leader",
|
|
142
175
|
content,
|
|
143
176
|
opts.task_id.as_ref(),
|
|
144
|
-
opts.sender.
|
|
177
|
+
opts.sender.display_name(),
|
|
145
178
|
opts.requires_ack,
|
|
146
179
|
None,
|
|
147
180
|
opts.message_id.as_deref(),
|
|
@@ -742,7 +775,7 @@ pub fn apply_worker_sender_bypass(
|
|
|
742
775
|
|
|
743
776
|
/// `session_drift_refusal` (`session_drift.py:69`):send 时检测会话漂移并拒绝。
|
|
744
777
|
/// `None` = 无漂移 (放行);`Some` = 拒绝 [`DeliveryOutcome`] (reason=`SessionDrift`)。
|
|
745
|
-
pub fn session_drift_refusal(
|
|
778
|
+
pub(crate) fn session_drift_refusal(
|
|
746
779
|
state: &serde_json::Value,
|
|
747
780
|
target: &str,
|
|
748
781
|
leader_id: &str,
|
|
@@ -1,5 +1,10 @@
|
|
|
1
1
|
#![allow(clippy::unwrap_used, clippy::expect_used, clippy::panic)]
|
|
2
2
|
use super::*;
|
|
3
|
+
use super::delivery::tmux_pane_width;
|
|
4
|
+
use super::helpers::fail_leader_delivery;
|
|
5
|
+
use super::selftest::evaluate_idle_behavior;
|
|
6
|
+
use super::send::session_drift_refusal;
|
|
7
|
+
use super::watchers::{delivered_result_message, notify_result_watchers};
|
|
3
8
|
use std::collections::BTreeMap;
|
|
4
9
|
use std::path::{Path, PathBuf};
|
|
5
10
|
|
|
@@ -407,14 +407,14 @@ pub struct IdleEvaluation {
|
|
|
407
407
|
|
|
408
408
|
/// 抑制快照 (card §50;`scheduler.py:383` `_agent_alert_snapshot`)。清除判据靠 snapshot diff。
|
|
409
409
|
#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)]
|
|
410
|
-
pub struct AlertSnapshot {
|
|
410
|
+
pub(crate) struct AlertSnapshot {
|
|
411
411
|
pub assigned_task_ids: Vec<TaskId>,
|
|
412
412
|
pub delivered_message_ids: Vec<String>,
|
|
413
413
|
}
|
|
414
414
|
|
|
415
415
|
/// 告警抑制条目 (card §50;`scheduler.py:287`)。
|
|
416
416
|
#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)]
|
|
417
|
-
pub struct AlertSuppression {
|
|
417
|
+
pub(crate) struct AlertSuppression {
|
|
418
418
|
pub suppressed_at: String,
|
|
419
419
|
pub suppressed_by: String,
|
|
420
420
|
pub snapshot: AlertSnapshot,
|
|
@@ -5,12 +5,13 @@ use std::path::Path;
|
|
|
5
5
|
use rusqlite::{params, OptionalExtension};
|
|
6
6
|
|
|
7
7
|
use crate::event_log::EventLog;
|
|
8
|
+
use crate::leader::LeaderIncident;
|
|
8
9
|
use crate::message_store::{MessageStore, NotificationClaimParams};
|
|
9
10
|
use crate::model::ids::{TaskId, TeamKey};
|
|
10
11
|
use crate::transport::PaneId;
|
|
11
12
|
|
|
12
13
|
#[derive(Debug, Clone, PartialEq, Eq)]
|
|
13
|
-
pub struct RecoveryIncident {
|
|
14
|
+
pub(crate) struct RecoveryIncident {
|
|
14
15
|
pub incident_id: String,
|
|
15
16
|
pub occurred_at: String,
|
|
16
17
|
}
|
|
@@ -20,7 +21,7 @@ use super::{MessagingError, WatcherNotice, RESULT_DELIVERY_MAX_ATTEMPTS};
|
|
|
20
21
|
/// `notify_result_watchers` (`result_delivery.py:38`):匹配 + 去重 + (有界) 投递 result 给 leader
|
|
21
22
|
/// watcher。**恰好一次** (Gap 32/38):同 result_id 多 watcher → 1 次注入,余 `superseded`。
|
|
22
23
|
/// 去重唯一原语 = [`MessageStore::claim_leader_notification_delivery`]。`collect`/coordinator tick 调。
|
|
23
|
-
pub fn notify_result_watchers(
|
|
24
|
+
pub(crate) fn notify_result_watchers(
|
|
24
25
|
workspace: &Path,
|
|
25
26
|
result: &serde_json::Value,
|
|
26
27
|
event_log: &EventLog,
|
|
@@ -475,20 +476,25 @@ pub fn requeue_after_claim_leader(
|
|
|
475
476
|
|
|
476
477
|
pub fn recover_watchers_for_incident(
|
|
477
478
|
workspace: &Path,
|
|
478
|
-
store: &MessageStore,
|
|
479
479
|
event_log: &EventLog,
|
|
480
480
|
owner_team_id: &TeamKey,
|
|
481
481
|
claimed_pane_id: &PaneId,
|
|
482
|
-
incident:
|
|
482
|
+
incident: LeaderIncident,
|
|
483
483
|
) -> Result<Vec<WatcherNotice>, MessagingError> {
|
|
484
|
-
|
|
485
|
-
|
|
486
|
-
|
|
487
|
-
|
|
488
|
-
|
|
489
|
-
|
|
490
|
-
|
|
491
|
-
|
|
484
|
+
match incident {
|
|
485
|
+
LeaderIncident::LeaderAttached => Ok(Vec::new()),
|
|
486
|
+
LeaderIncident::LeaderClaimed => {
|
|
487
|
+
let store = MessageStore::open(workspace)?;
|
|
488
|
+
requeue_after_claim_leader(
|
|
489
|
+
workspace,
|
|
490
|
+
&store,
|
|
491
|
+
event_log,
|
|
492
|
+
owner_team_id,
|
|
493
|
+
claimed_pane_id,
|
|
494
|
+
None,
|
|
495
|
+
)
|
|
496
|
+
}
|
|
497
|
+
}
|
|
492
498
|
}
|
|
493
499
|
|
|
494
500
|
/// 0.5.5 gate054 round-2: attach-leader (and claim-leader) requeue for leader messages
|
|
@@ -601,7 +607,7 @@ pub fn requeue_delivery_exhausted_watchers(
|
|
|
601
607
|
|
|
602
608
|
/// `delivered_result_message` (`result_delivery.py:394`):内容级去重 —— 查某 result_id 是否已有
|
|
603
609
|
/// 投递的 leader 通知消息。
|
|
604
|
-
pub fn delivered_result_message(
|
|
610
|
+
pub(crate) fn delivered_result_message(
|
|
605
611
|
store: &MessageStore,
|
|
606
612
|
result_id: &str,
|
|
607
613
|
task_id: Option<&TaskId>,
|