@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.
- package/Cargo.lock +1 -1
- package/Cargo.toml +1 -1
- package/crates/team-agent/src/cli/adapters.rs +49 -3
- package/crates/team-agent/src/cli/attach_app_server_leader.rs +1 -0
- package/crates/team-agent/src/cli/diagnose.rs +184 -0
- package/crates/team-agent/src/cli/emit.rs +104 -21
- package/crates/team-agent/src/cli/helpers.rs +1 -0
- package/crates/team-agent/src/cli/leader.rs +14 -2
- package/crates/team-agent/src/cli/leaders.rs +2 -0
- package/crates/team-agent/src/cli/mod.rs +296 -8
- package/crates/team-agent/src/cli/named_address.rs +26 -2
- 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 +3 -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 +5 -1
- 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/status_port/store.rs +7 -3
- package/crates/team-agent/src/cli/tests/named_address.rs +65 -0
- package/crates/team-agent/src/cli/tests/verb_profile.rs +38 -0
- package/crates/team-agent/src/cli/types.rs +36 -2
- package/crates/team-agent/src/communication_mode/mod.rs +54 -0
- package/crates/team-agent/src/compiler/tests.rs +5 -5
- package/crates/team-agent/src/compiler.rs +54 -1
- 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 +47 -2
- 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/fake_worker.rs +21 -1
- 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 +1072 -186
- 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 +71 -59
- package/crates/team-agent/src/leader/tests/identity_session_names.rs +42 -0
- 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 +7 -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_agent.rs +1 -1
- 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 +2 -28
- 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 +4 -4
- package/crates/team-agent/src/lifecycle/restart/common.rs +1 -1
- 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/lifecycle/worker_command_context.rs +29 -11
- 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 +5 -3
- package/crates/team-agent/src/mcp_server/tests/send.rs +26 -0
- package/crates/team-agent/src/mcp_server/tests/wire.rs +1 -1
- package/crates/team-agent/src/mcp_server/tools.rs +101 -66
- package/crates/team-agent/src/mcp_server/types.rs +6 -18
- package/crates/team-agent/src/mcp_server/wire.rs +32 -26
- 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 +109 -41
- package/crates/team-agent/src/messaging/helpers.rs +2 -1
- package/crates/team-agent/src/messaging/leader_channel.rs +34 -10
- package/crates/team-agent/src/messaging/leader_receiver.rs +42 -24
- 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 +111 -1
- package/crates/team-agent/src/messaging/results.rs +166 -17
- 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 +135 -89
- package/crates/team-agent/src/messaging/tests/leader_channel.rs +6 -6
- package/crates/team-agent/src/messaging/tests/leader_inject_acceptance.rs +187 -0
- package/crates/team-agent/src/messaging/tests/mod.rs +5 -0
- package/crates/team-agent/src/messaging/tests/runtime.rs +13 -6
- package/crates/team-agent/src/messaging/types.rs +7 -2
- package/crates/team-agent/src/messaging/watchers.rs +24 -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 +2 -0
- package/crates/team-agent/src/model/name_similarity.rs +1 -0
- package/crates/team-agent/src/model/pane_authority_refusal.rs +359 -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 +17 -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 +41 -22
- 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 +93 -3
- package/crates/team-agent/src/provider/session_scan/codex.rs +1 -0
- package/crates/team-agent/src/provider/session_scan/common.rs +24 -7
- package/crates/team-agent/src/provider/session_scan/copilot.rs +1 -0
- package/crates/team-agent/src/provider/session_scan.rs +6 -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/topology.rs +3 -0
- package/crates/team-agent/src/transport.rs +15 -0
- package/package.json +4 -4
- package/skills/team-agent/command-coverage.json +379 -0
- package/crates/team-agent/src/leader/inject.rs +0 -33
- package/crates/team-agent/src/provider/command.rs +0 -80
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
//! coordinator 共享数据面:常量 / newtype / 穷尽 enum / metadata / schema health /
|
|
2
|
-
//! report 结构 /
|
|
2
|
+
//! report 结构 / abnormal-track 数据型 / WatchCursor / cross-dep 占位。
|
|
3
3
|
|
|
4
4
|
use std::collections::BTreeSet;
|
|
5
5
|
use std::path::{Path, PathBuf};
|
|
@@ -9,11 +9,10 @@ use serde_json::Value;
|
|
|
9
9
|
use thiserror::Error;
|
|
10
10
|
|
|
11
11
|
// ── REUSE — committed model types(不重定义)──────────────────────────────────
|
|
12
|
-
use crate::model::enums::
|
|
13
|
-
// AuthMode/PaneLiveness 经 provider/transport 间接复用;此处只点名直接用到的。
|
|
12
|
+
use crate::model::enums::Provider;
|
|
14
13
|
|
|
15
14
|
// ── REUSE — step 8 provider(经 trait,MUST-NOT-13:绝不依赖 provider client crate)──
|
|
16
|
-
use crate::provider::{
|
|
15
|
+
use crate::provider::{ProviderAdapter, RolloutPath, TurnState};
|
|
17
16
|
|
|
18
17
|
// ===========================================================================
|
|
19
18
|
// CONSTANTS(metadata.py:13 / __main__.py:101)
|
|
@@ -354,137 +353,10 @@ pub struct StopReport {
|
|
|
354
353
|
pub pid: Option<Pid>,
|
|
355
354
|
}
|
|
356
355
|
|
|
357
|
-
// ===========================================================================
|
|
358
|
-
// CoordinatorEvent(§3/§22:typed event enum,serde tag 与 Python 字节级一致)
|
|
359
|
-
// ===========================================================================
|
|
360
|
-
|
|
361
|
-
/// 本 step 发出的事件(card 表整列;事件名稳定契约由 step 4 EventLog 拥有,本卡只点名
|
|
362
|
-
/// coordinator 发的那批)。serde `tag = "event"` + 精确 rename 锁死字节(与 events.jsonl 一致)。
|
|
363
|
-
/// 渲染(`watch::render_event_line`)是它的 `Display` 投影。
|
|
364
|
-
#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)] // 无 Eq:某变体含 f64
|
|
365
|
-
#[serde(tag = "event")]
|
|
366
|
-
pub enum CoordinatorEvent {
|
|
367
|
-
#[serde(rename = "coordinator.boot")]
|
|
368
|
-
Boot { workspace: String, once: bool },
|
|
369
|
-
#[serde(rename = "coordinator.started")]
|
|
370
|
-
Started { pid: Pid, log: String },
|
|
371
|
-
#[serde(rename = "coordinator.stopped")]
|
|
372
|
-
Stopped { pid: Pid },
|
|
373
|
-
#[serde(rename = "coordinator.exit")]
|
|
374
|
-
Exit { stop: bool },
|
|
375
|
-
#[serde(rename = "coordinator.session_missing")]
|
|
376
|
-
SessionMissing { session: String },
|
|
377
|
-
#[serde(rename = "coordinator.orphan_self_terminate")]
|
|
378
|
-
OrphanSelfTerminate {
|
|
379
|
-
initial_ppid: u32,
|
|
380
|
-
current_ppid: u32,
|
|
381
|
-
workspace: String,
|
|
382
|
-
},
|
|
383
|
-
#[serde(rename = "coordinator.tick_error")]
|
|
384
|
-
TickError {
|
|
385
|
-
error: String,
|
|
386
|
-
exc_type: String,
|
|
387
|
-
consecutive_failures: u32,
|
|
388
|
-
next_sleep_sec: f64,
|
|
389
|
-
},
|
|
390
|
-
#[serde(rename = "coordinator.tick_error.suppressed")]
|
|
391
|
-
TickErrorSuppressed {
|
|
392
|
-
consecutive_failures: u32,
|
|
393
|
-
next_sleep_sec: f64,
|
|
394
|
-
},
|
|
395
|
-
#[serde(rename = "coordinator.tick_recovered")]
|
|
396
|
-
TickRecovered { consecutive_failures: u32 },
|
|
397
|
-
#[serde(rename = "coordinator.restart_incompatible")]
|
|
398
|
-
RestartIncompatible {
|
|
399
|
-
pid: Option<Pid>,
|
|
400
|
-
expected_protocol: u32,
|
|
401
|
-
expected_schema: i64,
|
|
402
|
-
},
|
|
403
|
-
#[serde(rename = "coordinator.restart_incompatible_stop_failed")]
|
|
404
|
-
RestartIncompatibleStopFailed { pid: Option<Pid> },
|
|
405
|
-
#[serde(rename = "coordinator.schema_incompatible")]
|
|
406
|
-
SchemaIncompatible {
|
|
407
|
-
table: Option<String>,
|
|
408
|
-
missing_columns: Vec<String>,
|
|
409
|
-
},
|
|
410
|
-
#[serde(rename = "idle_takeover.unknown_persistent")]
|
|
411
|
-
IdleTakeoverUnknownPersistent {
|
|
412
|
-
node_id: String,
|
|
413
|
-
provider: Option<Provider>,
|
|
414
|
-
auth_mode: Option<AuthMode>,
|
|
415
|
-
consecutive_ticks: u32,
|
|
416
|
-
rollout_path: Option<RolloutPath>,
|
|
417
|
-
},
|
|
418
|
-
#[serde(rename = "abnormal.notify")]
|
|
419
|
-
AbnormalNotify {
|
|
420
|
-
signature: String,
|
|
421
|
-
turn_id: Option<TurnId>,
|
|
422
|
-
decision: AbnormalDecision,
|
|
423
|
-
},
|
|
424
|
-
#[serde(rename = "worker.abnormal_exit")]
|
|
425
|
-
WorkerAbnormalExit {
|
|
426
|
-
team_id: String,
|
|
427
|
-
agent_id: String,
|
|
428
|
-
provider: Provider,
|
|
429
|
-
path: String,
|
|
430
|
-
provider_process_dead: bool,
|
|
431
|
-
latest_explicit_error: bool,
|
|
432
|
-
signature: String,
|
|
433
|
-
turn_id: Option<TurnId>,
|
|
434
|
-
process_liveness: ProcessLiveness,
|
|
435
|
-
},
|
|
436
|
-
#[serde(rename = "worker.abnormal_exit.check")]
|
|
437
|
-
WorkerAbnormalExitCheck {
|
|
438
|
-
team_id: String,
|
|
439
|
-
agent_id: String,
|
|
440
|
-
provider: Provider,
|
|
441
|
-
path: String,
|
|
442
|
-
provider_process_dead: bool,
|
|
443
|
-
latest_explicit_error: bool,
|
|
444
|
-
notification: bool,
|
|
445
|
-
suppressed_reason: Option<String>,
|
|
446
|
-
},
|
|
447
|
-
#[serde(rename = "abnormal_exit.single_signal_suppressed")]
|
|
448
|
-
AbnormalExitSingleSignalSuppressed {
|
|
449
|
-
team_id: String,
|
|
450
|
-
agent_id: String,
|
|
451
|
-
provider: Provider,
|
|
452
|
-
path: String,
|
|
453
|
-
reason: String,
|
|
454
|
-
provider_process_dead: bool,
|
|
455
|
-
dead_process: bool,
|
|
456
|
-
latest_explicit_error: bool,
|
|
457
|
-
},
|
|
458
|
-
#[serde(rename = "abnormal.whole_team_gone")]
|
|
459
|
-
AbnormalWholeTeamGone { classification: WholeTeamGoneClass },
|
|
460
|
-
#[serde(rename = "leader_notification.log_pruned")]
|
|
461
|
-
LeaderNotificationLogPruned { removed: u64 },
|
|
462
|
-
#[serde(rename = "leader_notification.prune_failed")]
|
|
463
|
-
LeaderNotificationPruneFailed { error: String },
|
|
464
|
-
#[serde(rename = "runtime.state.save_failed")]
|
|
465
|
-
RuntimeStateSaveFailed {
|
|
466
|
-
phase: String,
|
|
467
|
-
error: String,
|
|
468
|
-
exc_type: String,
|
|
469
|
-
},
|
|
470
|
-
}
|
|
471
|
-
|
|
472
356
|
// ===========================================================================
|
|
473
357
|
// 异常轨 abnormal_track(abnormal_track.py)—— provider-neutral 数据型
|
|
474
358
|
// ===========================================================================
|
|
475
359
|
|
|
476
|
-
/// `_classify` 决策(`abnormal_track.py:198-204`)。whitelist > blacklist > default(C9 catch-bias)。
|
|
477
|
-
#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash, Serialize, Deserialize)]
|
|
478
|
-
#[serde(rename_all = "snake_case")]
|
|
479
|
-
pub enum AbnormalDecision {
|
|
480
|
-
/// whitelist 命中 → 不通知(`abnormal_track.py:201`)。
|
|
481
|
-
Skip,
|
|
482
|
-
/// blacklist 命中 → 通知(`abnormal_track.py:203`)。
|
|
483
|
-
NotifyBlacklist,
|
|
484
|
-
/// 结构化 fault 默认通知(C9 catch-bias,`abnormal_track.py:204`)。
|
|
485
|
-
NotifyDefault,
|
|
486
|
-
}
|
|
487
|
-
|
|
488
360
|
/// `detect_whole_team_gone` 分类(`abnormal_track.py:130/132/143`)。
|
|
489
361
|
#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash, Serialize, Deserialize)]
|
|
490
362
|
#[serde(rename_all = "snake_case")]
|
|
@@ -498,35 +370,6 @@ pub enum WholeTeamGoneClass {
|
|
|
498
370
|
UnexpectedExit,
|
|
499
371
|
}
|
|
500
372
|
|
|
501
|
-
/// `process_abnormal_records` 单条通知(`abnormal_track.py:70-79`)。
|
|
502
|
-
/// dedup key = `(signature, turn_id|fingerprint)`(C8,`abnormal_track.py:64-66`):turn_id 缺失退化为
|
|
503
|
-
/// per-record content fingerprint 桶,**绝不**把不同 fault 折叠进一个全局桶。
|
|
504
|
-
#[derive(Debug, Clone, PartialEq, Eq)]
|
|
505
|
-
pub struct AbnormalNotification {
|
|
506
|
-
pub signature: String,
|
|
507
|
-
pub turn_id: Option<TurnId>,
|
|
508
|
-
/// `kind == "approval"` → blocked_on_human,否则 abnormal(`abnormal_track.py:74`)。
|
|
509
|
-
pub state: TurnState,
|
|
510
|
-
pub decision: AbnormalDecision,
|
|
511
|
-
pub provider: Option<Provider>,
|
|
512
|
-
/// 原始 fault fact(provider reader 产出的结构化记录;本 module 不读屏不命名 provider)。
|
|
513
|
-
pub raw: Value,
|
|
514
|
-
}
|
|
515
|
-
|
|
516
|
-
/// `process_abnormal_records` 返回(`abnormal_track.py:83-88` typed 版)。
|
|
517
|
-
#[derive(Debug, Clone, PartialEq, Eq)]
|
|
518
|
-
pub struct AbnormalProcessOutput {
|
|
519
|
-
pub notifications: Vec<AbnormalNotification>,
|
|
520
|
-
/// 更新后的去重状态(`seen` 集合,`abnormal_track.py:82`)——caller 回存。
|
|
521
|
-
pub notification_state: AbnormalNotificationState,
|
|
522
|
-
}
|
|
523
|
-
|
|
524
|
-
/// abnormal 去重状态(`abnormal_track.py:31-32,82`)。`seen` = `signature\0bucket` key 集合。
|
|
525
|
-
#[derive(Debug, Clone, Default, PartialEq, Eq, Serialize, Deserialize)]
|
|
526
|
-
pub struct AbnormalNotificationState {
|
|
527
|
-
pub seen: BTreeSet<String>,
|
|
528
|
-
}
|
|
529
|
-
|
|
530
373
|
/// `detect_whole_team_gone` 返回(`abnormal_track.py:140-147` typed 版)。
|
|
531
374
|
#[derive(Debug, Clone, PartialEq, Eq)]
|
|
532
375
|
pub struct WholeTeamGoneReport {
|
|
@@ -551,13 +394,6 @@ pub struct TeamPresenceSnapshot {
|
|
|
551
394
|
pub restart_in_progress: bool,
|
|
552
395
|
}
|
|
553
396
|
|
|
554
|
-
/// abnormal track 错误(provider reader 翻译 fault facts 失败)。
|
|
555
|
-
#[derive(Debug, Error)]
|
|
556
|
-
pub enum AbnormalError {
|
|
557
|
-
#[error("provider: {0}")]
|
|
558
|
-
Provider(#[from] crate::provider::ProviderError),
|
|
559
|
-
}
|
|
560
|
-
|
|
561
397
|
// ===========================================================================
|
|
562
398
|
// WatchCursor(watch/__init__.py)
|
|
563
399
|
// ===========================================================================
|
|
@@ -591,15 +427,6 @@ pub use crate::model::ids::AgentId;
|
|
|
591
427
|
pub trait ProviderRegistry {
|
|
592
428
|
/// 拿某 provider 的 adapter(`providers.get_adapter`)。
|
|
593
429
|
fn adapter_for(&self, provider: Provider) -> Box<dyn ProviderAdapter>;
|
|
594
|
-
/// 该 provider 的 error 黑白名单(`get_provider_registry(provider)["error_lists"]`,abnormal_track 用)。
|
|
595
|
-
fn error_lists(&self, provider: Provider) -> ErrorLists;
|
|
596
|
-
}
|
|
597
|
-
|
|
598
|
-
/// provider error 黑白名单(`abnormal_track.py:184-195`)。**PLACEHOLDER**(step 8 拥有)。
|
|
599
|
-
#[derive(Debug, Clone, Default, PartialEq, Eq)]
|
|
600
|
-
pub struct ErrorLists {
|
|
601
|
-
pub whitelist: Vec<String>,
|
|
602
|
-
pub blacklist: Vec<String>,
|
|
603
430
|
}
|
|
604
431
|
|
|
605
432
|
/// idle take-over 候选 node(`idle_takeover_wiring.build_idle_nodes`,step 8/11 拥有真名)。
|
|
@@ -4,6 +4,7 @@
|
|
|
4
4
|
// physical relocation (zero behavior change).
|
|
5
5
|
#![allow(clippy::unwrap_used, clippy::expect_used, clippy::panic)]
|
|
6
6
|
|
|
7
|
+
//!
|
|
7
8
|
//! step 7 · message_store — core message lifecycle over `team.db`.
|
|
8
9
|
//!
|
|
9
10
|
//! Truth source (READ-ONLY): `team-agent-public` @ v0.2.11,
|
|
@@ -97,6 +98,7 @@ pub enum MessageRowStatus {
|
|
|
97
98
|
QueuedPaneMissing,
|
|
98
99
|
TargetResolved,
|
|
99
100
|
SubmittedAwaitingReceipt,
|
|
101
|
+
InjectedAwaitingReceipt,
|
|
100
102
|
SubmittedUnverified,
|
|
101
103
|
Delivered,
|
|
102
104
|
Acknowledged,
|
|
@@ -115,6 +117,7 @@ impl MessageRowStatus {
|
|
|
115
117
|
Self::QueuedPaneMissing,
|
|
116
118
|
Self::TargetResolved,
|
|
117
119
|
Self::SubmittedAwaitingReceipt,
|
|
120
|
+
Self::InjectedAwaitingReceipt,
|
|
118
121
|
Self::SubmittedUnverified,
|
|
119
122
|
Self::Delivered,
|
|
120
123
|
Self::Acknowledged,
|
|
@@ -133,6 +136,7 @@ impl MessageRowStatus {
|
|
|
133
136
|
Self::QueuedPaneMissing => "queued_pane_missing",
|
|
134
137
|
Self::TargetResolved => "target_resolved",
|
|
135
138
|
Self::SubmittedAwaitingReceipt => "submitted_pending_acceptance",
|
|
139
|
+
Self::InjectedAwaitingReceipt => "injected_awaiting_receipt",
|
|
136
140
|
Self::SubmittedUnverified => "submitted_unverified",
|
|
137
141
|
Self::Delivered => "delivered",
|
|
138
142
|
Self::Acknowledged => "acknowledged",
|
|
@@ -202,7 +206,7 @@ pub struct PersistMessageInput<'a> {
|
|
|
202
206
|
|
|
203
207
|
/// `leader_notification_log._legacy_epoch_from_uuid` (line 145-147):
|
|
204
208
|
/// `int(zlib.crc32(str(uuid or "").encode("utf-8")) & 0x7FFFFFFF)`.
|
|
205
|
-
|
|
209
|
+
fn legacy_epoch_from_uuid(leader_session_uuid: Option<&str>) -> i64 {
|
|
206
210
|
let mut crc = 0xFFFF_FFFFu32;
|
|
207
211
|
for byte in leader_session_uuid.unwrap_or("").as_bytes() {
|
|
208
212
|
crc ^= u32::from(*byte);
|
|
@@ -394,7 +398,10 @@ impl MessageStore {
|
|
|
394
398
|
acknowledged_at = case when ?2 = 'acknowledged' then ?3 else acknowledged_at end,
|
|
395
399
|
error = case when ?2 = 'delivered' then null else coalesce(?4, error) end
|
|
396
400
|
where message_id = ?1
|
|
397
|
-
and status not in (
|
|
401
|
+
and status not in (
|
|
402
|
+
'acknowledged', 'consumed', 'submitted_pending_acceptance',
|
|
403
|
+
'injected_awaiting_receipt'
|
|
404
|
+
)
|
|
398
405
|
and (status != 'delivered' or ?2 in ('delivered', 'acknowledged'))
|
|
399
406
|
and (?2 != 'acknowledged' or status = 'delivered')",
|
|
400
407
|
params![message_id, status, now, error],
|
|
@@ -468,6 +475,44 @@ impl MessageStore {
|
|
|
468
475
|
Ok(())
|
|
469
476
|
}
|
|
470
477
|
|
|
478
|
+
/// Persist a verified leader transport submission when no provider receipt
|
|
479
|
+
/// source is available. This state is claim/requeue-ineligible but does not
|
|
480
|
+
/// clear the delivery obligation; `consumed_at` remains unset until a
|
|
481
|
+
/// provider-side receipt reaches `mark_delivered_with_receipt`.
|
|
482
|
+
pub fn mark_injected_awaiting_receipt(
|
|
483
|
+
&self,
|
|
484
|
+
message_id: &str,
|
|
485
|
+
) -> Result<(), MessageStoreError> {
|
|
486
|
+
let conn = crate::db::schema::open_db(&self.path)?;
|
|
487
|
+
let changed = conn.execute(
|
|
488
|
+
"update messages
|
|
489
|
+
set status = ?2,
|
|
490
|
+
updated_at = ?3,
|
|
491
|
+
error = 'leader_receipt_source_unavailable'
|
|
492
|
+
where message_id = ?1
|
|
493
|
+
and status in (?4, ?5, ?6)
|
|
494
|
+
and exists (
|
|
495
|
+
select 1 from delivery_tokens
|
|
496
|
+
where delivery_tokens.message_id = messages.message_id
|
|
497
|
+
and delivery_tokens.injected_at is not null
|
|
498
|
+
)",
|
|
499
|
+
params![
|
|
500
|
+
message_id,
|
|
501
|
+
MessageRowStatus::InjectedAwaitingReceipt.as_str(),
|
|
502
|
+
now_ts(),
|
|
503
|
+
MessageRowStatus::TargetResolved.as_str(),
|
|
504
|
+
MessageRowStatus::SubmittedAwaitingReceipt.as_str(),
|
|
505
|
+
MessageRowStatus::InjectedAwaitingReceipt.as_str(),
|
|
506
|
+
],
|
|
507
|
+
)?;
|
|
508
|
+
if changed != 1 {
|
|
509
|
+
return Err(MessageStoreError::DeliveryReceiptMissing(
|
|
510
|
+
message_id.to_string(),
|
|
511
|
+
));
|
|
512
|
+
}
|
|
513
|
+
Ok(())
|
|
514
|
+
}
|
|
515
|
+
|
|
471
516
|
/// Atomically persist the provider-side receipt and advance the message to
|
|
472
517
|
/// delivered. A transport-only caller cannot use this without first
|
|
473
518
|
/// recording the submission row above.
|
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
//!
|
|
1
2
|
//! `team.db` 列布局迁移(Gap 46;真相源 `message_store/schema_migration.py`)。
|
|
2
3
|
//!
|
|
3
4
|
//! 检测**物理列序漂移**(`pragma table_info` 顺序 vs canonical),在**一个原子事务**
|
|
@@ -141,7 +142,7 @@ fn create_table_ddl(table: &str, name: &str) -> Option<String> {
|
|
|
141
142
|
|
|
142
143
|
/// 一张表的布局 diff。
|
|
143
144
|
#[derive(Debug, Clone)]
|
|
144
|
-
|
|
145
|
+
struct Diff {
|
|
145
146
|
pub table: &'static str,
|
|
146
147
|
pub expected: Vec<&'static str>,
|
|
147
148
|
pub actual: Vec<String>,
|
|
@@ -187,7 +188,7 @@ fn table_count(conn: &Connection, table: &str) -> Result<i64, DbError> {
|
|
|
187
188
|
Ok(conn.query_row(&format!("select count(*) from {table}"), [], |r| r.get(0))?)
|
|
188
189
|
}
|
|
189
190
|
|
|
190
|
-
|
|
191
|
+
fn pragma_user_version(conn: &Connection) -> Result<i64, DbError> {
|
|
191
192
|
Ok(conn.query_row("pragma user_version", [], |r| r.get(0))?)
|
|
192
193
|
}
|
|
193
194
|
|
|
@@ -230,7 +231,7 @@ fn run_version_migrations(conn: &Connection, schema_version: i64) -> Result<(),
|
|
|
230
231
|
|
|
231
232
|
/// `schema_migration.py:_layout_diffs`:按 `table_info` 物理列序检测漂移。
|
|
232
233
|
/// 无任何 managed 表存在(fresh DB)→ 空(initialize 随后建表)。
|
|
233
|
-
|
|
234
|
+
fn layout_diffs(conn: &Connection) -> Result<Vec<Diff>, DbError> {
|
|
234
235
|
let mut any = false;
|
|
235
236
|
for (t, _) in MANAGED_TABLE_LAYOUTS {
|
|
236
237
|
if table_exists(conn, t)? {
|
|
@@ -419,7 +420,7 @@ pub fn ensure_table_layout(
|
|
|
419
420
|
}
|
|
420
421
|
|
|
421
422
|
/// `schema_migration.py:schema_diagnosis`:只读判定(不变更 DB)。
|
|
422
|
-
|
|
423
|
+
fn schema_diagnosis(db_path: &Path, schema_version: i64) -> Result<Diagnosis, DbError> {
|
|
423
424
|
if !db_path.exists() {
|
|
424
425
|
// T3-3 cr verdict (A parity lock, 2026-06-10): a missing db is the LEGAL
|
|
425
426
|
// first-use state — ok:true is layered with the explicit status axis and the
|
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
|
|
1
2
|
use std::path::Path;
|
|
2
3
|
|
|
3
4
|
use serde_json::{json, Value};
|
|
@@ -212,7 +213,7 @@ fn verifies_json(check: &SelftestCheck) -> Value {
|
|
|
212
213
|
serde_json::to_value(check.verifies).unwrap_or_else(|_| json!("unknown"))
|
|
213
214
|
}
|
|
214
215
|
|
|
215
|
-
|
|
216
|
+
fn receiver_binding_mismatches(
|
|
216
217
|
owner_pane_id: &Value,
|
|
217
218
|
caller_pane_id: &Value,
|
|
218
219
|
pane_id: &Value,
|
|
@@ -153,7 +153,7 @@ fn fake_envelope(
|
|
|
153
153
|
) -> serde_json::Value {
|
|
154
154
|
serde_json::json!({
|
|
155
155
|
"schema_version": "result_envelope_v1",
|
|
156
|
-
"task_id": task_id.unwrap_or(
|
|
156
|
+
"task_id": task_id.unwrap_or(message_id),
|
|
157
157
|
"agent_id": agent_id,
|
|
158
158
|
"status": "success",
|
|
159
159
|
"summary": format!("Fake worker handled message {message_id}"),
|
|
@@ -280,4 +280,24 @@ mod tests {
|
|
|
280
280
|
"rendered form prints WORKING per line; got {printed}"
|
|
281
281
|
);
|
|
282
282
|
}
|
|
283
|
+
|
|
284
|
+
#[test]
|
|
285
|
+
fn fake_worker_direct_message_uses_message_scope_instead_of_manual() {
|
|
286
|
+
let ws = fake_ws();
|
|
287
|
+
let input = "Team Agent message from leader:\nplease do X\n[team-agent-token:m1]\n";
|
|
288
|
+
let mut out: Vec<u8> = Vec::new();
|
|
289
|
+
run(&ws, "w1", Cursor::new(input.as_bytes()), &mut out).expect("fake worker run");
|
|
290
|
+
|
|
291
|
+
let (task_id, agent_id, status, envelope) = stored_result(&ws);
|
|
292
|
+
assert_eq!(
|
|
293
|
+
(task_id.as_str(), agent_id.as_str(), status.as_str()),
|
|
294
|
+
("m1", "w1", "success"),
|
|
295
|
+
"a direct-message result must use its message id for message-scope collection"
|
|
296
|
+
);
|
|
297
|
+
assert_ne!(
|
|
298
|
+
envelope["task_id"],
|
|
299
|
+
serde_json::json!("manual"),
|
|
300
|
+
"the fake worker must not emit the production-impossible manual fallback"
|
|
301
|
+
);
|
|
302
|
+
}
|
|
283
303
|
}
|
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
//!
|
|
1
2
|
//! 0.3.28 layout step 2 — leader placement.
|
|
2
3
|
//!
|
|
3
4
|
//! Public API for managed-mode leader placement. The runtime calls
|
|
@@ -34,6 +35,7 @@ pub enum LeaderPlacement {
|
|
|
34
35
|
},
|
|
35
36
|
}
|
|
36
37
|
|
|
38
|
+
///
|
|
37
39
|
/// Compute the placement for a leader given its identity, the desired
|
|
38
40
|
/// `LeaderStartMode`, and the environment (used to detect `$TMUX`).
|
|
39
41
|
///
|
|
@@ -58,13 +60,6 @@ pub fn leader_placement(
|
|
|
58
60
|
}
|
|
59
61
|
}
|
|
60
62
|
|
|
61
|
-
/// The leader session name for a given provider + workspace. `LeaderIdentity`
|
|
62
|
-
/// in this codebase does not carry the provider field; the caller supplies it
|
|
63
|
-
/// explicitly (matches how `leader_session_name` itself is shaped).
|
|
64
|
-
pub fn leader_session_for_provider(provider: Provider, workspace: &Path) -> SessionName {
|
|
65
|
-
leader_session_name(provider, workspace)
|
|
66
|
-
}
|
|
67
|
-
|
|
68
63
|
#[allow(dead_code)]
|
|
69
64
|
fn _unused_identity_marker(_id: &LeaderIdentity) {}
|
|
70
65
|
|
|
@@ -74,6 +69,7 @@ use crate::layout::placement::{WorkerSpawnAction, WorkerSpawnTarget};
|
|
|
74
69
|
use crate::model::yaml::Value as YamlValue;
|
|
75
70
|
use crate::transport::Transport;
|
|
76
71
|
|
|
72
|
+
///
|
|
77
73
|
/// Compute the spawn target for a worker. Python parity: one window per
|
|
78
74
|
/// agent in the worker session, named after `agent_id`. First worker
|
|
79
75
|
/// (= session does not yet exist) → NewSession; otherwise NewWindow.
|
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
//!
|
|
1
2
|
//! 0.3.28 — Unified adaptive layout manager.
|
|
2
3
|
//!
|
|
3
4
|
//! Single source of truth for tmux topology decisions in the runtime:
|
|
@@ -31,6 +32,5 @@ pub mod worker_env;
|
|
|
31
32
|
pub mod worker_window_helpers;
|
|
32
33
|
|
|
33
34
|
pub use runtime_sessions::{
|
|
34
|
-
LeaderLauncherSession,
|
|
35
|
-
WorkerSession, WorkerSessionError,
|
|
35
|
+
LeaderLauncherSession, RuntimeSessionAnomaly, RuntimeSessions, WorkerSession,
|
|
36
36
|
};
|
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
//!
|
|
1
2
|
//! 0.3.28 layout step 8 — display overlay (3-pane tiling).
|
|
2
3
|
//!
|
|
3
4
|
//! Python truth source: 3-pane tiling exists ONLY in the display overlay
|
|
@@ -15,6 +16,7 @@ use crate::transport::{SessionName, WindowName};
|
|
|
15
16
|
/// 3 panes per overlay window — Python parity.
|
|
16
17
|
pub const OVERLAY_PANES_PER_WINDOW: usize = 3;
|
|
17
18
|
|
|
19
|
+
///
|
|
18
20
|
/// Overlay window name for a 0-based group index. Index 0 → `overview`;
|
|
19
21
|
/// N ≥ 1 → `overview-{N+1}`. Names are scoped by `session_tag` so multiple
|
|
20
22
|
/// teams can coexist on one leader session.
|
|
@@ -38,6 +40,7 @@ pub struct OverlayPlacement {
|
|
|
38
40
|
pub window: WindowName,
|
|
39
41
|
}
|
|
40
42
|
|
|
43
|
+
///
|
|
41
44
|
/// Compute the overlay placements for a list of agent_ids. Deterministic by
|
|
42
45
|
/// input order: agent `i` → window `i / 3`, slot `i % 3`.
|
|
43
46
|
pub fn plan_overlay_placements(session_tag: &str, agents: &[&str]) -> Vec<OverlayPlacement> {
|
|
@@ -53,9 +56,10 @@ pub fn plan_overlay_placements(session_tag: &str, agents: &[&str]) -> Vec<Overla
|
|
|
53
56
|
.collect()
|
|
54
57
|
}
|
|
55
58
|
|
|
59
|
+
///
|
|
56
60
|
/// True when a window name belongs to a display overlay (matches
|
|
57
61
|
/// `team-agent:<...>:overview[-N]`).
|
|
58
|
-
|
|
62
|
+
fn is_overlay_window(name: &WindowName) -> bool {
|
|
59
63
|
let n = name.as_str();
|
|
60
64
|
if !n.starts_with("team-agent:") {
|
|
61
65
|
return false;
|
|
@@ -63,6 +67,7 @@ pub fn is_overlay_window(name: &WindowName) -> bool {
|
|
|
63
67
|
n.contains(":overview")
|
|
64
68
|
}
|
|
65
69
|
|
|
70
|
+
///
|
|
66
71
|
/// 0.3.28 Step 8 invariant: `spawn_split` may ONLY be called from the
|
|
67
72
|
/// overlay module. This helper emits a warn-level event when called from
|
|
68
73
|
/// anywhere else (Step 9 promotes to a hard error / panic gate). The
|
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
//!
|
|
1
2
|
//! 0.3.28 layout step 7 — leader pane recovery.
|
|
2
3
|
//!
|
|
3
4
|
//! Python truth source (`leader/__init__.py:885-887` +
|
|
@@ -28,6 +29,7 @@ pub enum RecoveryOutcome {
|
|
|
28
29
|
NeedsUserAttach,
|
|
29
30
|
}
|
|
30
31
|
|
|
32
|
+
///
|
|
31
33
|
/// Compute the recovery outcome from the current environment.
|
|
32
34
|
///
|
|
33
35
|
/// Reads `TMUX_PANE` from the supplied environment iterator (use
|
|
@@ -44,6 +46,7 @@ where
|
|
|
44
46
|
RecoveryOutcome::NeedsUserAttach
|
|
45
47
|
}
|
|
46
48
|
|
|
49
|
+
///
|
|
47
50
|
/// Emit the canonical `leader_receiver.rebind_required` event when the
|
|
48
51
|
/// runtime falls through to `NeedsUserAttach`. Logs to stderr so operators
|
|
49
52
|
/// see the cascade in event logs.
|
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
//!
|
|
1
2
|
//! unit-1 (Stage 1) — typed runtime session identity.
|
|
2
3
|
//!
|
|
3
4
|
//! Provides two compile-time-distinct newtypes plus a `RuntimeSessions`
|
|
@@ -35,7 +36,7 @@ pub struct LeaderLauncherSession(SessionName);
|
|
|
35
36
|
|
|
36
37
|
/// Why `WorkerSession::new` rejected a name.
|
|
37
38
|
#[derive(Debug, Clone, PartialEq, Eq)]
|
|
38
|
-
|
|
39
|
+
enum WorkerSessionError {
|
|
39
40
|
/// The name is empty.
|
|
40
41
|
Empty,
|
|
41
42
|
/// The name carries the leader launcher prefix — must not be a worker
|
|
@@ -45,7 +46,7 @@ pub enum WorkerSessionError {
|
|
|
45
46
|
|
|
46
47
|
/// Why `LeaderLauncherSession::new` rejected a name.
|
|
47
48
|
#[derive(Debug, Clone, PartialEq, Eq)]
|
|
48
|
-
|
|
49
|
+
enum LeaderLauncherSessionError {
|
|
49
50
|
/// The name is empty.
|
|
50
51
|
Empty,
|
|
51
52
|
/// The name does not carry the required leader launcher prefix.
|
|
@@ -136,6 +137,7 @@ pub enum RuntimeSessionAnomaly {
|
|
|
136
137
|
}
|
|
137
138
|
|
|
138
139
|
impl RuntimeSessions {
|
|
140
|
+
///
|
|
139
141
|
/// Read state.json's session-identity fields and wrap them in typed
|
|
140
142
|
/// values. Never panics on bad state — anomalies are surfaced for
|
|
141
143
|
/// callers to act on.
|
|
@@ -197,11 +199,13 @@ impl RuntimeSessions {
|
|
|
197
199
|
}
|
|
198
200
|
}
|
|
199
201
|
|
|
202
|
+
///
|
|
200
203
|
/// True if any session-identity anomaly was detected in state.
|
|
201
204
|
pub fn has_anomalies(&self) -> bool {
|
|
202
205
|
!self.anomalies.is_empty()
|
|
203
206
|
}
|
|
204
207
|
|
|
208
|
+
///
|
|
205
209
|
/// True if a `state.session_name` looked like a leader launcher session
|
|
206
210
|
/// — the exact 0.3.39 shape unit-3 must refuse before any kill.
|
|
207
211
|
pub fn worker_session_name_is_leader_prefixed(&self) -> bool {
|
|
@@ -214,9 +218,10 @@ impl RuntimeSessions {
|
|
|
214
218
|
}
|
|
215
219
|
}
|
|
216
220
|
|
|
221
|
+
///
|
|
217
222
|
/// True when `name` is a leader launcher session (mirrors
|
|
218
223
|
/// `layout::sessions::is_leader_session` on a raw &str).
|
|
219
|
-
|
|
224
|
+
fn name_is_leader_launcher(name: &str) -> bool {
|
|
220
225
|
let session = SessionName::new(name);
|
|
221
226
|
is_leader_session(&session)
|
|
222
227
|
}
|
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
//!
|
|
1
2
|
//! 0.3.28 layout step 1 — session name constructors + topology invariant guard.
|
|
2
3
|
//!
|
|
3
4
|
//! Python 0.2.11 truth source (recap):
|
|
@@ -25,6 +26,7 @@ use serde_json::Value as JsonValue;
|
|
|
25
26
|
/// code does not have to depend on the leader module's internals.
|
|
26
27
|
pub const LEADER_SESSION_PREFIX: &str = crate::leader::start::LEADER_SESSION_PREFIX;
|
|
27
28
|
|
|
29
|
+
///
|
|
28
30
|
/// Leader's dedicated tmux session name.
|
|
29
31
|
///
|
|
30
32
|
/// Format: `team-agent-leader-<provider_wire>-<folder>-<sha1(workspace)[:8]>`.
|
|
@@ -37,6 +39,7 @@ pub fn leader_session_name(provider: Provider, workspace: &Path) -> SessionName
|
|
|
37
39
|
crate::leader::start::leader_session_name(provider, workspace)
|
|
38
40
|
}
|
|
39
41
|
|
|
42
|
+
///
|
|
40
43
|
/// Worker tmux session name derived from the team spec.
|
|
41
44
|
///
|
|
42
45
|
/// Format: `spec.runtime.session_name` if set, else `team-<team.name>`
|
|
@@ -48,13 +51,15 @@ pub fn worker_session_name(spec: &YamlValue) -> SessionName {
|
|
|
48
51
|
crate::lifecycle::launch::worker_session_name_pub(spec)
|
|
49
52
|
}
|
|
50
53
|
|
|
54
|
+
///
|
|
51
55
|
/// True when `name` starts with the leader session prefix.
|
|
52
56
|
pub fn is_leader_session(name: &SessionName) -> bool {
|
|
53
57
|
name.as_str().starts_with(LEADER_SESSION_PREFIX)
|
|
54
58
|
}
|
|
55
59
|
|
|
60
|
+
///
|
|
56
61
|
/// True when `name` equals the worker session name derived from `spec`.
|
|
57
|
-
|
|
62
|
+
fn is_worker_session(name: &SessionName, spec: &YamlValue) -> bool {
|
|
58
63
|
worker_session_name(spec).as_str() == name.as_str()
|
|
59
64
|
}
|
|
60
65
|
|
|
@@ -78,6 +83,7 @@ pub enum TopologyViolationKind {
|
|
|
78
83
|
LeaderPaneIdCollidesWithAgent,
|
|
79
84
|
}
|
|
80
85
|
|
|
86
|
+
///
|
|
81
87
|
/// Assert the runtime-state topology invariants (Step 1 — `warn!` only).
|
|
82
88
|
///
|
|
83
89
|
/// Checks:
|
|
@@ -174,6 +180,7 @@ pub fn assert_topology_invariants(state: &JsonValue, spec: &YamlValue) -> Vec<To
|
|
|
174
180
|
out
|
|
175
181
|
}
|
|
176
182
|
|
|
183
|
+
///
|
|
177
184
|
/// Logs each violation in `violations` to stderr under the
|
|
178
185
|
/// `team_agent::layout` tag. No-op when the list is empty. This is the
|
|
179
186
|
/// Step-1 surface — `eprintln!` matches the codebase's existing logging
|