@team-agent/installer 0.5.64 → 0.5.66
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/Cargo.toml +5 -0
- package/crates/team-agent/src/cli/adapters.rs +6 -1
- package/crates/team-agent/src/cli/emit.rs +15 -0
- package/crates/team-agent/src/cli/mod.rs +9 -8
- package/crates/team-agent/src/cli/send/presentation.rs +1 -0
- package/crates/team-agent/src/cli/spec.rs +3 -0
- package/crates/team-agent/src/cli/tests/compile.rs +1 -1
- package/crates/team-agent/src/cli/tests/mod.rs +33 -2
- package/crates/team-agent/src/cli/tests/run_delegation.rs +1 -1
- package/crates/team-agent/src/cli/tests/status_send.rs +13 -3
- package/crates/team-agent/src/cli/tests/verb_validate.rs +1 -1
- package/crates/team-agent/src/cli/types.rs +7 -0
- package/crates/team-agent/src/compiler/tests.rs +23 -20
- package/crates/team-agent/src/compiler.rs +25 -5
- package/crates/team-agent/src/conpty/backend.rs +16 -0
- package/crates/team-agent/src/coordinator/health.rs +17 -0
- package/crates/team-agent/src/coordinator/steps/abnormal.rs +55 -2
- package/crates/team-agent/src/db/migration.rs +2 -1
- package/crates/team-agent/src/db/schema.rs +16 -8
- package/crates/team-agent/src/leader/lease.rs +1 -2
- package/crates/team-agent/src/leader/start.rs +175 -10
- package/crates/team-agent/src/leader/tests/team_in_team_state_scope_red.rs +1 -1
- package/crates/team-agent/src/lifecycle/launch/add_agent.rs +0 -2
- package/crates/team-agent/src/lifecycle/launch/add_agent_state.rs +7 -2
- package/crates/team-agent/src/lifecycle/launch/agent_state.rs +137 -2
- package/crates/team-agent/src/lifecycle/launch/fork_agent.rs +1 -2
- package/crates/team-agent/src/lifecycle/launch/fork_finalize.rs +5 -0
- package/crates/team-agent/src/lifecycle/launch/spawn.rs +39 -2
- package/crates/team-agent/src/lifecycle/launch/spec_state.rs +105 -48
- package/crates/team-agent/src/lifecycle/launch/state_projection.rs +0 -2
- package/crates/team-agent/src/lifecycle/launch.rs +117 -21
- package/crates/team-agent/src/lifecycle/restart/agent.rs +89 -3
- package/crates/team-agent/src/lifecycle/restart/common.rs +9 -12
- package/crates/team-agent/src/lifecycle/restart/rebuild.rs +59 -15
- package/crates/team-agent/src/lifecycle/tests/acceptance_b_batch_red.rs +1 -1
- package/crates/team-agent/src/lifecycle/tests/agent_ops.rs +4 -4
- package/crates/team-agent/src/lifecycle/tests/behavioral_diff_264_red.rs +1 -1
- package/crates/team-agent/src/lifecycle/tests/claude_compatible_config_red.rs +2 -2
- package/crates/team-agent/src/lifecycle/tests/claude_profile_launch_red.rs +4 -4
- package/crates/team-agent/src/lifecycle/tests/clone_fork_copilot_perms_red.rs +24 -32
- package/crates/team-agent/src/lifecycle/tests/communication_mode_runtime_contract_red.rs +2 -2
- package/crates/team-agent/src/lifecycle/tests/copilot_provider_red.rs +13 -11
- package/crates/team-agent/src/lifecycle/tests/core.rs +0 -18
- package/crates/team-agent/src/lifecycle/tests/core_034_real_red.rs +1 -1
- package/crates/team-agent/src/lifecycle/tests/display_adaptive_red.rs +1 -1
- package/crates/team-agent/src/lifecycle/tests/f032_startup_prompt_best_effort_red.rs +1 -1
- package/crates/team-agent/src/lifecycle/tests/harvest2_a_batch_red.rs +3 -0
- package/crates/team-agent/src/lifecycle/tests/host_cotenant_death_p0_contract.rs +3 -3
- package/crates/team-agent/src/lifecycle/tests/lane_ops.rs +2 -2
- package/crates/team-agent/src/lifecycle/tests/launch_spawn.rs +17 -30
- package/crates/team-agent/src/lifecycle/tests/lifecycle_rollback_red.rs +1 -1
- package/crates/team-agent/src/lifecycle/tests/phase_b_contracts.rs +4 -4
- package/crates/team-agent/src/lifecycle/tests/phase_golden.rs +1 -1
- package/crates/team-agent/src/lifecycle/tests/quick_start_worker_readiness_red.rs +2 -2
- package/crates/team-agent/src/lifecycle/tests/restart_build_before_destroy_0540_contract.rs +1 -1
- package/crates/team-agent/src/lifecycle/tests/restart_liveness_red.rs +1 -1
- package/crates/team-agent/src/lifecycle/tests/restart_rebind_hotfix_252_red.rs +1 -1
- package/crates/team-agent/src/lifecycle/tests/restart_session_capture_red.rs +2 -2
- package/crates/team-agent/src/lifecycle/tests/resume_recover_red.rs +1 -1
- package/crates/team-agent/src/lifecycle/tests/stale_team_saveconflict_contract.rs +1 -1
- package/crates/team-agent/src/lifecycle/tests/startup_latency_contract.rs +11 -7
- package/crates/team-agent/src/lifecycle/tests/status_credential_redaction_contract.rs +3 -3
- package/crates/team-agent/src/lifecycle/tests/subprep_codex_trust_roundtrip_red.rs +1 -1
- package/crates/team-agent/src/lifecycle/tests/swallow_batch4_semantics_red.rs +1 -1
- package/crates/team-agent/src/lifecycle/tests/team_in_team_identity_scope_red.rs +1 -1
- package/crates/team-agent/src/lifecycle/tests/team_in_team_sibling_quick_start_red.rs +1 -1
- package/crates/team-agent/src/lifecycle/tests/team_in_team_state_scope_red.rs +1 -1
- package/crates/team-agent/src/lifecycle/tests/team_key_retirement_txn_red.rs +1 -1
- package/crates/team-agent/src/lifecycle/tests/test_isolation_escape_contract.rs +1 -1
- package/crates/team-agent/src/lifecycle/tests/upgrade_compat_0211_red.rs +1 -1
- package/crates/team-agent/src/lifecycle/tests/verify_rs031_window_consistency_red.rs +2 -2
- package/crates/team-agent/src/lifecycle/tests/worker_spawn_env_red.rs +1 -1
- package/crates/team-agent/src/lifecycle/tests.rs +11 -7
- package/crates/team-agent/src/lifecycle/types.rs +0 -2
- package/crates/team-agent/src/lifecycle/worker_command_context.rs +115 -22
- package/crates/team-agent/src/mcp_server/helpers.rs +1 -0
- package/crates/team-agent/src/messaging/delivery.rs +29 -0
- package/crates/team-agent/src/messaging/helpers.rs +2 -0
- package/crates/team-agent/src/messaging/leader_receiver.rs +12 -0
- package/crates/team-agent/src/messaging/mod.rs +2 -0
- package/crates/team-agent/src/messaging/results.rs +5 -0
- package/crates/team-agent/src/messaging/send.rs +9 -0
- package/crates/team-agent/src/messaging/tests/main_preserved.rs +1 -1
- package/crates/team-agent/src/messaging/tests/runtime.rs +32 -0
- package/crates/team-agent/src/messaging/types.rs +2 -0
- package/crates/team-agent/src/messaging/wait.rs +366 -0
- package/crates/team-agent/src/messaging/watchers.rs +153 -6
- package/crates/team-agent/src/model/spec.rs +129 -6
- package/crates/team-agent/src/model/testdata/spec_invalid_a.yaml +3 -1
- package/crates/team-agent/src/model/testdata/team.spec.golden.yaml +3 -1
- package/crates/team-agent/src/model/testdata/team.spec.yaml +3 -1
- package/crates/team-agent/src/provider/adapters/claude.rs +5 -2
- package/crates/team-agent/src/provider/adapters/codex.rs +5 -2
- package/crates/team-agent/src/provider/adapters/copilot.rs +5 -2
- package/crates/team-agent/src/provider/bypass_flags.rs +80 -0
- package/crates/team-agent/src/provider/mod.rs +2 -0
- package/crates/team-agent/src/tmux_backend.rs +35 -12
- package/crates/team-agent/src/transport/test_support.rs +20 -0
- package/crates/team-agent/src/transport.rs +28 -11
- package/package.json +4 -4
- package/crates/team-agent/src/lifecycle/launch/approval.rs +0 -134
- package/crates/team-agent/src/lifecycle/tests/codex_mcp_approval_inheritance_red.rs +0 -1187
- package/crates/team-agent/src/lifecycle/tests/worker_dangerous_bypass_argv_red.rs +0 -327
|
@@ -229,8 +229,9 @@ team_orchestrator or @<.team/runtime/mcp/worker_a.json>; got {value:?}"
|
|
|
229
229
|
}
|
|
230
230
|
|
|
231
231
|
/// Face 1 dangerous tier (C-5-1, verdict `dangerous_auto_approve_argv_contains_allow_all`):
|
|
232
|
-
///
|
|
233
|
-
/// parity, paths+urls included) — NOT the
|
|
232
|
+
/// role `dangerously_skip_permissions: true` must map to `--allow-all` (claude
|
|
233
|
+
/// `--dangerously-skip-permissions` parity, paths+urls included) — NOT the
|
|
234
|
+
/// silently-narrower `--allow-all-tools`. 0.5.66 bypass 单源:bypass 由角色字段驱动。
|
|
234
235
|
#[test]
|
|
235
236
|
#[serial(env)]
|
|
236
237
|
fn copilot_argv_dangerous_maps_to_allow_all() {
|
|
@@ -254,7 +255,7 @@ fn copilot_argv_dangerous_maps_to_allow_all() {
|
|
|
254
255
|
let mut failures = Vec::new();
|
|
255
256
|
if !argv.iter().any(|arg| arg == "--allow-all") {
|
|
256
257
|
failures.push(format!(
|
|
257
|
-
"C-5-1:
|
|
258
|
+
"C-5-1: dangerously_skip_permissions=true must produce `--allow-all` (=--yolo, claude \
|
|
258
259
|
parity incl. paths+urls); argv={argv:?}"
|
|
259
260
|
));
|
|
260
261
|
}
|
|
@@ -1101,8 +1102,8 @@ fn copilot_subscription_model_precedence_role_over_profile() {
|
|
|
1101
1102
|
// point the agent at the profile
|
|
1102
1103
|
let agent_md = team_dir.join("agents/worker_a.md");
|
|
1103
1104
|
let body = std::fs::read_to_string(&agent_md).unwrap().replace(
|
|
1104
|
-
"auth_mode: subscription\n",
|
|
1105
|
-
"auth_mode: subscription\nprofile: subm\n",
|
|
1105
|
+
"auth_mode: subscription\ndangerously_skip_permissions: false\n",
|
|
1106
|
+
"auth_mode: subscription\ndangerously_skip_permissions: false\nprofile: subm\n",
|
|
1106
1107
|
);
|
|
1107
1108
|
std::fs::write(&agent_md, body).unwrap();
|
|
1108
1109
|
seed_healthy_coordinator(&ws);
|
|
@@ -1387,7 +1388,7 @@ fn write_copilot_byok_team(ws: &Path, name: &str, model: Option<&str>) -> PathBu
|
|
|
1387
1388
|
std::fs::write(
|
|
1388
1389
|
team.join("agents/worker_a.md"),
|
|
1389
1390
|
format!(
|
|
1390
|
-
"---\nname: worker_a\nrole: Copilot Worker\nprovider: copilot\n{model_field}auth_mode: compatible_api\nprofile: byok\ntools:\n - mcp_team\n---\n\nCOPILOT ROLE BODY SENTINEL: BYOK worker.\n"
|
|
1391
|
+
"---\nname: worker_a\nrole: Copilot Worker\nprovider: copilot\n{model_field}auth_mode: compatible_api\ndangerously_skip_permissions: false\nprofile: byok\ntools:\n - mcp_team\n---\n\nCOPILOT ROLE BODY SENTINEL: BYOK worker.\n"
|
|
1391
1392
|
),
|
|
1392
1393
|
)
|
|
1393
1394
|
.unwrap();
|
|
@@ -1412,15 +1413,16 @@ fn write_copilot_team(ws: &Path, name: &str, tools: &[&str], dangerous: bool) ->
|
|
|
1412
1413
|
let _ = TeamOpts;
|
|
1413
1414
|
let team = ws.join(name);
|
|
1414
1415
|
std::fs::create_dir_all(team.join("agents")).unwrap();
|
|
1415
|
-
|
|
1416
|
-
|
|
1416
|
+
// 0.5.66 bypass 单源:bypass 由角色字段驱动,不再是 TEAM.md dangerous_auto_approve。
|
|
1417
|
+
let role_bypass = if dangerous {
|
|
1418
|
+
"true"
|
|
1417
1419
|
} else {
|
|
1418
|
-
""
|
|
1420
|
+
"false"
|
|
1419
1421
|
};
|
|
1420
1422
|
std::fs::write(
|
|
1421
1423
|
team.join("TEAM.md"),
|
|
1422
1424
|
format!(
|
|
1423
|
-
"---\nname: {name}\nobjective: copilot provider contract fixture.\nprovider: copilot\n
|
|
1425
|
+
"---\nname: {name}\nobjective: copilot provider contract fixture.\nprovider: copilot\n---\n\nTeam fixture.\n"
|
|
1424
1426
|
),
|
|
1425
1427
|
)
|
|
1426
1428
|
.unwrap();
|
|
@@ -1431,7 +1433,7 @@ fn write_copilot_team(ws: &Path, name: &str, tools: &[&str], dangerous: bool) ->
|
|
|
1431
1433
|
std::fs::write(
|
|
1432
1434
|
team.join("agents/worker_a.md"),
|
|
1433
1435
|
format!(
|
|
1434
|
-
"---\nname: worker_a\nrole: Copilot Worker\nprovider: copilot\nmodel: gpt-5\nauth_mode: subscription\ntools:\n{tool_lines}---\n\nCOPILOT ROLE BODY SENTINEL: serve the copilot adapter contract.\n"
|
|
1436
|
+
"---\nname: worker_a\nrole: Copilot Worker\nprovider: copilot\nmodel: gpt-5\nauth_mode: subscription\ndangerously_skip_permissions: {role_bypass}\ntools:\n{tool_lines}---\n\nCOPILOT ROLE BODY SENTINEL: serve the copilot adapter contract.\n"
|
|
1435
1437
|
),
|
|
1436
1438
|
)
|
|
1437
1439
|
.unwrap();
|
|
@@ -1010,24 +1010,6 @@ fn quick_start_empty_dir_returns_typed_report_not_error_path_only() {
|
|
|
1010
1010
|
}
|
|
1011
1011
|
}
|
|
1012
1012
|
|
|
1013
|
-
// ───────────────────────────────────────────────────────────────────────
|
|
1014
|
-
// detect_dangerous_approval — launch/config.py
|
|
1015
|
-
// 默认进程(无 --dangerously-* 祖先)→ enabled=false / source=Disabled / inherited=false。
|
|
1016
|
-
// launch 在 inherited=false 且无 --yes 时 raise DangerousApprovalRequired(core.py:120)。
|
|
1017
|
-
// ───────────────────────────────────────────────────────────────────────
|
|
1018
|
-
|
|
1019
|
-
#[test]
|
|
1020
|
-
#[serial_test::serial(env)]
|
|
1021
|
-
fn detect_dangerous_approval_clean_process_is_disabled() {
|
|
1022
|
-
// Explicit mock ancestry keeps the test independent from the real Codex/CI
|
|
1023
|
-
// process tree that runs cargo.
|
|
1024
|
-
let _ancestry = EnvVarGuard::set("TEAM_AGENT_TEST_PROCESS_ANCESTRY_ARGV_JSON", "[]");
|
|
1025
|
-
let got = detect_dangerous_approval().expect("探测祖先链应 Ok");
|
|
1026
|
-
assert!(!got.enabled, "干净进程不应启用危险审批");
|
|
1027
|
-
assert_eq!(got.source, DangerousApprovalSource::Disabled);
|
|
1028
|
-
assert!(!got.inherited);
|
|
1029
|
-
}
|
|
1030
|
-
|
|
1031
1013
|
#[test]
|
|
1032
1014
|
#[serial_test::serial(env)]
|
|
1033
1015
|
fn leader_pane_env_absent_pane_fails_fast() {
|
|
@@ -746,7 +746,7 @@ fn write_team(
|
|
|
746
746
|
std::fs::write(
|
|
747
747
|
team.join("agents").join(format!("{}.md", agent.id)),
|
|
748
748
|
format!(
|
|
749
|
-
"---\nname: {}\nrole: {}\nprovider: {}\nmodel: fake\nauth_mode: subscription\ntools:\n{}---\n\n{}\n",
|
|
749
|
+
"---\nname: {}\nrole: {}\nprovider: {}\nmodel: fake\nauth_mode: subscription\ndangerously_skip_permissions: false\ntools:\n{}---\n\n{}\n",
|
|
750
750
|
agent.id, agent.role, agent.provider, tools, agent.body
|
|
751
751
|
),
|
|
752
752
|
)
|
|
@@ -358,7 +358,7 @@ impl DisplayFixture {
|
|
|
358
358
|
std::fs::write(
|
|
359
359
|
team.join("agents").join(format!("{worker}.md")),
|
|
360
360
|
format!(
|
|
361
|
-
"---\nname: {worker}\nrole: Adaptive fake worker {worker}\nprovider: fake\nmodel: fake\nauth_mode: subscription\ntools:\n - mcp_team\n---\n\nWorker.\n"
|
|
361
|
+
"---\nname: {worker}\nrole: Adaptive fake worker {worker}\nprovider: fake\nmodel: fake\nauth_mode: subscription\ndangerously_skip_permissions: false\ntools:\n - mcp_team\n---\n\nWorker.\n"
|
|
362
362
|
),
|
|
363
363
|
)
|
|
364
364
|
.unwrap();
|
|
@@ -27,7 +27,7 @@ static SEQ: AtomicU32 = AtomicU32::new(0);
|
|
|
27
27
|
|
|
28
28
|
const TEAM_MD: &str =
|
|
29
29
|
"---\nname: f032team\nobjective: F032 lifecycle prompt fault probe.\nprovider: codex\n---\n\nF032.\n";
|
|
30
|
-
const ROLE_MD: &str = "---\nname: implementer\nrole: Implementation Engineer\nprovider: codex\nmodel: gpt-5.5\nauth_mode: subscription\ntools:\n - mcp_team\n---\n\nImplement.\n";
|
|
30
|
+
const ROLE_MD: &str = "---\nname: implementer\nrole: Implementation Engineer\nprovider: codex\nmodel: gpt-5.5\nauth_mode: subscription\ndangerously_skip_permissions: false\ntools:\n - mcp_team\n---\n\nImplement.\n";
|
|
31
31
|
|
|
32
32
|
#[test]
|
|
33
33
|
fn f032_launch_spawn_path_treats_startup_prompt_panic_as_best_effort() {
|
|
@@ -422,7 +422,10 @@ check behind it = false green); it must reflect an actual doctor result"
|
|
|
422
422
|
/// T3-2 (claude_auth_hint parse failure): when `claude auth status` output is
|
|
423
423
|
/// unparseable / unsuccessful, the hint must not default to Present (auth misreported
|
|
424
424
|
/// as available). PATH-shims a `claude` that prints garbage and exits non-zero.
|
|
425
|
+
/// Mutates the process-global PATH/HOME — must not race host_cotenant's ps/tmux
|
|
426
|
+
/// shims (P0 pid-probe isolation), hence `#[serial(pid_probe)]`.
|
|
425
427
|
#[test]
|
|
428
|
+
#[serial(pid_probe)]
|
|
426
429
|
fn t3_claude_auth_hint_parse_failure_is_not_present() {
|
|
427
430
|
let home = tmp_ws("t3-auth-home");
|
|
428
431
|
let shim_dir = home.join("bin");
|
|
@@ -65,7 +65,7 @@ const POLLUTED_CALLER_AUTHORITY_ENVS: &[&str] = &[
|
|
|
65
65
|
];
|
|
66
66
|
|
|
67
67
|
#[test]
|
|
68
|
-
#[serial(env)]
|
|
68
|
+
#[serial(env, pid_probe)]
|
|
69
69
|
fn polluted_caller_env_never_authorizes_teardown_to_kill_foreign_tmux() {
|
|
70
70
|
let env = hermetic_guard::HermeticTestEnv::enter("p0-caller-env-sentinel");
|
|
71
71
|
let shim_dir = env.root().join("bin");
|
|
@@ -150,7 +150,7 @@ exec "$TEAM_AGENT_TEST_REAL_TMUX" "$@"
|
|
|
150
150
|
}
|
|
151
151
|
|
|
152
152
|
#[test]
|
|
153
|
-
#[serial(env)]
|
|
153
|
+
#[serial(env, pid_probe)]
|
|
154
154
|
fn restart_allow_fresh_does_not_leave_same_role_host_cotenants() {
|
|
155
155
|
let mut failures = Vec::new();
|
|
156
156
|
let (env, workspace) = team_case("p0-restart", &["developer", "test-engineer", "arch-reviewer"]);
|
|
@@ -677,7 +677,7 @@ fn write_team_docs(workspace: &Path, workers: &[(&str, &str)]) {
|
|
|
677
677
|
fs::create_dir_all(workspace.join("agents")).unwrap();
|
|
678
678
|
fs::write(workspace.join("TEAM.md"), "---\nname: current\nobjective: P0 host co-tenant contract.\nprovider: codex\n---\n").unwrap();
|
|
679
679
|
for (worker, model) in workers {
|
|
680
|
-
let role = format!("---\nname: {worker}\nrole: {worker}\nprovider: codex\nmodel: {model}\nauth_mode: subscription\ntools:\n - mcp_team\n---\n\n{worker}.\n");
|
|
680
|
+
let role = format!("---\nname: {worker}\nrole: {worker}\nprovider: codex\nmodel: {model}\nauth_mode: subscription\ndangerously_skip_permissions: false\ntools:\n - mcp_team\n---\n\n{worker}.\n");
|
|
681
681
|
fs::write(workspace.join("agents").join(format!("{worker}.md")), role).unwrap();
|
|
682
682
|
}
|
|
683
683
|
}
|
|
@@ -3,7 +3,7 @@ use super::*;
|
|
|
3
3
|
|
|
4
4
|
// ═════════════════════════════════════════════════════════════════════════
|
|
5
5
|
|
|
6
|
-
const DELEG_ROLE_ALPHA_COMPAT: &str = "---\nname: alpha\nrole: Alpha Worker\nprovider: codex\nmodel: gpt-5.5\nauth_mode: compatible_api\nprofile: alpha-compat\ntools:\n - mcp_team\n---\n\nAlpha.\n";
|
|
6
|
+
const DELEG_ROLE_ALPHA_COMPAT: &str = "---\nname: alpha\nrole: Alpha Worker\nprovider: codex\nmodel: gpt-5.5\nauth_mode: compatible_api\ndangerously_skip_permissions: false\nprofile: alpha-compat\ntools:\n - mcp_team\n---\n\nAlpha.\n";
|
|
7
7
|
|
|
8
8
|
type LaneKills = std::sync::Arc<std::sync::Mutex<Vec<String>>>;
|
|
9
9
|
pub(super) type LaneSpawns = std::sync::Arc<std::sync::Mutex<Vec<(String, Vec<String>)>>>;
|
|
@@ -816,7 +816,7 @@ fn current_alias_authority_does_not_leak_into_real_sibling_same_id_retirement()
|
|
|
816
816
|
);
|
|
817
817
|
}
|
|
818
818
|
|
|
819
|
-
const CHARLIE_ROLE: &str = "---\nname: charlie\nrole: Charlie Worker\nprovider: codex\nmodel: gpt-5.5\nauth_mode: subscription\ntools:\n - mcp_team\n---\n\nCharlie.\n";
|
|
819
|
+
const CHARLIE_ROLE: &str = "---\nname: charlie\nrole: Charlie Worker\nprovider: codex\nmodel: gpt-5.5\nauth_mode: subscription\ndangerously_skip_permissions: false\ntools:\n - mcp_team\n---\n\nCharlie.\n";
|
|
820
820
|
|
|
821
821
|
struct HermeticTestEnv {
|
|
822
822
|
root: std::path::PathBuf,
|
|
@@ -31,8 +31,8 @@ struct HermeticTestEnv;
|
|
|
31
31
|
|
|
32
32
|
const QS_TEAM_MD: &str =
|
|
33
33
|
"---\nname: quickteam\nobjective: Quick start.\nprovider: codex\n---\n\nQuick-start team.\n";
|
|
34
|
-
pub(super) const QS_VALID_ROLE: &str = "---\nname: implementer\nrole: Implementation Engineer\nprovider: codex\nmodel: gpt-5.5\nauth_mode: subscription\ntools:\n - mcp_team\n---\n\nImplement bounded tasks.\n";
|
|
35
|
-
const QS_ROLE_NO_PROVIDER: &str = "---\nname: implementer\nrole: Implementation Engineer\nmodel: gpt-5.5\nauth_mode: subscription\ntools:\n - mcp_team\n---\n\nImplement bounded tasks.\n";
|
|
34
|
+
pub(super) const QS_VALID_ROLE: &str = "---\nname: implementer\nrole: Implementation Engineer\nprovider: codex\nmodel: gpt-5.5\nauth_mode: subscription\ndangerously_skip_permissions: false\ntools:\n - mcp_team\n---\n\nImplement bounded tasks.\n";
|
|
35
|
+
const QS_ROLE_NO_PROVIDER: &str = "---\nname: implementer\nrole: Implementation Engineer\nmodel: gpt-5.5\nauth_mode: subscription\ndangerously_skip_permissions: false\ntools:\n - mcp_team\n---\n\nImplement bounded tasks.\n";
|
|
36
36
|
|
|
37
37
|
/// A REAL team dir `<base>/teamdir/{TEAM.md, agents/implementer.md}` — already in team-dir
|
|
38
38
|
/// layout, so quick_start's prepare_quick_start_team returns it as-is and writes the compiled
|
|
@@ -57,7 +57,7 @@ fn quick_start_team_dir_with_roles(role_docs: &[(&str, &str)]) -> PathBuf {
|
|
|
57
57
|
|
|
58
58
|
fn role_doc(id: &str) -> String {
|
|
59
59
|
format!(
|
|
60
|
-
"---\nname: {id}\nrole: {id} Worker\nprovider: codex\nmodel: gpt-5.5\nauth_mode: subscription\ntools:\n - mcp_team\n---\n\n{id} worker.\n"
|
|
60
|
+
"---\nname: {id}\nrole: {id} Worker\nprovider: codex\nmodel: gpt-5.5\nauth_mode: subscription\ndangerously_skip_permissions: false\ntools:\n - mcp_team\n---\n\n{id} worker.\n"
|
|
61
61
|
)
|
|
62
62
|
}
|
|
63
63
|
|
|
@@ -448,7 +448,7 @@ fn add_agent_proceeds_past_owner_gate_and_reaches_recompile() {
|
|
|
448
448
|
let role = ws.join("w2-role.md");
|
|
449
449
|
std::fs::write(
|
|
450
450
|
&role,
|
|
451
|
-
"---\nname: w2\nrole: Second Worker\nprovider: codex\nmodel: gpt-5.5\nauth_mode: subscription\ntools:\n - mcp_team\n---\n\nSecond worker.\n",
|
|
451
|
+
"---\nname: w2\nrole: Second Worker\nprovider: codex\nmodel: gpt-5.5\nauth_mode: subscription\ndangerously_skip_permissions: false\ntools:\n - mcp_team\n---\n\nSecond worker.\n",
|
|
452
452
|
)
|
|
453
453
|
.unwrap();
|
|
454
454
|
let transport = OfflineTransport::new();
|
|
@@ -617,23 +617,8 @@ fn spine_quick_start_seeds_state_under_team_workspace_not_team_dir() {
|
|
|
617
617
|
);
|
|
618
618
|
}
|
|
619
619
|
|
|
620
|
-
// #10 — launch dry-run safety
|
|
621
|
-
//
|
|
622
|
-
#[test]
|
|
623
|
-
fn spine_launch_dry_run_safety_reflects_spec_dangerous() {
|
|
624
|
-
let team = quick_start_team_dir_custom(QS_TEAM_MD_DANGEROUS, QS_VALID_ROLE);
|
|
625
|
-
let spec_path = compiled_spec_path(&team);
|
|
626
|
-
let report = launch(&spec_path, true, false, true).expect("dry_run launch");
|
|
627
|
-
assert!(
|
|
628
|
-
report.safety.enabled,
|
|
629
|
-
"safety must reflect spec.runtime.dangerous_auto_approve=true"
|
|
630
|
-
);
|
|
631
|
-
assert_eq!(
|
|
632
|
-
report.safety.source,
|
|
633
|
-
DangerousApprovalSource::RuntimeConfig,
|
|
634
|
-
"safety source must be runtime_config when spec-declared"
|
|
635
|
-
);
|
|
636
|
-
}
|
|
620
|
+
// #10 removed — launch dry-run safety was derived from spec.runtime.dangerous_auto_approve.
|
|
621
|
+
// 0.5.66 bypass 单源:该字段废弃,safety 改由 per-agent `dangerously_skip_permissions` 派生。
|
|
637
622
|
|
|
638
623
|
// #12 — launch dry-run produces one RoutingDecision PER spec.task via route_task, with the real task id
|
|
639
624
|
// and the route_task reason taxonomy — not one synthetic 'default_assignee' route. Golden core.py:77-88.
|
|
@@ -709,7 +694,7 @@ fn e5_add_agent_does_not_copy_role_into_platform_dir_and_injects_into_spec() {
|
|
|
709
694
|
seed_canonical_team_identity(&team, "teamdir");
|
|
710
695
|
// External role file OUTSIDE team_dir/agents, with recognizable body content.
|
|
711
696
|
let role = team.parent().unwrap().join("w2-external-role.md");
|
|
712
|
-
let role_body = "---\nname: w2\nrole: Second Worker\nprovider: codex\nmodel: gpt-5.5\nauth_mode: subscription\ntools:\n - mcp_team\n---\n\nUNIQUE-E5-BUG1-MARKER body for w2.\n";
|
|
697
|
+
let role_body = "---\nname: w2\nrole: Second Worker\nprovider: codex\nmodel: gpt-5.5\nauth_mode: subscription\ndangerously_skip_permissions: false\ntools:\n - mcp_team\n---\n\nUNIQUE-E5-BUG1-MARKER body for w2.\n";
|
|
713
698
|
std::fs::write(&role, role_body).unwrap();
|
|
714
699
|
let transport = OfflineTransport::new();
|
|
715
700
|
// The spawn may not complete under OfflineTransport; we only assert the no-copy + spec-inject
|
|
@@ -749,7 +734,7 @@ fn e5_restart_rebuilds_runtime_spec_from_role_docs() {
|
|
|
749
734
|
// Edit a role doc AFTER initial compile: change alpha's role text.
|
|
750
735
|
std::fs::write(
|
|
751
736
|
ws.join("agents").join("alpha.md"),
|
|
752
|
-
"---\nname: alpha\nrole: RENAMED Alpha Role\nprovider: codex\nmodel: gpt-5.5\nauth_mode: subscription\ntools:\n - mcp_team\n---\n\nAlpha edited.\n",
|
|
737
|
+
"---\nname: alpha\nrole: RENAMED Alpha Role\nprovider: codex\nmodel: gpt-5.5\nauth_mode: subscription\ndangerously_skip_permissions: false\ntools:\n - mcp_team\n---\n\nAlpha edited.\n",
|
|
753
738
|
)
|
|
754
739
|
.unwrap();
|
|
755
740
|
let transport = OfflineTransport::new();
|
|
@@ -974,7 +959,7 @@ fn e5_add_agent_resolves_team_dir_to_role_dir_when_runtime_spec_exists() {
|
|
|
974
959
|
let role = team.join("w2-role.md");
|
|
975
960
|
std::fs::write(
|
|
976
961
|
&role,
|
|
977
|
-
"---\nname: w2\nrole: Second Worker\nprovider: codex\nmodel: gpt-5.5\nauth_mode: subscription\ntools:\n - mcp_team\n---\n\nw2.\n",
|
|
962
|
+
"---\nname: w2\nrole: Second Worker\nprovider: codex\nmodel: gpt-5.5\nauth_mode: subscription\ndangerously_skip_permissions: false\ntools:\n - mcp_team\n---\n\nw2.\n",
|
|
978
963
|
)
|
|
979
964
|
.unwrap();
|
|
980
965
|
let transport = OfflineTransport::new();
|
|
@@ -1563,9 +1548,9 @@ fn quick_start_fresh_ws_spawns_resident_tmux_and_coordinator() {
|
|
|
1563
1548
|
// Golden: restart/orchestration.py (Route-B resume spawn), lifecycle/start.py, lifecycle/operations.py.
|
|
1564
1549
|
// ═════════════════════════════════════════════════════════════════════════
|
|
1565
1550
|
|
|
1566
|
-
pub(super) const DELEG_ROLE_ALPHA: &str = "---\nname: alpha\nrole: Alpha Worker\nprovider: codex\nmodel: gpt-5.5\nauth_mode: subscription\ntools:\n - mcp_team\n---\n\nAlpha.\n";
|
|
1567
|
-
pub(super) const DELEG_ROLE_BRAVO: &str = "---\nname: bravo\nrole: Bravo Worker\nprovider: codex\nmodel: gpt-5.5\nauth_mode: subscription\ntools:\n - mcp_team\n---\n\nBravo.\n";
|
|
1568
|
-
const DELEG_ROLE_WORKER2: &str = "---\nname: worker2\nrole: Second Worker\nprovider: codex\nmodel: gpt-5.5\nauth_mode: subscription\ntools:\n - mcp_team\n---\n\nSecond worker.\n";
|
|
1551
|
+
pub(super) const DELEG_ROLE_ALPHA: &str = "---\nname: alpha\nrole: Alpha Worker\nprovider: codex\nmodel: gpt-5.5\nauth_mode: subscription\ndangerously_skip_permissions: false\ntools:\n - mcp_team\n---\n\nAlpha.\n";
|
|
1552
|
+
pub(super) const DELEG_ROLE_BRAVO: &str = "---\nname: bravo\nrole: Bravo Worker\nprovider: codex\nmodel: gpt-5.5\nauth_mode: subscription\ndangerously_skip_permissions: false\ntools:\n - mcp_team\n---\n\nBravo.\n";
|
|
1553
|
+
const DELEG_ROLE_WORKER2: &str = "---\nname: worker2\nrole: Second Worker\nprovider: codex\nmodel: gpt-5.5\nauth_mode: subscription\ndangerously_skip_permissions: false\ntools:\n - mcp_team\n---\n\nSecond worker.\n";
|
|
1569
1554
|
|
|
1570
1555
|
/// A workspace (= self-contained team dir) with a compiled 2-agent spec + state listing alpha/bravo as
|
|
1571
1556
|
/// RESUMABLE (running, valid first_send_at, session_id) + a seeded HEALTHY coordinator.
|
|
@@ -2437,7 +2422,7 @@ fn restart_allow_fresh_copilot_keeps_session_id_null_until_capture_confirms() {
|
|
|
2437
2422
|
.unwrap();
|
|
2438
2423
|
std::fs::write(
|
|
2439
2424
|
ws.join("agents").join("alpha.md"),
|
|
2440
|
-
"---\nname: alpha\nrole: Alpha Worker\nprovider: copilot\nmodel: gpt-5.5\nauth_mode: subscription\ntools:\n - mcp_team\n---\n\nAlpha.\n",
|
|
2425
|
+
"---\nname: alpha\nrole: Alpha Worker\nprovider: copilot\nmodel: gpt-5.5\nauth_mode: subscription\ndangerously_skip_permissions: false\ntools:\n - mcp_team\n---\n\nAlpha.\n",
|
|
2441
2426
|
)
|
|
2442
2427
|
.unwrap();
|
|
2443
2428
|
let spec = crate::compiler::compile_team(&ws).expect("compile copilot team");
|
|
@@ -2541,7 +2526,7 @@ fn restart_allow_fresh_claude_clears_poisoned_session_id() {
|
|
|
2541
2526
|
.unwrap();
|
|
2542
2527
|
std::fs::write(
|
|
2543
2528
|
ws.join("agents").join("alpha.md"),
|
|
2544
|
-
"---\nname: alpha\nrole: Alpha\nprovider: claude\nmodel: sonnet\nauth_mode: subscription\ntools:\n - mcp_team\n---\n\nAlpha.\n",
|
|
2529
|
+
"---\nname: alpha\nrole: Alpha\nprovider: claude\nmodel: sonnet\nauth_mode: subscription\ndangerously_skip_permissions: false\ntools:\n - mcp_team\n---\n\nAlpha.\n",
|
|
2545
2530
|
)
|
|
2546
2531
|
.unwrap();
|
|
2547
2532
|
let spec = crate::compiler::compile_team(&ws).expect("compile");
|
|
@@ -2612,7 +2597,7 @@ fn fork_refuses_source_with_partial_tuple() {
|
|
|
2612
2597
|
.unwrap();
|
|
2613
2598
|
std::fs::write(
|
|
2614
2599
|
ws.join("agents").join("src.md"),
|
|
2615
|
-
"---\nname: src\nrole: Source\nprovider: codex\nmodel: gpt\nauth_mode: subscription\ntools:\n - mcp_team\n---\n\nSrc.\n",
|
|
2600
|
+
"---\nname: src\nrole: Source\nprovider: codex\nmodel: gpt\nauth_mode: subscription\ndangerously_skip_permissions: false\ntools:\n - mcp_team\n---\n\nSrc.\n",
|
|
2616
2601
|
)
|
|
2617
2602
|
.unwrap();
|
|
2618
2603
|
let spec = crate::compiler::compile_team(&ws).expect("compile");
|
|
@@ -3084,6 +3069,8 @@ fn quick_start_running_agent_state_shape_after_spawn_is_golden() {
|
|
|
3084
3069
|
"mcp_config",
|
|
3085
3070
|
"permissions",
|
|
3086
3071
|
"effective_approval_policy",
|
|
3072
|
+
// 0.5.66 bypass 单源:fresh spawn 记录运行面 bypass 值(restart drift 挡板)。
|
|
3073
|
+
"as_launched_dangerously_skip_permissions",
|
|
3087
3074
|
"session_id",
|
|
3088
3075
|
"rollout_path",
|
|
3089
3076
|
"captured_at",
|
|
@@ -410,7 +410,7 @@ impl RollbackFixture {
|
|
|
410
410
|
|
|
411
411
|
fn agent_doc(name: &str, role: &str) -> String {
|
|
412
412
|
format!(
|
|
413
|
-
"---\nname: {name}\nrole: {role}\nprovider: codex\nauth_mode: subscription\ntools:\n - mcp_team\n---\n\n{role}.\n"
|
|
413
|
+
"---\nname: {name}\nrole: {role}\nprovider: codex\nauth_mode: subscription\ndangerously_skip_permissions: false\ntools:\n - mcp_team\n---\n\n{role}.\n"
|
|
414
414
|
)
|
|
415
415
|
}
|
|
416
416
|
|
|
@@ -463,8 +463,8 @@ fn team_dir_with_roles(role_docs: &[(&str, &str)]) -> PathBuf {
|
|
|
463
463
|
}
|
|
464
464
|
|
|
465
465
|
fn breal_workspace() -> (PathBuf, PathBuf) {
|
|
466
|
-
let w1 = "---\nname: w1\nrole: Phase B Real Worker One\nprovider: codex\nmodel: gpt-5.5\nauth_mode: subscription\ntools:\n - mcp_team\n---\n\nWorker one body.\n";
|
|
467
|
-
let w2 = "---\nname: w2\nrole: Phase B Real Worker Two\nprovider: codex\nmodel: gpt-5.5\nauth_mode: subscription\ntools:\n - mcp_team\n---\n\nWorker two body.\n";
|
|
466
|
+
let w1 = "---\nname: w1\nrole: Phase B Real Worker One\nprovider: codex\nmodel: gpt-5.5\nauth_mode: subscription\ndangerously_skip_permissions: false\ntools:\n - mcp_team\n---\n\nWorker one body.\n";
|
|
467
|
+
let w2 = "---\nname: w2\nrole: Phase B Real Worker Two\nprovider: codex\nmodel: gpt-5.5\nauth_mode: subscription\ndangerously_skip_permissions: false\ntools:\n - mcp_team\n---\n\nWorker two body.\n";
|
|
468
468
|
let team = team_dir_with_roles(&[("w1.md", w1), ("w2.md", w2)]);
|
|
469
469
|
let workspace = team.parent().expect("team workspace").to_path_buf();
|
|
470
470
|
seed_healthy_coordinator(&workspace);
|
|
@@ -483,7 +483,7 @@ fn breal_workspace() -> (PathBuf, PathBuf) {
|
|
|
483
483
|
}
|
|
484
484
|
|
|
485
485
|
fn breal_one_worker_workspace() -> (PathBuf, PathBuf) {
|
|
486
|
-
let w1 = "---\nname: w1\nrole: Phase B Real Worker One\nprovider: codex\nmodel: gpt-5.5\nauth_mode: subscription\ntools:\n - mcp_team\n---\n\nWorker one body.\n";
|
|
486
|
+
let w1 = "---\nname: w1\nrole: Phase B Real Worker One\nprovider: codex\nmodel: gpt-5.5\nauth_mode: subscription\ndangerously_skip_permissions: false\ntools:\n - mcp_team\n---\n\nWorker one body.\n";
|
|
487
487
|
let team = team_dir_with_roles(&[("w1.md", w1)]);
|
|
488
488
|
let workspace = team.parent().expect("team workspace").to_path_buf();
|
|
489
489
|
seed_healthy_coordinator(&workspace);
|
|
@@ -526,7 +526,7 @@ fn strip_runtime_command_context(workspace: &std::path::Path) {
|
|
|
526
526
|
|
|
527
527
|
fn role_doc(id: &str) -> String {
|
|
528
528
|
format!(
|
|
529
|
-
"---\nname: {id}\nrole: {id} Worker\nprovider: codex\nmodel: gpt-5.5\nauth_mode: subscription\ntools:\n - mcp_team\n---\n\n{id} worker.\n"
|
|
529
|
+
"---\nname: {id}\nrole: {id} Worker\nprovider: codex\nmodel: gpt-5.5\nauth_mode: subscription\ndangerously_skip_permissions: false\ntools:\n - mcp_team\n---\n\n{id} worker.\n"
|
|
530
530
|
)
|
|
531
531
|
}
|
|
532
532
|
|
|
@@ -387,7 +387,7 @@ fn codex_ready_transport() -> OfflineTransport {
|
|
|
387
387
|
|
|
388
388
|
fn role_doc(id: &str) -> String {
|
|
389
389
|
format!(
|
|
390
|
-
"---\nname: {id}\nrole: {id} Worker\nprovider: codex\nmodel: gpt-5.5\nauth_mode: subscription\ntools:\n - mcp_team\n---\n\n{id} worker.\n"
|
|
390
|
+
"---\nname: {id}\nrole: {id} Worker\nprovider: codex\nmodel: gpt-5.5\nauth_mode: subscription\ndangerously_skip_permissions: false\ntools:\n - mcp_team\n---\n\n{id} worker.\n"
|
|
391
391
|
)
|
|
392
392
|
}
|
|
393
393
|
|
|
@@ -38,9 +38,9 @@ use hermetic::HermeticTestEnv;
|
|
|
38
38
|
const TEAM_MD: &str =
|
|
39
39
|
"---\nname: bug7\nobjective: BUG-7 worker readiness honesty contract.\nprovider: codex\n---\n\nTeam.\n";
|
|
40
40
|
|
|
41
|
-
const CODEX_ROLE: &str = "---\nname: codexer\nrole: Codex Worker\nprovider: codex\nmodel: gpt-5.5\nauth_mode: subscription\ntools:\n - mcp_team\n---\n\nCodex worker.\n";
|
|
41
|
+
const CODEX_ROLE: &str = "---\nname: codexer\nrole: Codex Worker\nprovider: codex\nmodel: gpt-5.5\nauth_mode: subscription\ndangerously_skip_permissions: false\ntools:\n - mcp_team\n---\n\nCodex worker.\n";
|
|
42
42
|
|
|
43
|
-
const CLAUDE_ROLE: &str = "---\nname: clauder\nrole: Claude Worker\nprovider: claude\nmodel: claude-sonnet-4-6\nauth_mode: subscription\ntools:\n - mcp_team\n---\n\nClaude worker.\n";
|
|
43
|
+
const CLAUDE_ROLE: &str = "---\nname: clauder\nrole: Claude Worker\nprovider: claude\nmodel: claude-sonnet-4-6\nauth_mode: subscription\ndangerously_skip_permissions: false\ntools:\n - mcp_team\n---\n\nClaude worker.\n";
|
|
44
44
|
|
|
45
45
|
#[test]
|
|
46
46
|
#[ignore = "real-machine: quick-start worker readiness gate"]
|
|
@@ -218,7 +218,7 @@ fn write_team_docs(team_dir: &Path, workers: &[String], provider: ProviderShape)
|
|
|
218
218
|
fs::write(
|
|
219
219
|
team_dir.join("agents").join(format!("{worker}.md")),
|
|
220
220
|
format!(
|
|
221
|
-
"---\nname: {worker}\nrole: Worker {worker}\nprovider: {}\nmodel: {}\nauth_mode: subscription\ntools:\n - mcp_team\n---\n\n{worker}.\n",
|
|
221
|
+
"---\nname: {worker}\nrole: Worker {worker}\nprovider: {}\nmodel: {}\nauth_mode: subscription\ndangerously_skip_permissions: false\ntools:\n - mcp_team\n---\n\n{worker}.\n",
|
|
222
222
|
provider.provider(),
|
|
223
223
|
provider.model()
|
|
224
224
|
),
|
|
@@ -492,7 +492,7 @@ impl RestartFixture {
|
|
|
492
492
|
std::fs::write(
|
|
493
493
|
team.join("agents").join(format!("{agent}.md")),
|
|
494
494
|
format!(
|
|
495
|
-
"---\nname: {agent}\nrole: Worker {agent}\nprovider: codex\nmodel: gpt-5.5\nauth_mode: subscription\ntools:\n - mcp_team\n---\n\nWorker.\n"
|
|
495
|
+
"---\nname: {agent}\nrole: Worker {agent}\nprovider: codex\nmodel: gpt-5.5\nauth_mode: subscription\ndangerously_skip_permissions: false\ntools:\n - mcp_team\n---\n\nWorker.\n"
|
|
496
496
|
),
|
|
497
497
|
)
|
|
498
498
|
.unwrap();
|
|
@@ -342,7 +342,7 @@ impl HotfixCase {
|
|
|
342
342
|
std::fs::write(
|
|
343
343
|
dir.join("agents").join(format!("{agent_id}.md")),
|
|
344
344
|
format!(
|
|
345
|
-
"---\nname: {agent_id}\nrole: Greeter\nprovider: {}\nmodel: test\nauth_mode: subscription\ntools:\n - mcp_team\n---\n\nWorker.\n",
|
|
345
|
+
"---\nname: {agent_id}\nrole: Greeter\nprovider: {}\nmodel: test\nauth_mode: subscription\ndangerously_skip_permissions: false\ntools:\n - mcp_team\n---\n\nWorker.\n",
|
|
346
346
|
provider_name(provider)
|
|
347
347
|
),
|
|
348
348
|
)
|
|
@@ -1371,7 +1371,7 @@ impl RestartFixture {
|
|
|
1371
1371
|
std::fs::write(
|
|
1372
1372
|
team.join("agents/worker_a.md"),
|
|
1373
1373
|
format!(
|
|
1374
|
-
"---\nname: worker_a\nrole: Worker\nprovider: {provider}\nmodel: {}\nauth_mode: subscription\ntools:\n - mcp_team\n---\n\nWorker.\n",
|
|
1374
|
+
"---\nname: worker_a\nrole: Worker\nprovider: {provider}\nmodel: {}\nauth_mode: subscription\ndangerously_skip_permissions: false\ntools:\n - mcp_team\n---\n\nWorker.\n",
|
|
1375
1375
|
if provider == "claude" {
|
|
1376
1376
|
"claude-sonnet-4-6"
|
|
1377
1377
|
} else {
|
|
@@ -1409,7 +1409,7 @@ impl RestartFixture {
|
|
|
1409
1409
|
std::fs::write(
|
|
1410
1410
|
team.join("agents/worker_a.md"),
|
|
1411
1411
|
format!(
|
|
1412
|
-
"---\nname: worker_a\nrole: Worker\nprovider: {provider}\nmodel: {}\nauth_mode: subscription\ntools:\n - mcp_team\n---\n\nWorker.\n",
|
|
1412
|
+
"---\nname: worker_a\nrole: Worker\nprovider: {provider}\nmodel: {}\nauth_mode: subscription\ndangerously_skip_permissions: false\ntools:\n - mcp_team\n---\n\nWorker.\n",
|
|
1413
1413
|
if provider == "claude" {
|
|
1414
1414
|
"claude-sonnet-4-6"
|
|
1415
1415
|
} else {
|
|
@@ -151,7 +151,7 @@ impl ResumeFixture {
|
|
|
151
151
|
.unwrap();
|
|
152
152
|
std::fs::write(
|
|
153
153
|
team.join("agents").join("worker_a.md"),
|
|
154
|
-
"---\nname: worker_a\nrole: Worker A\nprovider: codex\nmodel: gpt-5.5\nauth_mode: subscription\ntools:\n - mcp_team\n---\n\nWorker.\n",
|
|
154
|
+
"---\nname: worker_a\nrole: Worker A\nprovider: codex\nmodel: gpt-5.5\nauth_mode: subscription\ndangerously_skip_permissions: false\ntools:\n - mcp_team\n---\n\nWorker.\n",
|
|
155
155
|
)
|
|
156
156
|
.unwrap();
|
|
157
157
|
let spec = team_agent::compiler::compile_team(&team).unwrap();
|
|
@@ -291,7 +291,7 @@ fn agent(id: &str, status: &str, topology: bool) -> Value {
|
|
|
291
291
|
}
|
|
292
292
|
|
|
293
293
|
fn role_doc(id: &str) -> String {
|
|
294
|
-
format!("---\nname: {id}\nrole: {id}\nprovider: fake\nmodel: fake\nauth_mode: subscription\ntools:\n - mcp_team\n---\n\n{id}.\n")
|
|
294
|
+
format!("---\nname: {id}\nrole: {id}\nprovider: fake\nmodel: fake\nauth_mode: subscription\ndangerously_skip_permissions: false\ntools:\n - mcp_team\n---\n\n{id}.\n")
|
|
295
295
|
}
|
|
296
296
|
|
|
297
297
|
fn assert_no_standards(case: &Case) {
|
|
@@ -167,13 +167,17 @@ fn restart_failure_aggregation_matches_serial_semantics_without_early_abort() {
|
|
|
167
167
|
["w1", "w2", "w4", "w5", "w6", "w7", "w8"],
|
|
168
168
|
"R2: successful workers after w3 must still be spawned and reported"
|
|
169
169
|
);
|
|
170
|
+
let mut observed_spawn_windows = transport
|
|
171
|
+
.spawn_calls()
|
|
172
|
+
.into_iter()
|
|
173
|
+
.map(|call| call.window)
|
|
174
|
+
.collect::<Vec<_>>();
|
|
175
|
+
let mut expected_spawn_windows = worker_ids(8);
|
|
176
|
+
observed_spawn_windows.sort();
|
|
177
|
+
expected_spawn_windows.sort();
|
|
170
178
|
assert_eq!(
|
|
171
|
-
|
|
172
|
-
|
|
173
|
-
.iter()
|
|
174
|
-
.map(|call| call.window.as_str())
|
|
175
|
-
.collect::<Vec<_>>(),
|
|
176
|
-
worker_ids(8),
|
|
179
|
+
observed_spawn_windows,
|
|
180
|
+
expected_spawn_windows,
|
|
177
181
|
"R2: failure aggregation must attempt the full plan; no early return after w3"
|
|
178
182
|
);
|
|
179
183
|
|
|
@@ -484,7 +488,7 @@ fn write_team_docs(team_dir: &Path, workers: usize) {
|
|
|
484
488
|
|
|
485
489
|
fn role_doc(worker: &str) -> String {
|
|
486
490
|
format!(
|
|
487
|
-
"---\nname: {worker}\nrole: Worker {worker}\nprovider: fake\nmodel: fake\nauth_mode: subscription\ntools:\n - mcp_team\n---\n\n{worker}.\n"
|
|
491
|
+
"---\nname: {worker}\nrole: Worker {worker}\nprovider: fake\nmodel: fake\nauth_mode: subscription\ndangerously_skip_permissions: false\ntools:\n - mcp_team\n---\n\n{worker}.\n"
|
|
488
492
|
)
|
|
489
493
|
}
|
|
490
494
|
|
|
@@ -368,7 +368,7 @@ fn red6_cli_restart_reports_and_top_level_error_logs_are_redacted() {
|
|
|
368
368
|
}
|
|
369
369
|
|
|
370
370
|
#[test]
|
|
371
|
-
#[serial(env)]
|
|
371
|
+
#[serial(env, pid_probe)]
|
|
372
372
|
fn red7_pane_and_profile_scrubbers_converge_without_losing_existing_policy() {
|
|
373
373
|
let root = Path::new(env!("CARGO_MANIFEST_DIR"));
|
|
374
374
|
let tmux = fs::read_to_string(root.join("src/tmux_backend.rs")).unwrap();
|
|
@@ -685,12 +685,12 @@ fn write_profile_fixture(root: &Path, base_url: &str, token: &str) -> PathBuf {
|
|
|
685
685
|
.unwrap();
|
|
686
686
|
fs::write(
|
|
687
687
|
team.join("TEAM.md"),
|
|
688
|
-
"---\nname: redact-profile\nobjective: Synthetic redaction profile contract.\nprovider: claude\nauth_mode: compatible_api\n---\n\nTeam.\n",
|
|
688
|
+
"---\nname: redact-profile\nobjective: Synthetic redaction profile contract.\nprovider: claude\nauth_mode: compatible_api\ndangerously_skip_permissions: false\n---\n\nTeam.\n",
|
|
689
689
|
)
|
|
690
690
|
.unwrap();
|
|
691
691
|
fs::write(
|
|
692
692
|
team.join("agents/worker.md"),
|
|
693
|
-
"---\nname: worker\nrole: Worker\nprovider: claude\nauth_mode: compatible_api\nprofile: local\nmodel: null\ntools:\n - mcp_team\n---\n\nWorker.\n",
|
|
693
|
+
"---\nname: worker\nrole: Worker\nprovider: claude\nauth_mode: compatible_api\ndangerously_skip_permissions: false\nprofile: local\nmodel: null\ntools:\n - mcp_team\n---\n\nWorker.\n",
|
|
694
694
|
)
|
|
695
695
|
.unwrap();
|
|
696
696
|
team
|
|
@@ -861,7 +861,7 @@ fn contract_c_lifecycle_launch_command_carries_role_tools_and_real_mcp_context()
|
|
|
861
861
|
.unwrap();
|
|
862
862
|
std::fs::write(
|
|
863
863
|
teamdir.join("agents").join("w1.md"),
|
|
864
|
-
"---\nname: w1\nrole: Worker must call report_result exactly once.\nprovider: codex\nmodel: gpt-5.5\nauth_mode: subscription\ntools:\n - mcp_team\n---\n\nAlways use report_result for completion.\n",
|
|
864
|
+
"---\nname: w1\nrole: Worker must call report_result exactly once.\nprovider: codex\nmodel: gpt-5.5\nauth_mode: subscription\ndangerously_skip_permissions: false\ntools:\n - mcp_team\n---\n\nAlways use report_result for completion.\n",
|
|
865
865
|
)
|
|
866
866
|
.unwrap();
|
|
867
867
|
let spec = team_agent::compiler::compile_team(&teamdir).unwrap();
|
|
@@ -172,7 +172,7 @@ fn write_claude_compatible_team(ws: &Path) -> PathBuf {
|
|
|
172
172
|
.unwrap();
|
|
173
173
|
std::fs::write(
|
|
174
174
|
team.join("agents/worker_a.md"),
|
|
175
|
-
"---\nname: worker_a\nrole: Compat Worker\nprovider: claude\nmodel: claude-haiku\nauth_mode: compatible_api\nprofile: relay\ntools:\n - mcp_team\n---\n\nCompat worker.\n",
|
|
175
|
+
"---\nname: worker_a\nrole: Compat Worker\nprovider: claude\nmodel: claude-haiku\nauth_mode: compatible_api\ndangerously_skip_permissions: false\nprofile: relay\ntools:\n - mcp_team\n---\n\nCompat worker.\n",
|
|
176
176
|
)
|
|
177
177
|
.unwrap();
|
|
178
178
|
std::fs::write(
|
|
@@ -244,7 +244,7 @@ fn write_team_dir(root: &Path, dir_name: &str, agent: &str) -> PathBuf {
|
|
|
244
244
|
|
|
245
245
|
fn role_doc(agent: &str) -> String {
|
|
246
246
|
format!(
|
|
247
|
-
"---\nname: {agent}\nrole: Worker\nprovider: codex\nmodel: gpt-5.5\nauth_mode: subscription\ntools:\n - mcp_team\n---\n\nWorker.\n"
|
|
247
|
+
"---\nname: {agent}\nrole: Worker\nprovider: codex\nmodel: gpt-5.5\nauth_mode: subscription\ndangerously_skip_permissions: false\ntools:\n - mcp_team\n---\n\nWorker.\n"
|
|
248
248
|
)
|
|
249
249
|
}
|
|
250
250
|
|
|
@@ -881,7 +881,7 @@ fn team_dir_with_name(root: &Path, dir_name: &str, spec_name: &str, agent_id: &s
|
|
|
881
881
|
|
|
882
882
|
fn role_doc(name: &str) -> String {
|
|
883
883
|
format!(
|
|
884
|
-
"---\nname: {name}\nrole: Worker\nprovider: codex\nmodel: gpt-5.5\nauth_mode: subscription\ntools:\n - mcp_team\n---\n\nWorker.\n"
|
|
884
|
+
"---\nname: {name}\nrole: Worker\nprovider: codex\nmodel: gpt-5.5\nauth_mode: subscription\ndangerously_skip_permissions: false\ntools:\n - mcp_team\n---\n\nWorker.\n"
|
|
885
885
|
)
|
|
886
886
|
}
|
|
887
887
|
|
|
@@ -1057,7 +1057,7 @@ fn team_dir(root: &Path, name: &str, agents: &[(&str, &str)]) -> PathBuf {
|
|
|
1057
1057
|
|
|
1058
1058
|
fn role_doc(name: &str, role: &str) -> String {
|
|
1059
1059
|
format!(
|
|
1060
|
-
"---\nname: {name}\nrole: {role}\nprovider: codex\nmodel: gpt-5.5\nauth_mode: subscription\ntools:\n - mcp_team\n---\n\n{role}.\n"
|
|
1060
|
+
"---\nname: {name}\nrole: {role}\nprovider: codex\nmodel: gpt-5.5\nauth_mode: subscription\ndangerously_skip_permissions: false\ntools:\n - mcp_team\n---\n\n{role}.\n"
|
|
1061
1061
|
)
|
|
1062
1062
|
}
|
|
1063
1063
|
|
|
@@ -390,7 +390,7 @@ impl RollbackFixture {
|
|
|
390
390
|
|
|
391
391
|
fn agent_doc(name: &str, role: &str) -> String {
|
|
392
392
|
format!(
|
|
393
|
-
"---\nname: {name}\nrole: {role}\nprovider: codex\nauth_mode: subscription\ntools:\n - mcp_team\n---\n\n{role}.\n"
|
|
393
|
+
"---\nname: {name}\nrole: {role}\nprovider: codex\nauth_mode: subscription\ndangerously_skip_permissions: false\ntools:\n - mcp_team\n---\n\n{role}.\n"
|
|
394
394
|
)
|
|
395
395
|
}
|
|
396
396
|
|
|
@@ -393,7 +393,7 @@ impl RestartAutoAttachCase {
|
|
|
393
393
|
std::fs::write(
|
|
394
394
|
workspace.join("agents").join(format!("{WORKER}.md")),
|
|
395
395
|
format!(
|
|
396
|
-
"---\nname: {WORKER}\nrole: Worker {WORKER}\nprovider: fake\nmodel: fake\nauth_mode: subscription\ntools:\n - mcp_team\n---\n\nWorker.\n"
|
|
396
|
+
"---\nname: {WORKER}\nrole: Worker {WORKER}\nprovider: fake\nmodel: fake\nauth_mode: subscription\ndangerously_skip_permissions: false\ntools:\n - mcp_team\n---\n\nWorker.\n"
|
|
397
397
|
),
|
|
398
398
|
)
|
|
399
399
|
.expect("write worker role");
|
|
@@ -456,7 +456,7 @@ impl UpgradeFixture {
|
|
|
456
456
|
std::fs::create_dir_all(self.team_dir.join("agents")).unwrap();
|
|
457
457
|
std::fs::write(
|
|
458
458
|
self.team_dir.join("agents").join("upgrade_worker.md"),
|
|
459
|
-
"---\nname: upgrade_worker\nrole: Upgrade Worker\nprovider: codex\nmodel: gpt-5.5\nauth_mode: subscription\ntools:\n - mcp_team\n---\n\nWorker.\n",
|
|
459
|
+
"---\nname: upgrade_worker\nrole: Upgrade Worker\nprovider: codex\nmodel: gpt-5.5\nauth_mode: subscription\ndangerously_skip_permissions: false\ntools:\n - mcp_team\n---\n\nWorker.\n",
|
|
460
460
|
)
|
|
461
461
|
.unwrap();
|
|
462
462
|
let spec = team_agent::compiler::compile_team(&self.team_dir).unwrap();
|
|
@@ -39,9 +39,9 @@ use hermetic::HermeticTestEnv;
|
|
|
39
39
|
const TEAM_MD: &str =
|
|
40
40
|
"---\nname: verify031\nobjective: Verify mixed provider windows.\nprovider: codex\n---\n\nTeam.\n";
|
|
41
41
|
|
|
42
|
-
const CODEX_ROLE: &str = "---\nname: codexer\nrole: Codex Worker\nprovider: codex\nmodel: gpt-5.5\nauth_mode: subscription\ntools:\n - mcp_team\n---\n\nCodex worker.\n";
|
|
42
|
+
const CODEX_ROLE: &str = "---\nname: codexer\nrole: Codex Worker\nprovider: codex\nmodel: gpt-5.5\nauth_mode: subscription\ndangerously_skip_permissions: false\ntools:\n - mcp_team\n---\n\nCodex worker.\n";
|
|
43
43
|
|
|
44
|
-
const CLAUDE_ROLE: &str = "---\nname: clauder\nrole: Claude Worker\nprovider: claude\nmodel: claude-sonnet-4-6\nauth_mode: subscription\ntools:\n - mcp_team\n---\n\nClaude worker.\n";
|
|
44
|
+
const CLAUDE_ROLE: &str = "---\nname: clauder\nrole: Claude Worker\nprovider: claude\nmodel: claude-sonnet-4-6\nauth_mode: subscription\ndangerously_skip_permissions: false\ntools:\n - mcp_team\n---\n\nClaude worker.\n";
|
|
45
45
|
|
|
46
46
|
#[test]
|
|
47
47
|
#[serial(env)]
|
|
@@ -329,7 +329,7 @@ fn compiled_team_dir(label: &str, agents: &[(&str, &str)]) -> PathBuf {
|
|
|
329
329
|
|
|
330
330
|
fn role_doc(name: &str, role: &str) -> String {
|
|
331
331
|
format!(
|
|
332
|
-
"---\nname: {name}\nrole: {role}\nprovider: codex\nmodel: codex-test-model\nauth_mode: subscription\ntools:\n - mcp_team\n---\n\n{role}.\n"
|
|
332
|
+
"---\nname: {name}\nrole: {role}\nprovider: codex\nmodel: codex-test-model\nauth_mode: subscription\ndangerously_skip_permissions: false\ntools:\n - mcp_team\n---\n\n{role}.\n"
|
|
333
333
|
)
|
|
334
334
|
}
|
|
335
335
|
|