@team-agent/installer 0.5.61 → 0.5.63
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 +15 -866
- 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 +139 -375
- 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 -49
- package/crates/team-agent/src/coordinator/tick.rs +23 -40
- 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 -66
- 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 -15
- 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 -13
- 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
|
@@ -0,0 +1,145 @@
|
|
|
1
|
+
//! team-key slice2 · layer 1 — pure retirement/roster table (RED).
|
|
2
|
+
//!
|
|
3
|
+
//! From locate §6.2 (agent lifecycle authority) and §7 observation points 6/8,
|
|
4
|
+
//! NOT from the root-cause reasoning: a `retired` tombstone under
|
|
5
|
+
//! `teams.<canonical>.agent_lifecycle.<agent_id>` must exclude that agent from
|
|
6
|
+
//! the restart desired roster, so a static/dynamic role source can no longer
|
|
7
|
+
//! silently resurrect a retired seat. Baseline 1ba6313 has no tombstone
|
|
8
|
+
//! semantics, so a retired agent with a dynamic_role_file is still rostered.
|
|
9
|
+
|
|
10
|
+
use serde_json::json;
|
|
11
|
+
use std::path::Path;
|
|
12
|
+
use team_agent::lifecycle::restart::restart_candidates;
|
|
13
|
+
use team_agent::state::persist::save_runtime_state;
|
|
14
|
+
|
|
15
|
+
/// A team `alpha` with two agents: `keep` (active) and `gone` (has a
|
|
16
|
+
/// dynamic_role_file AND a retired tombstone under agent_lifecycle).
|
|
17
|
+
fn seed(ws: &Path) {
|
|
18
|
+
let role_dir = ws.join(".team/runtime/teams/alpha/role-masters");
|
|
19
|
+
std::fs::create_dir_all(&role_dir).unwrap();
|
|
20
|
+
let gone_role = role_dir.join("gone.md");
|
|
21
|
+
std::fs::write(&gone_role, "---\nname: gone\nprovider: fake\n---\ngone\n").unwrap();
|
|
22
|
+
|
|
23
|
+
let state = json!({
|
|
24
|
+
"active_team_key": "alpha",
|
|
25
|
+
"session_name": "team-alpha",
|
|
26
|
+
"agents": {
|
|
27
|
+
"keep": { "status": "running", "provider": "fake" },
|
|
28
|
+
"gone": { "status": "running", "provider": "fake",
|
|
29
|
+
"dynamic_role_file": gone_role.to_string_lossy() }
|
|
30
|
+
},
|
|
31
|
+
"teams": {
|
|
32
|
+
"alpha": {
|
|
33
|
+
"status": "alive",
|
|
34
|
+
"session_name": "team-alpha",
|
|
35
|
+
"agents": {
|
|
36
|
+
"keep": { "status": "running", "provider": "fake" },
|
|
37
|
+
"gone": { "status": "running", "provider": "fake",
|
|
38
|
+
"dynamic_role_file": gone_role.to_string_lossy() }
|
|
39
|
+
},
|
|
40
|
+
"agent_lifecycle": {
|
|
41
|
+
"gone": { "state": "retired", "changed_at": "2026-07-20T00:00:00Z",
|
|
42
|
+
"reason": "one-shot complete" }
|
|
43
|
+
}
|
|
44
|
+
}
|
|
45
|
+
}
|
|
46
|
+
});
|
|
47
|
+
std::fs::create_dir_all(ws.join(".team/runtime")).unwrap();
|
|
48
|
+
save_runtime_state(ws, &state).unwrap();
|
|
49
|
+
std::fs::write(ws.join("team.spec.yaml"), "name: alpha\n").unwrap();
|
|
50
|
+
}
|
|
51
|
+
|
|
52
|
+
#[test]
|
|
53
|
+
fn retired_tombstone_excludes_agent_from_restart_roster() {
|
|
54
|
+
let dir = std::env::temp_dir().join(format!("tk2-roster-{}", std::process::id()));
|
|
55
|
+
let _ = std::fs::remove_dir_all(&dir);
|
|
56
|
+
std::fs::create_dir_all(&dir).unwrap();
|
|
57
|
+
seed(&dir);
|
|
58
|
+
|
|
59
|
+
let candidates = restart_candidates(&dir).expect("restart_candidates must resolve");
|
|
60
|
+
let _ = std::fs::remove_dir_all(&dir);
|
|
61
|
+
|
|
62
|
+
let alpha = candidates
|
|
63
|
+
.iter()
|
|
64
|
+
.find(|c| c.team_name == "alpha")
|
|
65
|
+
.expect("alpha team must be a restart candidate");
|
|
66
|
+
let rostered: Vec<&str> = alpha.agents.iter().map(|a| a.as_str()).collect();
|
|
67
|
+
|
|
68
|
+
assert!(
|
|
69
|
+
rostered.contains(&"keep"),
|
|
70
|
+
"the active agent must stay in the restart roster; roster={rostered:?}"
|
|
71
|
+
);
|
|
72
|
+
assert!(
|
|
73
|
+
!rostered.contains(&"gone"),
|
|
74
|
+
"a retired-tombstoned agent must NOT be in the restart desired roster \
|
|
75
|
+
(its dynamic_role_file must not resurrect it); roster={rostered:?}"
|
|
76
|
+
);
|
|
77
|
+
}
|
|
78
|
+
|
|
79
|
+
/// L1 补牙 (r15): a retired agent that is ALSO referenced as default_assignee,
|
|
80
|
+
/// in startup_order, and as a task assignee must STILL be excluded from the
|
|
81
|
+
/// restart roster (the pub-reachable surface). The full 5-surface spec scrub is
|
|
82
|
+
/// verified by owner-b's src unit test on the pure filter fn and by the L3
|
|
83
|
+
/// real-machine rebuilt-spec assertion; this pins the roster surface under a
|
|
84
|
+
/// MULTI-reference retired agent so a lingering reference cannot resurrect it.
|
|
85
|
+
fn seed_multiref(ws: &std::path::Path) {
|
|
86
|
+
let role_dir = ws.join(".team/runtime/teams/alpha/role-masters");
|
|
87
|
+
std::fs::create_dir_all(&role_dir).unwrap();
|
|
88
|
+
let gone_role = role_dir.join("boss.md");
|
|
89
|
+
std::fs::write(&gone_role, "---\nname: boss\nprovider: fake\n---\nboss\n").unwrap();
|
|
90
|
+
let state = json!({
|
|
91
|
+
"active_team_key": "alpha",
|
|
92
|
+
"session_name": "team-alpha",
|
|
93
|
+
"agents": {
|
|
94
|
+
"keep": { "status": "running", "provider": "fake" },
|
|
95
|
+
"boss": { "status": "running", "provider": "fake",
|
|
96
|
+
"dynamic_role_file": gone_role.to_string_lossy() }
|
|
97
|
+
},
|
|
98
|
+
"teams": {
|
|
99
|
+
"alpha": {
|
|
100
|
+
"status": "alive",
|
|
101
|
+
"session_name": "team-alpha",
|
|
102
|
+
"agents": {
|
|
103
|
+
"keep": { "status": "running", "provider": "fake" },
|
|
104
|
+
"boss": { "status": "running", "provider": "fake",
|
|
105
|
+
"dynamic_role_file": gone_role.to_string_lossy() }
|
|
106
|
+
},
|
|
107
|
+
"routing": { "default_assignee": "boss",
|
|
108
|
+
"rules": [{ "assign_to": "boss", "match": "*" }] },
|
|
109
|
+
"runtime": { "startup_order": ["boss", "keep"] },
|
|
110
|
+
"tasks": [{ "id": "t1", "assignee": "boss" }],
|
|
111
|
+
"agent_lifecycle": {
|
|
112
|
+
"boss": { "state": "retired", "changed_at": "2026-07-20T00:00:00Z",
|
|
113
|
+
"reason": "one-shot lead complete" }
|
|
114
|
+
}
|
|
115
|
+
}
|
|
116
|
+
}
|
|
117
|
+
});
|
|
118
|
+
std::fs::create_dir_all(ws.join(".team/runtime")).unwrap();
|
|
119
|
+
save_runtime_state(ws, &state).unwrap();
|
|
120
|
+
std::fs::write(ws.join("team.spec.yaml"), "name: alpha\n").unwrap();
|
|
121
|
+
}
|
|
122
|
+
|
|
123
|
+
#[test]
|
|
124
|
+
fn retired_default_assignee_with_many_references_is_still_excluded_from_roster() {
|
|
125
|
+
let dir = std::env::temp_dir().join(format!("tk2-roster-mref-{}", std::process::id()));
|
|
126
|
+
let _ = std::fs::remove_dir_all(&dir);
|
|
127
|
+
std::fs::create_dir_all(&dir).unwrap();
|
|
128
|
+
seed_multiref(&dir);
|
|
129
|
+
let candidates = restart_candidates(&dir).expect("restart_candidates must resolve");
|
|
130
|
+
let _ = std::fs::remove_dir_all(&dir);
|
|
131
|
+
let alpha = candidates
|
|
132
|
+
.iter()
|
|
133
|
+
.find(|c| c.team_name == "alpha")
|
|
134
|
+
.expect("alpha team must be a restart candidate");
|
|
135
|
+
let rostered: Vec<&str> = alpha.agents.iter().map(|a| a.as_str()).collect();
|
|
136
|
+
assert!(
|
|
137
|
+
rostered.contains(&"keep"),
|
|
138
|
+
"active agent must stay; roster={rostered:?}"
|
|
139
|
+
);
|
|
140
|
+
assert!(
|
|
141
|
+
!rostered.contains(&"boss"),
|
|
142
|
+
"a retired agent that is default_assignee / in startup_order / a task assignee \
|
|
143
|
+
must STILL be excluded from the restart roster; roster={rostered:?}"
|
|
144
|
+
);
|
|
145
|
+
}
|