@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
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
//!
|
|
1
2
|
//! Process argv / environ probe.
|
|
2
3
|
//!
|
|
3
4
|
//! ## Batch 4 real implementation (leader msg_0689a63a9e40)
|
|
@@ -41,6 +42,7 @@
|
|
|
41
42
|
//! same disabled default. **This is intentional**: leaking a
|
|
42
43
|
//! bypass via unknown argv would be a MUST-NOT-13 假绿 failure.
|
|
43
44
|
|
|
45
|
+
///
|
|
44
46
|
/// Return the argv tokens for `pid`, or `None` if unavailable on
|
|
45
47
|
/// this platform.
|
|
46
48
|
///
|
|
@@ -72,6 +74,7 @@ pub fn argv_tokens(pid: u32) -> Option<Vec<String>> {
|
|
|
72
74
|
}
|
|
73
75
|
}
|
|
74
76
|
|
|
77
|
+
///
|
|
75
78
|
/// Return the environ text (NUL-joined) for `pid`, or `None`.
|
|
76
79
|
///
|
|
77
80
|
/// - Linux: `/proc/<pid>/environ` verbatim (migration of
|
|
@@ -91,6 +94,7 @@ pub fn environ_text(pid: u32) -> Option<String> {
|
|
|
91
94
|
}
|
|
92
95
|
}
|
|
93
96
|
|
|
97
|
+
///
|
|
94
98
|
/// Return the parent PID of `pid`, or `None` if unavailable.
|
|
95
99
|
///
|
|
96
100
|
/// Byte-preserving migration of `lifecycle/launch.rs::process_parent_pid`:
|
|
@@ -1,4 +1,3 @@
|
|
|
1
|
-
//! Retryable OS error classifier + human-readable os_error_name.
|
|
2
1
|
//!
|
|
3
2
|
//! Batch 0 signature only. Batch 2 migrates the raw
|
|
4
3
|
//! `libc::{EACCES, EPERM, EBUSY, ENOSPC}` matching in
|
|
@@ -8,6 +7,12 @@
|
|
|
8
7
|
|
|
9
8
|
use std::io;
|
|
10
9
|
|
|
10
|
+
///
|
|
11
|
+
/// **本函数是单节点**:`#[cfg]` 在函数体内部分叉,只存在一个 `fn` 定义,
|
|
12
|
+
/// 故不适用 SPEC §4「两份实现=两个节点」——那条针对的是**多个独立 `fn` 定义**
|
|
13
|
+
/// (如 `process.rs` 里 Unix/Windows 各定义一次)。
|
|
14
|
+
/// `impl_notes` 只是实现说明,**不是节点身份**,不参与签名全等校验。
|
|
15
|
+
///
|
|
11
16
|
/// True when the OS error is a transient replace failure worth
|
|
12
17
|
/// retrying (EACCES on Windows during antivirus scan, EBUSY on
|
|
13
18
|
/// mounted filesystems, etc.). Batch 2 wires the callsite.
|
|
@@ -38,6 +43,10 @@ pub fn retryable_replace_error(error: &io::Error) -> bool {
|
|
|
38
43
|
}
|
|
39
44
|
}
|
|
40
45
|
|
|
46
|
+
///
|
|
47
|
+
/// 返回值是**对外稳定契约**:它会出现在诊断输出里被人和脚本读取,
|
|
48
|
+
/// 因此已发布的名字不可改写,只可新增。
|
|
49
|
+
///
|
|
41
50
|
/// Human-readable name for a raw OS error code — used in diagnostics
|
|
42
51
|
/// so operators see `EACCES` instead of `13`.
|
|
43
52
|
#[allow(dead_code)]
|
|
@@ -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
|
-
//
|
|
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
|
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
|
-
|
|
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
|
-
|
|
11
|
+
fn runtime_mcp_tool_allowlisted(tool: &str) -> bool {
|
|
11
12
|
!tool.trim().is_empty()
|
|
12
13
|
}
|
|
13
14
|
|
|
14
|
-
|
|
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
|
-
|
|
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
|
-
|
|
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
|
-
|
|
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
|
//! 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
|
//! 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
|
|
|
@@ -534,10 +535,6 @@ pub fn incomplete_resumable_agent_ids(state: &Value) -> Vec<String> {
|
|
|
534
535
|
out
|
|
535
536
|
}
|
|
536
537
|
|
|
537
|
-
pub fn session_capture_complete(state: &Value) -> bool {
|
|
538
|
-
incomplete_resumable_agent_ids(state).is_empty()
|
|
539
|
-
}
|
|
540
|
-
|
|
541
538
|
pub fn recover_resume_session_from_events(
|
|
542
539
|
workspace: &Path,
|
|
543
540
|
agent_id: &str,
|
|
@@ -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};
|