@team-agent/installer 0.5.113 → 0.5.114

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.
Files changed (46) hide show
  1. package/Cargo.lock +252 -84
  2. package/Cargo.toml +3 -1
  3. package/crates/team-agent/Cargo.toml +3 -0
  4. package/crates/team-agent/src/cli/adapters.rs +28 -15
  5. package/crates/team-agent/src/cli/diagnose.rs +36 -13
  6. package/crates/team-agent/src/cli/emit.rs +55 -20
  7. package/crates/team-agent/src/cli/leader.rs +16 -0
  8. package/crates/team-agent/src/cli/leader_prompt.rs +261 -0
  9. package/crates/team-agent/src/cli/mod.rs +152 -8
  10. package/crates/team-agent/src/cli/models.rs +68 -18
  11. package/crates/team-agent/src/cli/spec.rs +7 -1
  12. package/crates/team-agent/src/cli/status_port/brief.rs +268 -101
  13. package/crates/team-agent/src/cli/tests/base.rs +88 -0
  14. package/crates/team-agent/src/cli/tests/status_send.rs +2 -0
  15. package/crates/team-agent/src/compiler.rs +66 -18
  16. package/crates/team-agent/src/contract_runtime/backend.rs +646 -0
  17. package/crates/team-agent/src/contract_runtime/config.rs +309 -0
  18. package/crates/team-agent/src/contract_runtime/discovery.rs +237 -0
  19. package/crates/team-agent/src/contract_runtime/forward.rs +229 -0
  20. package/crates/team-agent/src/contract_runtime/framework.rs +261 -0
  21. package/crates/team-agent/src/contract_runtime/mcp.rs +396 -0
  22. package/crates/team-agent/src/contract_runtime/mod.rs +14 -0
  23. package/crates/team-agent/src/contract_runtime/prompt.rs +216 -0
  24. package/crates/team-agent/src/contract_runtime/pump.rs +207 -0
  25. package/crates/team-agent/src/contract_runtime/registry.rs +30 -0
  26. package/crates/team-agent/src/coordinator/tick.rs +26 -8
  27. package/crates/team-agent/src/leader/mod.rs +1 -0
  28. package/crates/team-agent/src/leader/prompt.rs +906 -0
  29. package/crates/team-agent/src/leader/start.rs +260 -16
  30. package/crates/team-agent/src/leader/tests/mod.rs +2 -0
  31. package/crates/team-agent/src/leader/tests/prompt_contract.rs +268 -0
  32. package/crates/team-agent/src/leader/types.rs +6 -0
  33. package/crates/team-agent/src/lib.rs +4 -0
  34. package/crates/team-agent/src/lifecycle/launch/quick_start.rs +472 -388
  35. package/crates/team-agent/src/lifecycle/launch/spawn.rs +38 -9
  36. package/crates/team-agent/src/lifecycle/launch/state_projection.rs +17 -0
  37. package/crates/team-agent/src/lifecycle/launch.rs +39 -28
  38. package/crates/team-agent/src/lifecycle/types.rs +4 -1
  39. package/crates/team-agent/src/lifecycle/worker_command_context.rs +37 -27
  40. package/crates/team-agent/src/main.rs +6 -0
  41. package/crates/team-agent/src/messaging/delivery.rs +50 -1
  42. package/crates/team-agent/src/messaging/send.rs +10 -0
  43. package/crates/team-agent/src/messaging/tests/leader_inject_acceptance.rs +131 -0
  44. package/crates/team-agent/src/model/spec.rs +24 -12
  45. package/crates/team-agent/src/state/persist.rs +73 -0
  46. package/package.json +4 -4
@@ -192,7 +192,9 @@ impl FreshQuickStartLeaderBindingOps for RuntimeFreshQuickStartLeaderBindingOps<
192
192
  let (error, applied_grant) = error.into_parts();
193
193
  self.applied_grant = applied_grant.map(|grant| (grant.owner, grant.receiver));
194
194
  self.cas_conflict = match &error {
195
- crate::leader::LeaderError::State(crate::state::StateError::SaveConflict(_)) => true,
195
+ crate::leader::LeaderError::State(crate::state::StateError::SaveConflict(
196
+ _,
197
+ )) => true,
196
198
  _ => false,
197
199
  };
198
200
  self.last_failure_reason = Some(if self.cas_conflict {
@@ -206,7 +208,8 @@ impl FreshQuickStartLeaderBindingOps for RuntimeFreshQuickStartLeaderBindingOps<
206
208
  crate::leader::LeaderError::Io(_)
207
209
  | crate::leader::LeaderError::Json(_)
208
210
  | crate::leader::LeaderError::MessageStore(_)
209
- | crate::leader::LeaderError::Start(_) => "attach_failed",
211
+ | crate::leader::LeaderError::Start(_)
212
+ | crate::leader::LeaderError::Prompt(_) => "attach_failed",
210
213
  crate::leader::LeaderError::EventLog(_) => "attach_event_log_failed",
211
214
  crate::leader::LeaderError::Messaging(_) => "attach_watcher_failed",
212
215
  }
@@ -273,16 +276,13 @@ impl FreshQuickStartLeaderBindingOps for RuntimeFreshQuickStartLeaderBindingOps<
273
276
  });
274
277
  return false;
275
278
  }
276
- let Ok(resolved) = crate::state::projection::resolve_runtime_team_scope(
277
- workspace,
278
- Some(team_key),
279
- ) else {
279
+ let Ok(resolved) =
280
+ crate::state::projection::resolve_runtime_team_scope(workspace, Some(team_key))
281
+ else {
280
282
  self.last_failure_reason = Some("receiver_scope_unavailable");
281
283
  return false;
282
284
  };
283
- let Some(receiver) =
284
- super::selected_team_leader_receiver(&resolved.state, team_key)
285
- else {
285
+ let Some(receiver) = super::selected_team_leader_receiver(&resolved.state, team_key) else {
286
286
  self.last_failure_reason = Some("receiver_missing");
287
287
  return false;
288
288
  };
@@ -291,9 +291,8 @@ impl FreshQuickStartLeaderBindingOps for RuntimeFreshQuickStartLeaderBindingOps<
291
291
  .and_then(serde_json::Value::as_str)
292
292
  .filter(|endpoint| !endpoint.is_empty())
293
293
  .map(crate::transport_factory::leader_endpoint_transport);
294
- let live_channel_transport: &dyn Transport = leader_transport
295
- .as_deref()
296
- .unwrap_or(self.transport);
294
+ let live_channel_transport: &dyn Transport =
295
+ leader_transport.as_deref().unwrap_or(self.transport);
297
296
  if !matches!(
298
297
  crate::messaging::resolve_live_leader_channel(
299
298
  workspace,
@@ -314,9 +313,7 @@ impl FreshQuickStartLeaderBindingOps for RuntimeFreshQuickStartLeaderBindingOps<
314
313
  }
315
314
 
316
315
  fn frozen_seed_receipt(&self) -> Option<(serde_json::Value, serde_json::Value)> {
317
- self.frozen_owner
318
- .clone()
319
- .zip(self.frozen_receiver.clone())
316
+ self.frozen_owner.clone().zip(self.frozen_receiver.clone())
320
317
  }
321
318
  }
322
319
 
@@ -376,7 +373,6 @@ impl BindingFileSnapshot {
376
373
  let bytes = std::fs::read(&path).ok();
377
374
  Self { path, bytes }
378
375
  }
379
-
380
376
  }
381
377
 
382
378
  fn binding_snapshots(workspace: &Path, team_key: &str) -> Vec<BindingFileSnapshot> {
@@ -434,7 +430,10 @@ fn persisted_binding_matches_verified_pane(
434
430
  {
435
431
  return false;
436
432
  }
437
- let Some(owner) = state.get("team_owner").and_then(serde_json::Value::as_object) else {
433
+ let Some(owner) = state
434
+ .get("team_owner")
435
+ .and_then(serde_json::Value::as_object)
436
+ else {
438
437
  return false;
439
438
  };
440
439
  let Some(receiver) = state
@@ -488,10 +487,9 @@ fn bind_fresh_quick_start_leader_with<O: FreshQuickStartLeaderBindingOps>(
488
487
  seeded_owner: Option<&serde_json::Value>,
489
488
  ops: &mut O,
490
489
  ) -> Result<bool, LifecycleError> {
491
- let Ok(resolved) = crate::state::projection::resolve_runtime_team_scope(
492
- workspace,
493
- Some(team_key),
494
- ) else {
490
+ let Ok(resolved) =
491
+ crate::state::projection::resolve_runtime_team_scope(workspace, Some(team_key))
492
+ else {
495
493
  return refuse_fresh_bind(workspace, team_key, "scope", "scope_unresolved");
496
494
  };
497
495
  if resolved.canonical_team_key != team_key {
@@ -550,27 +548,27 @@ fn bind_fresh_quick_start_leader_with<O: FreshQuickStartLeaderBindingOps>(
550
548
  // projected state still contains that seed.
551
549
  let current_receiver = state.get("leader_receiver");
552
550
  let frozen_receipt = ops.frozen_seed_receipt();
553
- let fresh_seeded_binding = if let Some((frozen_owner, frozen_receiver)) = frozen_receipt.as_ref()
554
- {
555
- state
556
- .get("team_owner")
557
- .is_some_and(|current| current == frozen_owner)
558
- && current_receiver.is_some_and(|current| current == frozen_receiver)
559
- } else {
560
- let pending_seed_receiver = current_receiver.is_some_and(|receiver| {
561
- receiver.get("status").and_then(serde_json::Value::as_str) == Some("pending")
562
- && receiver
563
- .get("discovery")
564
- .and_then(serde_json::Value::as_str)
565
- == Some("quick_start_seed")
566
- });
567
- seeded_owner.is_some_and(|seed| {
551
+ let fresh_seeded_binding =
552
+ if let Some((frozen_owner, frozen_receiver)) = frozen_receipt.as_ref() {
568
553
  state
569
554
  .get("team_owner")
570
- .is_some_and(|current| current == seed)
571
- && pending_seed_receiver
572
- })
573
- };
555
+ .is_some_and(|current| current == frozen_owner)
556
+ && current_receiver.is_some_and(|current| current == frozen_receiver)
557
+ } else {
558
+ let pending_seed_receiver = current_receiver.is_some_and(|receiver| {
559
+ receiver.get("status").and_then(serde_json::Value::as_str) == Some("pending")
560
+ && receiver
561
+ .get("discovery")
562
+ .and_then(serde_json::Value::as_str)
563
+ == Some("quick_start_seed")
564
+ });
565
+ seeded_owner.is_some_and(|seed| {
566
+ state
567
+ .get("team_owner")
568
+ .is_some_and(|current| current == seed)
569
+ && pending_seed_receiver
570
+ })
571
+ };
574
572
  let seeded_receiver = frozen_receipt
575
573
  .as_ref()
576
574
  .map(|(_, receiver)| receiver.clone())
@@ -721,9 +719,9 @@ fn combine_rollback_errors(
721
719
  match (state, registry) {
722
720
  (None, None) => None,
723
721
  (Some(error), None) | (None, Some(error)) => Some(error),
724
- (Some(state), Some(registry)) => Some(LifecycleError::StatePersist(format!(
725
- "{state}; {registry}"
726
- ))),
722
+ (Some(state), Some(registry)) => {
723
+ Some(LifecycleError::StatePersist(format!("{state}; {registry}")))
724
+ }
727
725
  }
728
726
  }
729
727
 
@@ -757,9 +755,11 @@ fn restore_this_attempt_state(
757
755
  });
758
756
  };
759
757
  let previous = match snapshot.map(|snapshot| snapshot.bytes.as_deref()) {
760
- Some(Some(bytes)) => serde_json::from_slice::<serde_json::Value>(bytes).map_err(|error| {
761
- LifecycleError::StatePersist(format!("quick-start binding cleanup failed: {error}"))
762
- })?,
758
+ Some(Some(bytes)) => {
759
+ serde_json::from_slice::<serde_json::Value>(bytes).map_err(|error| {
760
+ LifecycleError::StatePersist(format!("quick-start binding cleanup failed: {error}"))
761
+ })?
762
+ }
763
763
  Some(None) | None => serde_json::Value::Null,
764
764
  };
765
765
  let previous_owner = previous
@@ -879,9 +879,9 @@ fn clear_fresh_binding_on_refusal(
879
879
  };
880
880
  crate::state::repository::StateRepository::new(workspace)
881
881
  .save(intent, state)
882
- .map_err(|error| LifecycleError::StatePersist(format!(
883
- "quick-start binding cleanup failed: {error}"
884
- )))
882
+ .map_err(|error| {
883
+ LifecycleError::StatePersist(format!("quick-start binding cleanup failed: {error}"))
884
+ })
885
885
  }
886
886
 
887
887
  fn existing_runtime_identity_view(
@@ -907,16 +907,14 @@ fn caller_read_transport() -> Option<Box<dyn Transport>> {
907
907
  if !Path::new(&endpoint).exists() {
908
908
  return None;
909
909
  }
910
- Some(Box::new(crate::tmux_backend::TmuxBackend::for_tmux_endpoint(
911
- &endpoint,
912
- )))
910
+ Some(Box::new(
911
+ crate::tmux_backend::TmuxBackend::for_tmux_endpoint(&endpoint),
912
+ ))
913
913
  }
914
914
 
915
915
  fn query_caller_pane_command(transport: &dyn Transport, pane: &PaneId) -> Option<String> {
916
916
  let caller_transport = caller_read_transport();
917
- let query_transport: &dyn Transport = caller_transport
918
- .as_deref()
919
- .unwrap_or(transport);
917
+ let query_transport: &dyn Transport = caller_transport.as_deref().unwrap_or(transport);
920
918
  query_transport
921
919
  .query(&Target::Pane(pane.clone()), PaneField::PaneCurrentCommand)
922
920
  .ok()
@@ -959,8 +957,8 @@ fn preflight_fresh_leader_identity(
959
957
  let Some(pane) = pane else {
960
958
  return None;
961
959
  };
962
- let command = query_caller_pane_command(transport, &PaneId::new(pane))
963
- .unwrap_or_default();
960
+ let command =
961
+ query_caller_pane_command(transport, &PaneId::new(pane)).unwrap_or_default();
964
962
  let explicit = std::env::var("TEAM_AGENT_LEADER_PROVIDER")
965
963
  .ok()
966
964
  .filter(|provider| !provider.is_empty());
@@ -968,16 +966,11 @@ fn preflight_fresh_leader_identity(
968
966
  return Some((
969
967
  "quick-start refused before spawn: command unobservable".to_string(),
970
968
  vec!["stage=command_observation reason=command_unobservable".to_string()],
971
- vec![
972
- "run from a live provider pane; do not run claim-leader".to_string(),
973
- ],
969
+ vec!["run from a live provider pane; do not run claim-leader".to_string()],
974
970
  ));
975
971
  }
976
- if crate::leader::owner_bind::strict_owner_bind_provider(
977
- explicit.as_deref(),
978
- &command,
979
- )
980
- .is_some()
972
+ if crate::leader::owner_bind::strict_owner_bind_provider(explicit.as_deref(), &command)
973
+ .is_some()
981
974
  {
982
975
  None
983
976
  } else {
@@ -1097,12 +1090,7 @@ pub fn quick_start_in_workspace_with_backend(
1097
1090
  if is_tmux_or_default {
1098
1091
  let transport = quick_start_tmux_backend(&workspace);
1099
1092
  return quick_start_with_transport_in_workspace(
1100
- &workspace,
1101
- agents_dir,
1102
- name,
1103
- yes,
1104
- team_id,
1105
- &transport,
1093
+ &workspace, agents_dir, name, yes, team_id, &transport,
1106
1094
  );
1107
1095
  }
1108
1096
  // Explicit non-tmux backend: route through the factory. Parse the
@@ -1275,6 +1263,32 @@ pub(crate) fn quick_start_with_transport_in_workspace_pi_preflight(
1275
1263
  )));
1276
1264
  }
1277
1265
  crate::lifecycle::launch::run_pi_catalog_preflight(agents_dir, discover)?;
1266
+ #[cfg(unix)]
1267
+ {
1268
+ let input = crate::cli::QuickStartArgs {
1269
+ workspace: workspace.into(),
1270
+ agents_dir: agents_dir.into(),
1271
+ name: name.map(str::to_owned),
1272
+ team_id: team_id.map(str::to_owned),
1273
+ yes: false,
1274
+ json: false,
1275
+ detail: false,
1276
+ backend: Some(
1277
+ if matches!(transport.kind(), crate::transport::BackendKind::Tmux) {
1278
+ "tmux"
1279
+ } else {
1280
+ "conpty"
1281
+ }
1282
+ .into(),
1283
+ ),
1284
+ };
1285
+ if let Some(config) = crate::contract_runtime::config::read_team(&input)
1286
+ .map_err(|error| LifecycleError::Compile(error.to_string()))?
1287
+ {
1288
+ crate::contract_runtime::backend::preflight(&config)
1289
+ .map_err(|error| LifecycleError::Provider(error.to_string()))?;
1290
+ }
1291
+ }
1278
1292
  let workspace = workspace.to_path_buf();
1279
1293
  let mut spec = crate::compiler::compile_team(agents_dir)
1280
1294
  .map_err(|e| LifecycleError::Compile(e.to_string()))?;
@@ -1328,7 +1342,9 @@ pub(crate) fn quick_start_with_transport_in_workspace_pi_preflight(
1328
1342
  .get("tmux_endpoint")
1329
1343
  .and_then(serde_json::Value::as_str)
1330
1344
  .or_else(|| {
1331
- identity.get("tmux_socket").and_then(serde_json::Value::as_str)
1345
+ identity
1346
+ .get("tmux_socket")
1347
+ .and_then(serde_json::Value::as_str)
1332
1348
  })
1333
1349
  .or_else(|| {
1334
1350
  state
@@ -1450,10 +1466,7 @@ pub(crate) fn quick_start_with_transport_in_workspace_pi_preflight(
1450
1466
  .and_then(|teams| teams.get(&state_team_key))
1451
1467
  .and_then(|team| team.get("team_owner"))
1452
1468
  .filter(|owner| {
1453
- owner
1454
- .get("claimed_via")
1455
- .and_then(serde_json::Value::as_str)
1456
- == Some("quick-start")
1469
+ owner.get("claimed_via").and_then(serde_json::Value::as_str) == Some("quick-start")
1457
1470
  })
1458
1471
  .cloned();
1459
1472
  let seeded_receiver = state
@@ -1517,12 +1530,18 @@ pub(crate) fn quick_start_with_transport_in_workspace_pi_preflight(
1517
1530
  quick_start_session_capture_incomplete_agents(&workspace, &state_team_key);
1518
1531
  let coordinator_workspace = crate::coordinator::WorkspacePath::new(workspace.clone());
1519
1532
  let coordinator_report = crate::coordinator::start_coordinator(&coordinator_workspace)
1520
- .map_err(|error| LifecycleError::StatePersist(format!(
1521
- "coordinator start failed for {}: {error}; inspect {} before retrying",
1522
- workspace.display(),
1523
- crate::coordinator::coordinator_log_path(&coordinator_workspace).display()
1524
- )))?;
1525
- quick_start_phase_timer.emit(&workspace, "launch.phase", crate::lifecycle::restart::LifecyclePhase::CoordinatorStart);
1533
+ .map_err(|error| {
1534
+ LifecycleError::StatePersist(format!(
1535
+ "coordinator start failed for {}: {error}; inspect {} before retrying",
1536
+ workspace.display(),
1537
+ crate::coordinator::coordinator_log_path(&coordinator_workspace).display()
1538
+ ))
1539
+ })?;
1540
+ quick_start_phase_timer.emit(
1541
+ &workspace,
1542
+ "launch.phase",
1543
+ crate::lifecycle::restart::LifecyclePhase::CoordinatorStart,
1544
+ );
1526
1545
  require_quick_start_coordinator_started(&coordinator_report, &workspace)?;
1527
1546
  let coordinator_action = "coordinator started";
1528
1547
  // BUG-7: build an honest readiness verdict from the post-spawn runtime state.
@@ -1532,7 +1551,11 @@ pub(crate) fn quick_start_with_transport_in_workspace_pi_preflight(
1532
1551
  // loaded successfully (provider-side codex/claude schema rejections happen
1533
1552
  // asynchronously after spawn), so the verdict is PendingToolLoad — never
1534
1553
  // bare Ready.
1535
- quick_start_phase_timer.emit(&workspace, "launch.phase", crate::lifecycle::restart::LifecyclePhase::ReadinessWait);
1554
+ quick_start_phase_timer.emit(
1555
+ &workspace,
1556
+ "launch.phase",
1557
+ crate::lifecycle::restart::LifecyclePhase::ReadinessWait,
1558
+ );
1536
1559
  let worker_readiness = quick_start_worker_readiness(&workspace, &state_team_key);
1537
1560
  let attach_windows = load_runtime_state(&workspace)
1538
1561
  .ok()
@@ -1572,7 +1595,11 @@ pub(crate) fn quick_start_with_transport_in_workspace_pi_preflight(
1572
1595
  ));
1573
1596
  }
1574
1597
  next_actions.extend(attach_commands.iter().cloned());
1575
- quick_start_phase_timer.emit(&workspace, "launch.phase", crate::lifecycle::restart::LifecyclePhase::Completed);
1598
+ quick_start_phase_timer.emit(
1599
+ &workspace,
1600
+ "launch.phase",
1601
+ crate::lifecycle::restart::LifecyclePhase::Completed,
1602
+ );
1576
1603
  Ok(QuickStartReport::Ready {
1577
1604
  session_name,
1578
1605
  launch: Box::new(launch),
@@ -1595,8 +1622,15 @@ fn preserve_quick_start_bootstrap_binding(
1595
1622
  if let Some(receiver) = bootstrap.get("leader_receiver") {
1596
1623
  binding = binding.with_leader_receiver(receiver.clone());
1597
1624
  }
1598
- if let Some(epoch) = bootstrap.get("owner_epoch").and_then(serde_json::Value::as_u64)
1599
- .or_else(|| bootstrap.get("team_owner").and_then(|owner| owner.get("owner_epoch")).and_then(serde_json::Value::as_u64))
1625
+ if let Some(epoch) = bootstrap
1626
+ .get("owner_epoch")
1627
+ .and_then(serde_json::Value::as_u64)
1628
+ .or_else(|| {
1629
+ bootstrap
1630
+ .get("team_owner")
1631
+ .and_then(|owner| owner.get("owner_epoch"))
1632
+ .and_then(serde_json::Value::as_u64)
1633
+ })
1600
1634
  {
1601
1635
  binding = binding.with_owner_epoch(epoch);
1602
1636
  }
@@ -1682,13 +1716,19 @@ mod fresh_quick_start_leader_binding_tests {
1682
1716
  assert_eq!(launched.get(key), bootstrap.get(key));
1683
1717
  assert_eq!(launched["teams"]["current"].get(key), bootstrap.get(key));
1684
1718
  }
1685
- assert_eq!(launched.get("leader_client"), bootstrap.get("leader_client"));
1719
+ assert_eq!(
1720
+ launched.get("leader_client"),
1721
+ bootstrap.get("leader_client")
1722
+ );
1686
1723
  assert_eq!(launched.get("is_external_leader"), Some(&json!(true)));
1687
1724
  assert_eq!(launched["agents"], json!({"worker": {}}));
1688
1725
  let merged = super::super::state_projection::merge_workspace_team_state_with_key(
1689
1726
  &bootstrap, &launched, "current",
1690
1727
  );
1691
- assert_eq!(merged["teams"]["current"]["team_owner"], bootstrap["team_owner"]);
1728
+ assert_eq!(
1729
+ merged["teams"]["current"]["team_owner"],
1730
+ bootstrap["team_owner"]
1731
+ );
1692
1732
  assert_eq!(merged["teams"]["current"]["owner_epoch"], json!(7));
1693
1733
  }
1694
1734
 
@@ -1702,20 +1742,34 @@ mod fresh_quick_start_leader_binding_tests {
1702
1742
  binary_path: Some("/tmp/candidate/team-agent".to_string()),
1703
1743
  binary_version: Some("0.5.112".to_string()),
1704
1744
  rotation_reason: Some("original rotation reason".to_string()),
1705
- binary_identity_relation: crate::coordinator::CoordinatorBinaryIdentityRelation::Unknown,
1745
+ binary_identity_relation:
1746
+ crate::coordinator::CoordinatorBinaryIdentityRelation::Unknown,
1706
1747
  log: Some(PathBuf::from("/tmp/current/.team/runtime/coordinator.log")),
1707
- schema_error: Some(crate::coordinator::SchemaError::InitFailed { message: "original database permission denied".to_string() }),
1748
+ schema_error: Some(crate::coordinator::SchemaError::InitFailed {
1749
+ message: "original database permission denied".to_string(),
1750
+ }),
1708
1751
  action: Some("repair the exact database permissions".to_string()),
1709
1752
  };
1710
1753
  let error = require_quick_start_coordinator_started(&report, Path::new("/tmp/current"))
1711
- .unwrap_err().to_string();
1712
- for detail in ["schema_incompatible", "original database permission denied", "repair the exact database permissions", "/tmp/candidate/team-agent", "/tmp/current/.team/runtime/coordinator.log", "workers may already be started"] {
1754
+ .unwrap_err()
1755
+ .to_string();
1756
+ for detail in [
1757
+ "schema_incompatible",
1758
+ "original database permission denied",
1759
+ "repair the exact database permissions",
1760
+ "/tmp/candidate/team-agent",
1761
+ "/tmp/current/.team/runtime/coordinator.log",
1762
+ "workers may already be started",
1763
+ ] {
1713
1764
  assert!(error.contains(detail), "lost {detail}: {error}");
1714
1765
  }
1715
1766
  report.ok = true;
1716
1767
  report.status = crate::coordinator::StartOutcome::AlreadyRunning;
1717
- report.binary_identity_relation = crate::coordinator::CoordinatorBinaryIdentityRelation::DaemonNewerThanCaller;
1718
- assert!(require_quick_start_coordinator_started(&report, Path::new("/tmp/current")).is_ok());
1768
+ report.binary_identity_relation =
1769
+ crate::coordinator::CoordinatorBinaryIdentityRelation::DaemonNewerThanCaller;
1770
+ assert!(
1771
+ require_quick_start_coordinator_started(&report, Path::new("/tmp/current")).is_ok()
1772
+ );
1719
1773
  }
1720
1774
 
1721
1775
  #[test]
@@ -1725,11 +1779,17 @@ mod fresh_quick_start_leader_binding_tests {
1725
1779
  env.scrub_tmux();
1726
1780
  env.assert_no_real_tmux();
1727
1781
  let workspace = std::env::temp_dir().join(format!(
1728
- "ta-current-bootstrap-{}-{}", std::process::id(), SEQUENCE.fetch_add(1, Ordering::Relaxed)
1782
+ "ta-current-bootstrap-{}-{}",
1783
+ std::process::id(),
1784
+ SEQUENCE.fetch_add(1, Ordering::Relaxed)
1729
1785
  ));
1730
1786
  let team = workspace.join(".team/current");
1731
1787
  std::fs::create_dir_all(team.join("agents")).unwrap();
1732
- std::fs::write(team.join("TEAM.md"), "---\nname: current\nobjective: Bootstrap fixture.\n---\n").unwrap();
1788
+ std::fs::write(
1789
+ team.join("TEAM.md"),
1790
+ "---\nname: current\nobjective: Bootstrap fixture.\n---\n",
1791
+ )
1792
+ .unwrap();
1733
1793
  std::fs::write(team.join("agents/worker.md"), "---\nname: worker\nrole: Worker\nprovider: codex\nauth_mode: subscription\ndangerously_skip_permissions: false\n---\nBounded fixture.\n").unwrap();
1734
1794
  let state_path = crate::state::persist::runtime_state_path(&workspace);
1735
1795
  std::fs::create_dir_all(state_path.parent().unwrap()).unwrap();
@@ -1749,10 +1809,20 @@ mod fresh_quick_start_leader_binding_tests {
1749
1809
  std::env::set_var("TMUX_PANE", "%0");
1750
1810
  std::env::set_var(CALLER_PANE_ENV, "%0");
1751
1811
  std::env::set_var(CALLER_PROVIDER_ENV, "pi");
1752
- std::env::set_var(CALLER_ENDPOINT_ENV, "/private/tmp/different-bootstrap/default");
1753
- let transport = OfflineTransport::new().with_tmux_endpoint("/private/tmp/bootstrap-test/default");
1754
- let result = quick_start_with_transport_in_workspace(&workspace, &team, None, true, None, &transport).unwrap();
1755
- assert!(matches!(result, QuickStartReport::PreflightBlocked { .. }), "unexpected outcome: {result:?}");
1812
+ std::env::set_var(
1813
+ CALLER_ENDPOINT_ENV,
1814
+ "/private/tmp/different-bootstrap/default",
1815
+ );
1816
+ let transport =
1817
+ OfflineTransport::new().with_tmux_endpoint("/private/tmp/bootstrap-test/default");
1818
+ let result = quick_start_with_transport_in_workspace(
1819
+ &workspace, &team, None, true, None, &transport,
1820
+ )
1821
+ .unwrap();
1822
+ assert!(
1823
+ matches!(result, QuickStartReport::PreflightBlocked { .. }),
1824
+ "unexpected outcome: {result:?}"
1825
+ );
1756
1826
  assert_eq!(std::fs::read(&state_path).unwrap(), before);
1757
1827
  assert!(!workspace.join(".team/team.db").exists());
1758
1828
  assert!(!crate::model::paths::runtime_spec_path(&workspace, "current").exists());
@@ -1922,10 +1992,7 @@ mod fresh_quick_start_leader_binding_tests {
1922
1992
  )
1923
1993
  }
1924
1994
  _ => crate::state::persist::save_runtime_state_with_receiver_authority(
1925
- workspace,
1926
- state,
1927
- &team_key,
1928
- None,
1995
+ workspace, state, &team_key, None,
1929
1996
  ),
1930
1997
  };
1931
1998
  if saved.is_ok() {
@@ -1941,9 +2008,7 @@ mod fresh_quick_start_leader_binding_tests {
1941
2008
  }
1942
2009
 
1943
2010
  fn frozen_seed_receipt(&self) -> Option<(serde_json::Value, serde_json::Value)> {
1944
- self.frozen_owner
1945
- .clone()
1946
- .zip(self.frozen_receiver.clone())
2011
+ self.frozen_owner.clone().zip(self.frozen_receiver.clone())
1947
2012
  }
1948
2013
 
1949
2014
  fn this_attempt_extra_state_keys(&self) -> Vec<&'static str> {
@@ -1990,12 +2055,15 @@ mod fresh_quick_start_leader_binding_tests {
1990
2055
  }
1991
2056
 
1992
2057
  #[test]
1993
- fn fresh_binding_persists_then_registers_then_requires_canonical_readback_provider_independent() {
2058
+ fn fresh_binding_persists_then_registers_then_requires_canonical_readback_provider_independent()
2059
+ {
1994
2060
  let workspace = workspace("positive");
1995
2061
  let mut ops = MockOps::default();
1996
- assert!(bind_fresh_quick_start_leader_with(&workspace, "fresh", None, &mut ops)
1997
- .unwrap());
1998
- assert_eq!(ops.attached_provider, Some(crate::provider::Provider::Codex));
2062
+ assert!(bind_fresh_quick_start_leader_with(&workspace, "fresh", None, &mut ops).unwrap());
2063
+ assert_eq!(
2064
+ ops.attached_provider,
2065
+ Some(crate::provider::Provider::Codex)
2066
+ );
1999
2067
  assert_eq!(ops.attach_calls, 1);
2000
2068
  assert_eq!(ops.register_calls, 1);
2001
2069
  assert_eq!(ops.readback_calls, 1);
@@ -2030,11 +2098,13 @@ mod fresh_quick_start_leader_binding_tests {
2030
2098
  leader_session_uuid: "uuid-fresh".to_string(),
2031
2099
  leader_session_uuid_source: "env".to_string(),
2032
2100
  };
2033
- assert!(super::spec_state::seed_launched_owner_from_caller_with_provider_lookup(
2034
- &mut state,
2035
- caller,
2036
- |_| None
2037
- ));
2101
+ assert!(
2102
+ super::spec_state::seed_launched_owner_from_caller_with_provider_lookup(
2103
+ &mut state,
2104
+ caller,
2105
+ |_| None
2106
+ )
2107
+ );
2038
2108
  let owner = state
2039
2109
  .pointer("/teams/fresh/team_owner")
2040
2110
  .cloned()
@@ -2061,13 +2131,10 @@ mod fresh_quick_start_leader_binding_tests {
2061
2131
  frozen_receiver: Some(frozen_receiver.clone()),
2062
2132
  ..MockOps::default()
2063
2133
  };
2064
- assert!(bind_fresh_quick_start_leader_with(
2065
- &workspace,
2066
- "fresh",
2067
- Some(&owner),
2068
- &mut ops
2069
- )
2070
- .unwrap());
2134
+ assert!(
2135
+ bind_fresh_quick_start_leader_with(&workspace, "fresh", Some(&owner), &mut ops)
2136
+ .unwrap()
2137
+ );
2071
2138
  assert_eq!(ops.attach_calls, 1);
2072
2139
  assert_eq!(ops.last_expected_receiver, Some(frozen_receiver));
2073
2140
  let _ = std::fs::remove_dir_all(&workspace);
@@ -2084,10 +2151,7 @@ mod fresh_quick_start_leader_binding_tests {
2084
2151
  state["leader_receiver"] = newer.clone();
2085
2152
  state["teams"]["fresh"]["leader_receiver"] = newer.clone();
2086
2153
  crate::state::persist::save_runtime_state_with_receiver_authority(
2087
- &workspace,
2088
- &state,
2089
- "fresh",
2090
- None,
2154
+ &workspace, &state, "fresh", None,
2091
2155
  )
2092
2156
  .unwrap();
2093
2157
  let on_disk = crate::state::persist::load_runtime_state(&workspace).unwrap();
@@ -2104,13 +2168,10 @@ mod fresh_quick_start_leader_binding_tests {
2104
2168
  frozen_receiver: Some(frozen_receiver),
2105
2169
  ..MockOps::default()
2106
2170
  };
2107
- assert!(!bind_fresh_quick_start_leader_with(
2108
- &workspace,
2109
- "fresh",
2110
- Some(&owner),
2111
- &mut ops
2112
- )
2113
- .unwrap());
2171
+ assert!(
2172
+ !bind_fresh_quick_start_leader_with(&workspace, "fresh", Some(&owner), &mut ops)
2173
+ .unwrap()
2174
+ );
2114
2175
  assert_eq!(ops.attach_calls, 0);
2115
2176
  assert_eq!(ops.last_expected_receiver, None);
2116
2177
  let _ = std::fs::remove_dir_all(&workspace);
@@ -2127,10 +2188,7 @@ mod fresh_quick_start_leader_binding_tests {
2127
2188
  state["leader_receiver"] = winner.clone();
2128
2189
  state["teams"]["fresh"]["leader_receiver"] = winner.clone();
2129
2190
  crate::state::persist::save_runtime_state_with_receiver_authority(
2130
- &workspace,
2131
- &state,
2132
- "fresh",
2133
- None,
2191
+ &workspace, &state, "fresh", None,
2134
2192
  )
2135
2193
  .unwrap();
2136
2194
  let on_disk = crate::state::persist::load_runtime_state(&workspace).unwrap();
@@ -2147,13 +2205,10 @@ mod fresh_quick_start_leader_binding_tests {
2147
2205
  frozen_receiver: Some(frozen_receiver),
2148
2206
  ..MockOps::default()
2149
2207
  };
2150
- assert!(!bind_fresh_quick_start_leader_with(
2151
- &workspace,
2152
- "fresh",
2153
- Some(&owner),
2154
- &mut ops
2155
- )
2156
- .unwrap());
2208
+ assert!(
2209
+ !bind_fresh_quick_start_leader_with(&workspace, "fresh", Some(&owner), &mut ops)
2210
+ .unwrap()
2211
+ );
2157
2212
  assert_eq!(ops.attach_calls, 0);
2158
2213
  assert_eq!(ops.last_expected_receiver, None);
2159
2214
  let _ = std::fs::remove_dir_all(&workspace);
@@ -2163,7 +2218,11 @@ mod fresh_quick_start_leader_binding_tests {
2163
2218
  fn fresh_bind_refusal_event_keeps_first_safe_stage_and_reason() {
2164
2219
  for (case, expected_stage, expected_reason) in [
2165
2220
  ("missing_pane", "caller_pane", "caller_pane_missing"),
2166
- ("empty_command", "command_observation", "command_unobservable"),
2221
+ (
2222
+ "empty_command",
2223
+ "command_observation",
2224
+ "command_unobservable",
2225
+ ),
2167
2226
  ("unknown_provider", "strict_provider", "provider_unresolved"),
2168
2227
  (
2169
2228
  "existing_owner",
@@ -2200,12 +2259,16 @@ mod fresh_quick_start_leader_binding_tests {
2200
2259
  }
2201
2260
  crate::state::persist::save_runtime_state(&workspace, &state).unwrap();
2202
2261
 
2203
- assert!(!bind_fresh_quick_start_leader_with(&workspace, "fresh", None, &mut ops)
2204
- .unwrap());
2262
+ assert!(
2263
+ !bind_fresh_quick_start_leader_with(&workspace, "fresh", None, &mut ops).unwrap()
2264
+ );
2205
2265
  let events = crate::event_log::EventLog::new(&workspace).tail(0).unwrap();
2206
2266
  assert_eq!(events.len(), 1, "{case} must emit one first-refusal event");
2207
2267
  assert_eq!(events[0]["event"], json!(FRESH_BIND_REFUSAL_EVENT));
2208
- assert_eq!(events[0]["operation"], json!("fresh_quick_start_leader_bind"));
2268
+ assert_eq!(
2269
+ events[0]["operation"],
2270
+ json!("fresh_quick_start_leader_bind")
2271
+ );
2209
2272
  assert_eq!(events[0]["team_key"], json!("fresh"));
2210
2273
  assert_eq!(events[0]["stage"], json!(expected_stage));
2211
2274
  assert_eq!(events[0]["reason"], json!(expected_reason));
@@ -2223,9 +2286,12 @@ mod fresh_quick_start_leader_binding_tests {
2223
2286
  ));
2224
2287
  std::fs::create_dir_all(&empty_workspace).unwrap();
2225
2288
  let mut ops = MockOps::default();
2226
- assert!(!bind_fresh_quick_start_leader_with(&empty_workspace, "fresh", None, &mut ops)
2227
- .unwrap());
2228
- let events = crate::event_log::EventLog::new(&empty_workspace).tail(0).unwrap();
2289
+ assert!(
2290
+ !bind_fresh_quick_start_leader_with(&empty_workspace, "fresh", None, &mut ops).unwrap()
2291
+ );
2292
+ let events = crate::event_log::EventLog::new(&empty_workspace)
2293
+ .tail(0)
2294
+ .unwrap();
2229
2295
  assert_eq!(events.len(), 1);
2230
2296
  assert_eq!(events[0]["stage"], json!("scope"));
2231
2297
  assert_eq!(events[0]["reason"], json!("scope_unresolved"));
@@ -2240,8 +2306,9 @@ mod fresh_quick_start_leader_binding_tests {
2240
2306
  state["teams"] = json!({"fresh": {"team_key": "fresh", "agents": {}}});
2241
2307
  crate::state::persist::save_runtime_state(&workspace, &state).unwrap();
2242
2308
  let mut ops = MockOps::default();
2243
- assert!(!bind_fresh_quick_start_leader_with(&workspace, "current", None, &mut ops)
2244
- .unwrap());
2309
+ assert!(
2310
+ !bind_fresh_quick_start_leader_with(&workspace, "current", None, &mut ops).unwrap()
2311
+ );
2245
2312
  let events = crate::event_log::EventLog::new(&workspace).tail(0).unwrap();
2246
2313
  assert_eq!(events.len(), 1);
2247
2314
  assert_eq!(events[0]["stage"], json!("scope"));
@@ -2285,10 +2352,10 @@ mod fresh_quick_start_leader_binding_tests {
2285
2352
  ops.command = Some("codex".to_string());
2286
2353
  }
2287
2354
  "existing_owner" => state["team_owner"] = json!({"pane_id": "%old"}),
2288
- "existing_receiver" => {
2289
- state["leader_receiver"] = json!({"pane_id": "%old"})
2290
- }
2291
- "provider_mismatch" | "socket_mismatch" | "workspace_mismatch"
2355
+ "existing_receiver" => state["leader_receiver"] = json!({"pane_id": "%old"}),
2356
+ "provider_mismatch"
2357
+ | "socket_mismatch"
2358
+ | "workspace_mismatch"
2292
2359
  | "dual_state_mismatch" => {
2293
2360
  state["workspace"] = json!(workspace);
2294
2361
  state["team_owner"] = json!({
@@ -2303,8 +2370,10 @@ mod fresh_quick_start_leader_binding_tests {
2303
2370
  match case {
2304
2371
  "provider_mismatch" => {
2305
2372
  state["leader_receiver"]["provider"] = json!("claude")
2306
- },
2307
- "socket_mismatch" => state["leader_receiver"]["tmux_socket"] = json!("/tmp/other"),
2373
+ }
2374
+ "socket_mismatch" => {
2375
+ state["leader_receiver"]["tmux_socket"] = json!("/tmp/other")
2376
+ }
2308
2377
  "workspace_mismatch" => state["workspace"] = json!(workspace.join("other")),
2309
2378
  "dual_state_mismatch" => state["team_owner"]["owner_epoch"] = json!(2),
2310
2379
  _ => unreachable!(),
@@ -2314,11 +2383,10 @@ mod fresh_quick_start_leader_binding_tests {
2314
2383
  _ => unreachable!(),
2315
2384
  }
2316
2385
  crate::state::persist::save_runtime_state(&workspace, &state).unwrap();
2317
- let before = std::fs::read(crate::state::persist::runtime_state_path(&workspace))
2318
- .unwrap();
2386
+ let before =
2387
+ std::fs::read(crate::state::persist::runtime_state_path(&workspace)).unwrap();
2319
2388
  assert!(
2320
- !bind_fresh_quick_start_leader_with(&workspace, team_key, None, &mut ops)
2321
- .unwrap(),
2389
+ !bind_fresh_quick_start_leader_with(&workspace, team_key, None, &mut ops).unwrap(),
2322
2390
  "{case} must refuse"
2323
2391
  );
2324
2392
  assert_eq!(
@@ -2490,15 +2558,23 @@ mod fresh_quick_start_leader_binding_tests {
2490
2558
  || bind_fresh_quick_start_leader_with(&workspace, "fresh", None, &mut ops)
2491
2559
  )
2492
2560
  .unwrap());
2493
- assert_eq!(ops.attach_calls, 0, "preseeded dual state must not reattach");
2494
- let path = crate::leader::registry::registry_dir().unwrap().join(format!(
2495
- "{}__fresh.json",
2496
- crate::leader::registry::workspace_hash(&workspace)
2497
- ));
2561
+ assert_eq!(
2562
+ ops.attach_calls, 0,
2563
+ "preseeded dual state must not reattach"
2564
+ );
2565
+ let path = crate::leader::registry::registry_dir()
2566
+ .unwrap()
2567
+ .join(format!(
2568
+ "{}__fresh.json",
2569
+ crate::leader::registry::workspace_hash(&workspace)
2570
+ ));
2498
2571
  let entry: crate::leader::registry::LeaderRegistryEntry =
2499
2572
  serde_json::from_slice(&std::fs::read(path).unwrap()).unwrap();
2500
2573
  assert_eq!(
2501
- entry.channel.get("tmux_socket").and_then(serde_json::Value::as_str),
2574
+ entry
2575
+ .channel
2576
+ .get("tmux_socket")
2577
+ .and_then(serde_json::Value::as_str),
2502
2578
  Some("/private/tmp/tmux-test/default")
2503
2579
  );
2504
2580
  }
@@ -2528,8 +2604,7 @@ mod fresh_quick_start_leader_binding_tests {
2528
2604
  let before = std::fs::read(crate::state::persist::runtime_state_path(&workspace)).unwrap();
2529
2605
  let mut ops = MockOps::default();
2530
2606
 
2531
- assert!(!bind_fresh_quick_start_leader_with(&workspace, "fresh", None, &mut ops)
2532
- .unwrap());
2607
+ assert!(!bind_fresh_quick_start_leader_with(&workspace, "fresh", None, &mut ops).unwrap());
2533
2608
  assert_eq!(
2534
2609
  before,
2535
2610
  std::fs::read(crate::state::persist::runtime_state_path(&workspace)).unwrap(),
@@ -2709,10 +2784,7 @@ mod fresh_quick_start_leader_binding_tests {
2709
2784
  persisted["teams"][team_key]["leader_receiver"] = takeover.receiver.clone();
2710
2785
  persisted["teams"][team_key]["owner_epoch"] = json!(takeover.epoch);
2711
2786
  crate::state::persist::save_runtime_state_with_receiver_authority(
2712
- workspace,
2713
- &persisted,
2714
- team_key,
2715
- None,
2787
+ workspace, &persisted, team_key, None,
2716
2788
  )
2717
2789
  .unwrap();
2718
2790
  assert_fresh_binding_kept(
@@ -2744,18 +2816,13 @@ mod fresh_quick_start_leader_binding_tests {
2744
2816
  }
2745
2817
  }
2746
2818
 
2747
- fn assert_fresh_binding_kept(
2748
- persisted: &serde_json::Value,
2749
- takeover: &ConcurrentTakeover,
2750
- ) {
2819
+ fn assert_fresh_binding_kept(persisted: &serde_json::Value, takeover: &ConcurrentTakeover) {
2751
2820
  assert_eq!(
2752
- persisted["teams"]["fresh"]["team_owner"],
2753
- takeover.owner,
2821
+ persisted["teams"]["fresh"]["team_owner"], takeover.owner,
2754
2822
  "concurrent team_owner must survive seeded cleanup"
2755
2823
  );
2756
2824
  assert_eq!(
2757
- persisted["teams"]["fresh"]["leader_receiver"],
2758
- takeover.receiver,
2825
+ persisted["teams"]["fresh"]["leader_receiver"], takeover.receiver,
2759
2826
  "concurrent leader_receiver must survive seeded cleanup"
2760
2827
  );
2761
2828
  assert_eq!(
@@ -2769,13 +2836,10 @@ mod fresh_quick_start_leader_binding_tests {
2769
2836
  fn seeded_cleanup_clears_exact_seed_through_bind_repository_entry() {
2770
2837
  let (workspace, seed) = workspace_with_fresh_seed("seed-cleanup-success");
2771
2838
  let mut ops = failed_register_ops(None, false);
2772
- assert!(!bind_fresh_quick_start_leader_with(
2773
- &workspace,
2774
- "fresh",
2775
- Some(&seed),
2776
- &mut ops
2777
- )
2778
- .unwrap());
2839
+ assert!(
2840
+ !bind_fresh_quick_start_leader_with(&workspace, "fresh", Some(&seed), &mut ops)
2841
+ .unwrap()
2842
+ );
2779
2843
  assert_eq!(ops.inner.attach_calls, 1);
2780
2844
  assert_eq!(ops.inner.register_calls, 1);
2781
2845
  assert!(ops
@@ -2794,11 +2858,9 @@ mod fresh_quick_start_leader_binding_tests {
2794
2858
  "matching seed must be cleared via bind/repository; got {}",
2795
2859
  persisted["teams"]["fresh"]["team_owner"]
2796
2860
  );
2797
- assert!(
2798
- persisted
2799
- .pointer("/teams/fresh/leader_receiver")
2800
- .is_some_and(serde_json::Value::is_null)
2801
- );
2861
+ assert!(persisted
2862
+ .pointer("/teams/fresh/leader_receiver")
2863
+ .is_some_and(serde_json::Value::is_null));
2802
2864
  assert_eq!(
2803
2865
  persisted["teams"]["fresh"]["owner_epoch"],
2804
2866
  json!(1),
@@ -2811,13 +2873,10 @@ mod fresh_quick_start_leader_binding_tests {
2811
2873
  let (workspace, seed) = workspace_with_matching_seed("seed-cleanup-concurrent");
2812
2874
  let takeover = takeover_binding(1);
2813
2875
  let mut ops = failed_register_ops(Some(takeover_binding(1)), false);
2814
- assert!(!bind_fresh_quick_start_leader_with(
2815
- &workspace,
2816
- "fresh",
2817
- Some(&seed),
2818
- &mut ops
2819
- )
2820
- .unwrap());
2876
+ assert!(
2877
+ !bind_fresh_quick_start_leader_with(&workspace, "fresh", Some(&seed), &mut ops)
2878
+ .unwrap()
2879
+ );
2821
2880
  assert_fresh_binding_kept(
2822
2881
  &crate::state::persist::load_runtime_state(&workspace).unwrap(),
2823
2882
  &takeover,
@@ -2829,13 +2888,10 @@ mod fresh_quick_start_leader_binding_tests {
2829
2888
  let (workspace, seed) = workspace_with_matching_seed("seed-cleanup-epoch2");
2830
2889
  let takeover = takeover_binding(2);
2831
2890
  let mut ops = failed_register_ops(Some(takeover_binding(2)), false);
2832
- assert!(!bind_fresh_quick_start_leader_with(
2833
- &workspace,
2834
- "fresh",
2835
- Some(&seed),
2836
- &mut ops
2837
- )
2838
- .unwrap());
2891
+ assert!(
2892
+ !bind_fresh_quick_start_leader_with(&workspace, "fresh", Some(&seed), &mut ops)
2893
+ .unwrap()
2894
+ );
2839
2895
  assert_fresh_binding_kept(
2840
2896
  &crate::state::persist::load_runtime_state(&workspace).unwrap(),
2841
2897
  &takeover,
@@ -2846,13 +2902,8 @@ mod fresh_quick_start_leader_binding_tests {
2846
2902
  fn seeded_cleanup_propagates_persist_error() {
2847
2903
  let (workspace, seed) = workspace_with_fresh_seed("seed-cleanup-persist-err");
2848
2904
  let mut ops = failed_register_ops(None, true);
2849
- let error = bind_fresh_quick_start_leader_with(
2850
- &workspace,
2851
- "fresh",
2852
- Some(&seed),
2853
- &mut ops,
2854
- )
2855
- .expect_err("poisoned state.json must surface cleanup persist failure");
2905
+ let error = bind_fresh_quick_start_leader_with(&workspace, "fresh", Some(&seed), &mut ops)
2906
+ .expect_err("poisoned state.json must surface cleanup persist failure");
2856
2907
  assert_eq!(ops.inner.attach_calls, 1);
2857
2908
  assert_eq!(ops.inner.register_calls, 1);
2858
2909
  assert!(ops
@@ -2932,7 +2983,9 @@ mod fresh_quick_start_leader_binding_tests {
2932
2983
  "owner_epoch": 1
2933
2984
  }
2934
2985
  });
2935
- serde_json::to_string_pretty(&expected).unwrap().into_bytes()
2986
+ serde_json::to_string_pretty(&expected)
2987
+ .unwrap()
2988
+ .into_bytes()
2936
2989
  }
2937
2990
 
2938
2991
  fn assert_failure_rolls_back_this_attempt(
@@ -3031,8 +3084,7 @@ mod fresh_quick_start_leader_binding_tests {
3031
3084
  attach_ok: false,
3032
3085
  ..MockOps::default()
3033
3086
  };
3034
- assert!(!bind_fresh_quick_start_leader_with(&workspace, "fresh", None, &mut ops)
3035
- .unwrap());
3087
+ assert!(!bind_fresh_quick_start_leader_with(&workspace, "fresh", None, &mut ops).unwrap());
3036
3088
  let after = crate::state::persist::load_runtime_state(&workspace).unwrap();
3037
3089
  assert_eq!(after.get("tasks"), Some(&json!({"keep": true})));
3038
3090
  assert!(after.get("failed_attach_mutation").is_none());
@@ -3090,18 +3142,34 @@ mod fresh_quick_start_leader_binding_tests {
3090
3142
  let pane = PaneId::new("%0");
3091
3143
  assert_ne!(socket.to_str(), Some(endpoint.as_str()));
3092
3144
  assert!(persisted_binding_matches_verified_pane(
3093
- &state, workspace, &pane, Provider::Pi, Some(&endpoint),
3145
+ &state,
3146
+ workspace,
3147
+ &pane,
3148
+ Provider::Pi,
3149
+ Some(&endpoint),
3094
3150
  ));
3095
3151
  assert_eq!(state, before);
3096
3152
  assert!(!persisted_binding_matches_verified_pane(
3097
- &state, workspace, &PaneId::new("%1"), Provider::Pi, Some(&endpoint),
3153
+ &state,
3154
+ workspace,
3155
+ &PaneId::new("%1"),
3156
+ Provider::Pi,
3157
+ Some(&endpoint),
3098
3158
  ));
3099
3159
  assert!(!persisted_binding_matches_verified_pane(
3100
- &state, workspace, &pane, Provider::Codex, Some(&endpoint),
3160
+ &state,
3161
+ workspace,
3162
+ &pane,
3163
+ Provider::Codex,
3164
+ Some(&endpoint),
3101
3165
  ));
3102
3166
  for endpoint in [None, Some("")] {
3103
3167
  assert!(!persisted_binding_matches_verified_pane(
3104
- &state, workspace, &pane, Provider::Pi, endpoint,
3168
+ &state,
3169
+ workspace,
3170
+ &pane,
3171
+ Provider::Pi,
3172
+ endpoint,
3105
3173
  ));
3106
3174
  }
3107
3175
  for (field, value) in [
@@ -3121,15 +3189,26 @@ mod fresh_quick_start_leader_binding_tests {
3121
3189
  ] {
3122
3190
  let mut conflict = state.clone();
3123
3191
  *conflict.pointer_mut(field).unwrap() = value;
3124
- assert!(!persisted_binding_matches_verified_pane(
3125
- &conflict, workspace, &pane, Provider::Pi, Some(&endpoint),
3126
- ), "conflicting {field} must refuse");
3192
+ assert!(
3193
+ !persisted_binding_matches_verified_pane(
3194
+ &conflict,
3195
+ workspace,
3196
+ &pane,
3197
+ Provider::Pi,
3198
+ Some(&endpoint),
3199
+ ),
3200
+ "conflicting {field} must refuse"
3201
+ );
3127
3202
  }
3128
3203
  let mut unauthorized = state.clone();
3129
3204
  unauthorized["leader_receiver"]["authorized_team_workspace"] =
3130
3205
  json!(workspace.join("foreign"));
3131
3206
  assert!(!persisted_binding_matches_verified_pane(
3132
- &unauthorized, workspace, &pane, Provider::Pi, Some(&endpoint),
3207
+ &unauthorized,
3208
+ workspace,
3209
+ &pane,
3210
+ Provider::Pi,
3211
+ Some(&endpoint),
3133
3212
  ));
3134
3213
  }
3135
3214
 
@@ -3143,15 +3222,24 @@ mod fresh_quick_start_leader_binding_tests {
3143
3222
  let endpoint = transport.tmux_endpoint().unwrap();
3144
3223
  let foreign_socket = workspace.join("foreign-socket-root").join(&endpoint);
3145
3224
  let state = native_persisted_binding(workspace, foreign_socket.to_str().unwrap());
3146
- assert_eq!(foreign_socket.file_name().unwrap().to_str(), Some(endpoint.as_str()));
3225
+ assert_eq!(
3226
+ foreign_socket.file_name().unwrap().to_str(),
3227
+ Some(endpoint.as_str())
3228
+ );
3147
3229
  assert!(!persisted_binding_matches_verified_pane(
3148
- &state, workspace, &PaneId::new("%0"), Provider::Pi, Some(&endpoint),
3230
+ &state,
3231
+ workspace,
3232
+ &PaneId::new("%0"),
3233
+ Provider::Pi,
3234
+ Some(&endpoint),
3149
3235
  ));
3150
3236
  assert!(!quick_start_tmux_endpoints_match(
3151
- foreign_socket.to_str().unwrap(), "default",
3237
+ foreign_socket.to_str().unwrap(),
3238
+ "default",
3152
3239
  ));
3153
3240
  assert!(!quick_start_tmux_endpoints_match(
3154
- foreign_socket.to_str().unwrap(), "",
3241
+ foreign_socket.to_str().unwrap(),
3242
+ "",
3155
3243
  ));
3156
3244
  }
3157
3245
 
@@ -3169,7 +3257,10 @@ mod fresh_quick_start_leader_binding_tests {
3169
3257
  std::fs::write(&socket, "fixture endpoint; no tmux server").unwrap();
3170
3258
  let state = native_persisted_binding(workspace, socket.to_str().unwrap());
3171
3259
  assert!(persisted_binding_matches_verified_pane(
3172
- &state, workspace, &PaneId::new("%0"), Provider::Pi,
3260
+ &state,
3261
+ workspace,
3262
+ &PaneId::new("%0"),
3263
+ Provider::Pi,
3173
3264
  alias.join("ta-native.sock").to_str(),
3174
3265
  ));
3175
3266
  }
@@ -3185,10 +3276,7 @@ mod fresh_quick_start_leader_binding_tests {
3185
3276
  state["teams"]["fresh"]["leader_receiver"] = receiver.clone();
3186
3277
  state["teams"]["fresh"]["owner_epoch"] = json!(epoch);
3187
3278
  crate::state::persist::save_runtime_state_with_receiver_authority(
3188
- workspace,
3189
- &state,
3190
- "fresh",
3191
- None,
3279
+ workspace, &state, "fresh", None,
3192
3280
  )
3193
3281
  .unwrap();
3194
3282
  let raw = std::fs::read(crate::state::persist::runtime_state_path(workspace)).unwrap();
@@ -3248,7 +3336,10 @@ mod fresh_quick_start_leader_binding_tests {
3248
3336
  .unwrap();
3249
3337
  let after = crate::state::persist::load_runtime_state(&workspace).unwrap();
3250
3338
  assert_eq!(after["teams"]["fresh"]["team_owner"], previous_owner);
3251
- assert_eq!(after["teams"]["fresh"]["leader_receiver"], previous_receiver);
3339
+ assert_eq!(
3340
+ after["teams"]["fresh"]["leader_receiver"],
3341
+ previous_receiver
3342
+ );
3252
3343
  assert_eq!(after["teams"]["fresh"]["owner_epoch"], json!(1));
3253
3344
  assert_eq!(after.get("tasks"), Some(&json!({"keep": true})));
3254
3345
  let _ = std::fs::remove_dir_all(&workspace);
@@ -3298,7 +3389,10 @@ mod fresh_quick_start_leader_binding_tests {
3298
3389
  assert_eq!(after["teams"]["fresh"]["leader_receiver"], winner_receiver);
3299
3390
  assert_eq!(after["teams"]["fresh"]["owner_epoch"], json!(2));
3300
3391
  assert_ne!(after["teams"]["fresh"]["team_owner"], previous_owner);
3301
- assert_ne!(after["teams"]["fresh"]["leader_receiver"], previous_receiver);
3392
+ assert_ne!(
3393
+ after["teams"]["fresh"]["leader_receiver"],
3394
+ previous_receiver
3395
+ );
3302
3396
  let _ = std::fs::remove_dir_all(&workspace);
3303
3397
  }
3304
3398
 
@@ -3343,19 +3437,23 @@ mod fresh_quick_start_leader_binding_tests {
3343
3437
  let _home = HomeGuard::set(&home);
3344
3438
  let state_path = crate::state::persist::runtime_state_path(&workspace);
3345
3439
  let before = std::fs::read(&state_path).unwrap();
3346
- let registry_path = crate::leader::registry::registry_dir().unwrap().join(format!(
3347
- "{}__fresh.json",
3348
- crate::leader::registry::workspace_hash(&workspace)
3349
- ));
3440
+ let registry_path = crate::leader::registry::registry_dir()
3441
+ .unwrap()
3442
+ .join(format!(
3443
+ "{}__fresh.json",
3444
+ crate::leader::registry::workspace_hash(&workspace)
3445
+ ));
3350
3446
  let mut ops = AmbientRegistryOps {
3351
3447
  readback_ok: false,
3352
3448
  attach_calls: 0,
3353
3449
  registry_receipt: None,
3354
3450
  };
3355
- assert!(!bind_fresh_quick_start_leader_with(&workspace, "fresh", None, &mut ops)
3356
- .unwrap());
3451
+ assert!(!bind_fresh_quick_start_leader_with(&workspace, "fresh", None, &mut ops).unwrap());
3357
3452
  assert_eq!(std::fs::read(state_path).unwrap(), before);
3358
- assert!(!registry_path.exists(), "failed readback left registry bytes");
3453
+ assert!(
3454
+ !registry_path.exists(),
3455
+ "failed readback left registry bytes"
3456
+ );
3359
3457
  }
3360
3458
 
3361
3459
  struct RecordingRuntimeOps<'a> {
@@ -3563,7 +3661,10 @@ mod fresh_quick_start_leader_binding_tests {
3563
3661
  let mut focused = caller_target(parent.clone(), Some("shared-live-nonce"));
3564
3662
  focused.active = true;
3565
3663
  let (active_ok, active_reason) = bind_seeded_caller(focused, "runtime-focus-active");
3566
- assert!(active_ok, "focused live caller must bind: {active_reason:?}");
3664
+ assert!(
3665
+ active_ok,
3666
+ "focused live caller must bind: {active_reason:?}"
3667
+ );
3567
3668
 
3568
3669
  let mut background = caller_target(parent, Some("shared-live-nonce"));
3569
3670
  background.active = false;
@@ -3599,8 +3700,10 @@ mod fresh_quick_start_leader_binding_tests {
3599
3700
  frozen_receiver: None,
3600
3701
  nonce_writer: None,
3601
3702
  };
3602
- assert!(!bind_fresh_quick_start_leader_with(&workspace, "fresh", Some(&seed), &mut ops)
3603
- .unwrap());
3703
+ assert!(
3704
+ !bind_fresh_quick_start_leader_with(&workspace, "fresh", Some(&seed), &mut ops)
3705
+ .unwrap()
3706
+ );
3604
3707
  assert_eq!(ops.last_failure_reason, Some("caller_pane_not_live"));
3605
3708
  }
3606
3709
 
@@ -3647,7 +3750,10 @@ mod fresh_quick_start_leader_binding_tests {
3647
3750
  .map(|agents| agents.keys().cloned().collect::<Vec<_>>())
3648
3751
  .unwrap_or_default();
3649
3752
  assert_eq!(ids, vec!["bob".to_string()]);
3650
- assert_eq!(view.get("session_name").and_then(serde_json::Value::as_str), Some("team-bob"));
3753
+ assert_eq!(
3754
+ view.get("session_name").and_then(serde_json::Value::as_str),
3755
+ Some("team-bob")
3756
+ );
3651
3757
  }
3652
3758
 
3653
3759
  #[test]
@@ -3750,11 +3856,7 @@ mod fresh_quick_start_leader_binding_tests {
3750
3856
  .with_tmux_endpoint("/tmp/tmux.sock")
3751
3857
  .with_targets(vec![stale_target]);
3752
3858
  assert!(matches!(
3753
- crate::messaging::resolve_live_leader_channel(
3754
- &workspace,
3755
- &receiver,
3756
- &stale_transport
3757
- ),
3859
+ crate::messaging::resolve_live_leader_channel(&workspace, &receiver, &stale_transport),
3758
3860
  crate::messaging::LeaderChannelResolution::Unbound(
3759
3861
  crate::messaging::LeaderChannelUnbound::PaneWorkspaceMismatch(_)
3760
3862
  )
@@ -3792,10 +3894,17 @@ mod fresh_quick_start_leader_binding_tests {
3792
3894
  ));
3793
3895
 
3794
3896
  let mut foreign_receiver = receiver.clone();
3795
- foreign_receiver["authorized_team_workspace"] =
3796
- json!(hermetic.root().join("foreign").to_string_lossy().to_string());
3897
+ foreign_receiver["authorized_team_workspace"] = json!(hermetic
3898
+ .root()
3899
+ .join("foreign")
3900
+ .to_string_lossy()
3901
+ .to_string());
3797
3902
  assert!(matches!(
3798
- crate::messaging::resolve_live_leader_channel(&workspace, &foreign_receiver, &transport),
3903
+ crate::messaging::resolve_live_leader_channel(
3904
+ &workspace,
3905
+ &foreign_receiver,
3906
+ &transport
3907
+ ),
3799
3908
  crate::messaging::LeaderChannelResolution::Unbound(
3800
3909
  crate::messaging::LeaderChannelUnbound::PaneWorkspaceMismatch(_)
3801
3910
  )
@@ -3998,10 +4107,7 @@ mod fresh_quick_start_leader_binding_tests {
3998
4107
  let mut winner = crate::state::persist::load_runtime_state(workspace).unwrap();
3999
4108
  winner["teams"][team_key]["leader_receiver"]["pane_id"] = json!("%winner");
4000
4109
  crate::state::persist::save_runtime_state_with_receiver_authority(
4001
- workspace,
4002
- &winner,
4003
- team_key,
4004
- None,
4110
+ workspace, &winner, team_key, None,
4005
4111
  )
4006
4112
  .unwrap();
4007
4113
  let _ = crate::leader::registry::register_binding_from_state_best_effort(
@@ -4037,10 +4143,7 @@ mod fresh_quick_start_leader_binding_tests {
4037
4143
  .with_tmux_endpoint("/tmp/tmux.sock")
4038
4144
  .with_pane_current_command("%1", "bash")
4039
4145
  .with_targets(vec![target_with_nonce.clone()])
4040
- .with_target_snapshots(vec![
4041
- vec![target_without_nonce],
4042
- vec![target_with_nonce],
4043
- ]);
4146
+ .with_target_snapshots(vec![vec![target_without_nonce], vec![target_with_nonce]]);
4044
4147
  let mut ops = RuntimeCommitFailureOps {
4045
4148
  inner: RuntimeFreshQuickStartLeaderBindingOps {
4046
4149
  transport: &transport,
@@ -4059,13 +4162,10 @@ mod fresh_quick_start_leader_binding_tests {
4059
4162
  break_registry_lock: false,
4060
4163
  break_registry_read: false,
4061
4164
  };
4062
- assert!(!bind_fresh_quick_start_leader_with(
4063
- &workspace,
4064
- "fresh",
4065
- Some(&seed),
4066
- &mut ops
4067
- )
4068
- .unwrap());
4165
+ assert!(
4166
+ !bind_fresh_quick_start_leader_with(&workspace, "fresh", Some(&seed), &mut ops)
4167
+ .unwrap()
4168
+ );
4069
4169
  let persisted = crate::state::persist::load_runtime_state(&workspace).unwrap();
4070
4170
  assert!(persisted
4071
4171
  .pointer("/teams/fresh/team_owner")
@@ -4080,7 +4180,10 @@ mod fresh_quick_start_leader_binding_tests {
4080
4180
  "{}__fresh.json",
4081
4181
  crate::leader::registry::workspace_hash(&workspace)
4082
4182
  ));
4083
- assert!(!registry_path.exists(), "failed child grant left registry row");
4183
+ assert!(
4184
+ !registry_path.exists(),
4185
+ "failed child grant left registry row"
4186
+ );
4084
4187
  let observed = transport.list_targets().unwrap();
4085
4188
  assert_eq!(
4086
4189
  observed[0]
@@ -4128,14 +4231,14 @@ mod fresh_quick_start_leader_binding_tests {
4128
4231
  break_registry_lock: false,
4129
4232
  break_registry_read: false,
4130
4233
  };
4131
- assert!(!bind_fresh_quick_start_leader_with(
4132
- &workspace,
4133
- "fresh",
4134
- Some(&seed),
4135
- &mut ops,
4136
- )
4137
- .unwrap());
4138
- assert_eq!(ops.inner.last_failure_reason, Some("attach_event_log_failed"));
4234
+ assert!(
4235
+ !bind_fresh_quick_start_leader_with(&workspace, "fresh", Some(&seed), &mut ops,)
4236
+ .unwrap()
4237
+ );
4238
+ assert_eq!(
4239
+ ops.inner.last_failure_reason,
4240
+ Some("attach_event_log_failed")
4241
+ );
4139
4242
  let persisted = crate::state::persist::load_runtime_state(&workspace).unwrap();
4140
4243
  assert!(persisted
4141
4244
  .pointer("/teams/fresh/team_owner")
@@ -4192,7 +4295,10 @@ mod fresh_quick_start_leader_binding_tests {
4192
4295
  || bind_fresh_quick_start_leader_with(&workspace, "fresh", Some(&seed), &mut ops)
4193
4296
  )
4194
4297
  .unwrap());
4195
- assert_eq!(ops.last_failure_reason, Some("receiver_live_channel_unavailable"));
4298
+ assert_eq!(
4299
+ ops.last_failure_reason,
4300
+ Some("receiver_live_channel_unavailable")
4301
+ );
4196
4302
  let persisted = crate::state::persist::load_runtime_state(&workspace).unwrap();
4197
4303
  assert!(persisted
4198
4304
  .pointer("/teams/fresh/team_owner")
@@ -4245,13 +4351,10 @@ mod fresh_quick_start_leader_binding_tests {
4245
4351
  break_registry_lock: false,
4246
4352
  break_registry_read: false,
4247
4353
  };
4248
- assert!(!bind_fresh_quick_start_leader_with(
4249
- &workspace,
4250
- "fresh",
4251
- Some(&seed),
4252
- &mut ops
4253
- )
4254
- .unwrap());
4354
+ assert!(
4355
+ !bind_fresh_quick_start_leader_with(&workspace, "fresh", Some(&seed), &mut ops)
4356
+ .unwrap()
4357
+ );
4255
4358
  let persisted = crate::state::persist::load_runtime_state(&workspace).unwrap();
4256
4359
  assert!(persisted
4257
4360
  .pointer("/teams/fresh/team_owner")
@@ -4265,7 +4368,10 @@ mod fresh_quick_start_leader_binding_tests {
4265
4368
  "{}__fresh.json",
4266
4369
  crate::leader::registry::workspace_hash(&workspace)
4267
4370
  ));
4268
- assert!(!registry_path.exists(), "readback failure left registry row");
4371
+ assert!(
4372
+ !registry_path.exists(),
4373
+ "readback failure left registry row"
4374
+ );
4269
4375
  }
4270
4376
 
4271
4377
  #[test]
@@ -4304,13 +4410,10 @@ mod fresh_quick_start_leader_binding_tests {
4304
4410
  break_registry_lock: false,
4305
4411
  break_registry_read: false,
4306
4412
  };
4307
- assert!(!bind_fresh_quick_start_leader_with(
4308
- &workspace,
4309
- "fresh",
4310
- Some(&seed),
4311
- &mut ops,
4312
- )
4313
- .unwrap());
4413
+ assert!(
4414
+ !bind_fresh_quick_start_leader_with(&workspace, "fresh", Some(&seed), &mut ops,)
4415
+ .unwrap()
4416
+ );
4314
4417
  let persisted = crate::state::persist::load_runtime_state(&workspace).unwrap();
4315
4418
  assert_eq!(
4316
4419
  persisted
@@ -4348,13 +4451,11 @@ mod fresh_quick_start_leader_binding_tests {
4348
4451
  #[test]
4349
4452
  #[serial_test::serial(env)]
4350
4453
  fn seeded_runtime_registry_rollback_errors_are_visible_after_state_cleanup() {
4351
- for (tag, break_registry_lock, break_registry_read) in [
4352
- ("lock", true, false),
4353
- ("read", false, true),
4354
- ] {
4355
- let hermetic = HermeticTestEnv::enter(&format!(
4356
- "runtime-seeded-registry-rollback-{tag}"
4357
- ));
4454
+ for (tag, break_registry_lock, break_registry_read) in
4455
+ [("lock", true, false), ("read", false, true)]
4456
+ {
4457
+ let hermetic =
4458
+ HermeticTestEnv::enter(&format!("runtime-seeded-registry-rollback-{tag}"));
4358
4459
  let workspace = runtime_workspace(&hermetic, "fresh");
4359
4460
  let parent = hermetic.root().join("parent");
4360
4461
  std::fs::create_dir_all(&parent).unwrap();
@@ -4387,13 +4488,9 @@ mod fresh_quick_start_leader_binding_tests {
4387
4488
  break_registry_lock,
4388
4489
  break_registry_read,
4389
4490
  };
4390
- let error = bind_fresh_quick_start_leader_with(
4391
- &workspace,
4392
- "fresh",
4393
- Some(&seed),
4394
- &mut ops,
4395
- )
4396
- .expect_err("registry rollback failure must be visible");
4491
+ let error =
4492
+ bind_fresh_quick_start_leader_with(&workspace, "fresh", Some(&seed), &mut ops)
4493
+ .expect_err("registry rollback failure must be visible");
4397
4494
  assert!(error
4398
4495
  .to_string()
4399
4496
  .contains("quick-start registry rollback failed"));
@@ -4477,7 +4574,10 @@ mod fresh_quick_start_leader_binding_tests {
4477
4574
  )
4478
4575
  .unwrap());
4479
4576
  assert_eq!(ops.last_failure_reason, Some(expected_reason));
4480
- assert_eq!(refusal_reason(&workspace).map(|(_, reason)| reason), Some(expected_reason.to_string()));
4577
+ assert_eq!(
4578
+ refusal_reason(&workspace).map(|(_, reason)| reason),
4579
+ Some(expected_reason.to_string())
4580
+ );
4481
4581
  let persisted = crate::state::persist::load_runtime_state(&workspace).unwrap();
4482
4582
  assert!(persisted
4483
4583
  .pointer("/teams/fresh/team_owner")
@@ -4501,12 +4601,10 @@ mod fresh_quick_start_leader_binding_tests {
4501
4601
  let _caller_pane = hermetic.with_env(CALLER_PANE_ENV, "%1");
4502
4602
  let _caller_endpoint = hermetic.with_env(CALLER_ENDPOINT_ENV, "/tmp/tmux.sock");
4503
4603
  let seed = seeded_runtime_owner(&workspace);
4504
- let mut state = crate::state::projection::resolve_runtime_team_scope(
4505
- &workspace,
4506
- Some("fresh"),
4507
- )
4508
- .unwrap()
4509
- .state;
4604
+ let mut state =
4605
+ crate::state::projection::resolve_runtime_team_scope(&workspace, Some("fresh"))
4606
+ .unwrap()
4607
+ .state;
4510
4608
  let expected_owner = state["team_owner"].clone();
4511
4609
  let expected_receiver = state["leader_receiver"].clone();
4512
4610
  let target = caller_target(parent.clone(), None);
@@ -4538,12 +4636,10 @@ mod fresh_quick_start_leader_binding_tests {
4538
4636
 
4539
4637
  let workspace = runtime_workspace(&hermetic, "writer-failure");
4540
4638
  let seed = seeded_runtime_owner(&workspace);
4541
- let mut state = crate::state::projection::resolve_runtime_team_scope(
4542
- &workspace,
4543
- Some("fresh"),
4544
- )
4545
- .unwrap()
4546
- .state;
4639
+ let mut state =
4640
+ crate::state::projection::resolve_runtime_team_scope(&workspace, Some("fresh"))
4641
+ .unwrap()
4642
+ .state;
4547
4643
  let expected_owner = state["team_owner"].clone();
4548
4644
  let expected_receiver = state["leader_receiver"].clone();
4549
4645
  let target = caller_target(hermetic.root().join("parent"), None);
@@ -4583,27 +4679,22 @@ mod fresh_quick_start_leader_binding_tests {
4583
4679
  let _caller_pane = hermetic.with_env(CALLER_PANE_ENV, "%1");
4584
4680
  let _caller_endpoint = hermetic.with_env(CALLER_ENDPOINT_ENV, "/tmp/tmux.sock");
4585
4681
  let seed = seeded_runtime_owner(&workspace);
4586
- let concurrent_writer = |_: &str,
4587
- _: &PaneId,
4588
- _: &str|
4589
- -> Result<String, crate::leader::LeaderError> {
4590
- let mut winner = crate::state::persist::load_runtime_state(&workspace)
4682
+ let concurrent_writer =
4683
+ |_: &str, _: &PaneId, _: &str| -> Result<String, crate::leader::LeaderError> {
4684
+ let mut winner = crate::state::persist::load_runtime_state(&workspace)
4685
+ .map_err(crate::leader::LeaderError::State)?;
4686
+ winner["teams"]["fresh"]["leader_receiver"]["pane_id"] = json!("%winner");
4687
+ crate::state::persist::save_runtime_state_with_receiver_authority(
4688
+ &workspace, &winner, "fresh", None,
4689
+ )
4591
4690
  .map_err(crate::leader::LeaderError::State)?;
4592
- winner["teams"]["fresh"]["leader_receiver"]["pane_id"] = json!("%winner");
4593
- crate::state::persist::save_runtime_state_with_receiver_authority(
4594
- &workspace,
4595
- &winner,
4596
- "fresh",
4597
- None,
4598
- )
4599
- .map_err(crate::leader::LeaderError::State)?;
4600
- let _ = crate::leader::registry::register_binding_from_state_best_effort(
4601
- &workspace,
4602
- Some("fresh"),
4603
- "concurrent",
4604
- );
4605
- Ok("writer-winner".to_string())
4606
- };
4691
+ let _ = crate::leader::registry::register_binding_from_state_best_effort(
4692
+ &workspace,
4693
+ Some("fresh"),
4694
+ "concurrent",
4695
+ );
4696
+ Ok("writer-winner".to_string())
4697
+ };
4607
4698
  let target = caller_target(parent, None);
4608
4699
  let transport = OfflineTransport::new()
4609
4700
  .with_tmux_endpoint("/tmp/tmux.sock")
@@ -4619,30 +4710,35 @@ mod fresh_quick_start_leader_binding_tests {
4619
4710
  frozen_receiver: None,
4620
4711
  nonce_writer: Some(&concurrent_writer),
4621
4712
  };
4622
- assert!(!bind_fresh_quick_start_leader_with(
4623
- &workspace,
4624
- "fresh",
4625
- Some(&seed),
4626
- &mut ops
4627
- )
4628
- .unwrap());
4713
+ assert!(
4714
+ !bind_fresh_quick_start_leader_with(&workspace, "fresh", Some(&seed), &mut ops)
4715
+ .unwrap()
4716
+ );
4629
4717
  assert!(ops.cas_conflict);
4630
4718
  assert_eq!(ops.last_failure_reason, Some("attach_cas_conflict"));
4631
4719
  let persisted = crate::state::persist::load_runtime_state(&workspace).unwrap();
4632
4720
  assert_eq!(
4633
- persisted.pointer("/teams/fresh/team_owner/pane_id").and_then(serde_json::Value::as_str),
4721
+ persisted
4722
+ .pointer("/teams/fresh/team_owner/pane_id")
4723
+ .and_then(serde_json::Value::as_str),
4634
4724
  Some("%1")
4635
4725
  );
4636
4726
  assert_eq!(
4637
- persisted.pointer("/teams/fresh/leader_receiver/pane_id").and_then(serde_json::Value::as_str),
4727
+ persisted
4728
+ .pointer("/teams/fresh/leader_receiver/pane_id")
4729
+ .and_then(serde_json::Value::as_str),
4638
4730
  Some("%winner")
4639
4731
  );
4640
4732
  assert_eq!(
4641
- persisted.pointer("/teams/fresh/team_owner/owner_epoch").and_then(serde_json::Value::as_u64),
4733
+ persisted
4734
+ .pointer("/teams/fresh/team_owner/owner_epoch")
4735
+ .and_then(serde_json::Value::as_u64),
4642
4736
  Some(1)
4643
4737
  );
4644
4738
  assert_eq!(
4645
- persisted.pointer("/teams/fresh/leader_receiver/owner_epoch").and_then(serde_json::Value::as_u64),
4739
+ persisted
4740
+ .pointer("/teams/fresh/leader_receiver/owner_epoch")
4741
+ .and_then(serde_json::Value::as_u64),
4646
4742
  Some(1)
4647
4743
  );
4648
4744
  let registry_path = crate::leader::registry::registry_dir()
@@ -4651,7 +4747,10 @@ mod fresh_quick_start_leader_binding_tests {
4651
4747
  "{}__fresh.json",
4652
4748
  crate::leader::registry::workspace_hash(&workspace)
4653
4749
  ));
4654
- assert!(registry_path.exists(), "concurrent winner registry was removed");
4750
+ assert!(
4751
+ registry_path.exists(),
4752
+ "concurrent winner registry was removed"
4753
+ );
4655
4754
  let winner_entry: crate::leader::registry::LeaderRegistryEntry =
4656
4755
  serde_json::from_slice(&std::fs::read(registry_path).unwrap()).unwrap();
4657
4756
  assert_eq!(winner_entry.channel["pane_id"], json!("%winner"));
@@ -4661,18 +4760,8 @@ mod fresh_quick_start_leader_binding_tests {
4661
4760
  #[serial_test::serial(env)]
4662
4761
  fn runtime_socket_and_explicit_conflicts_refuse_without_command_fallback() {
4663
4762
  for (tag, endpoint, leader, scoped) in [
4664
- (
4665
- "socket",
4666
- "/tmp/other.sock",
4667
- None,
4668
- "/tmp/tmux.sock",
4669
- ),
4670
- (
4671
- "scoped",
4672
- "/tmp/tmux.sock",
4673
- None,
4674
- "/tmp/product.sock",
4675
- ),
4763
+ ("socket", "/tmp/other.sock", None, "/tmp/tmux.sock"),
4764
+ ("scoped", "/tmp/tmux.sock", None, "/tmp/product.sock"),
4676
4765
  (
4677
4766
  // The explicit leader provider intentionally conflicts with the
4678
4767
  // caller provider; worker_env must reject this before command fallback.
@@ -4689,7 +4778,8 @@ mod fresh_quick_start_leader_binding_tests {
4689
4778
  let _provider = hermetic.with_env(CALLER_PROVIDER_ENV, "codex");
4690
4779
  let _caller_pane = hermetic.with_env(CALLER_PANE_ENV, "%1");
4691
4780
  let _caller_endpoint = hermetic.with_env(CALLER_ENDPOINT_ENV, endpoint);
4692
- let _leader = leader.map(|value| hermetic.with_env("TEAM_AGENT_LEADER_PROVIDER", value));
4781
+ let _leader =
4782
+ leader.map(|value| hermetic.with_env("TEAM_AGENT_LEADER_PROVIDER", value));
4693
4783
  let transport = OfflineTransport::new()
4694
4784
  .with_tmux_endpoint(scoped)
4695
4785
  .with_pane_current_command("%1", "codex");
@@ -4702,7 +4792,6 @@ mod fresh_quick_start_leader_binding_tests {
4702
4792
  }
4703
4793
  }
4704
4794
 
4705
-
4706
4795
  #[test]
4707
4796
  fn pi_tool_category_is_transparently_accepted_by_compiler() {
4708
4797
  let root = std::env::temp_dir().join(format!(
@@ -4729,9 +4818,9 @@ mod fresh_quick_start_leader_binding_tests {
4729
4818
  .get("agents")
4730
4819
  .and_then(Value::as_list)
4731
4820
  .and_then(|agents| {
4732
- agents.iter().find(|agent| {
4733
- agent.get("id").and_then(Value::as_str) == Some("worker")
4734
- })
4821
+ agents
4822
+ .iter()
4823
+ .find(|agent| agent.get("id").and_then(Value::as_str) == Some("worker"))
4735
4824
  })
4736
4825
  .expect("compiled spec must retain the worker role");
4737
4826
  assert!(
@@ -4745,8 +4834,7 @@ mod fresh_quick_start_leader_binding_tests {
4745
4834
  fn fresh_binding_persists_then_registers_then_requires_canonical_readback() {
4746
4835
  let workspace = workspace_with_provider("positive-pi", "pi");
4747
4836
  let mut ops = MockOps::with_provider("pi");
4748
- assert!(bind_fresh_quick_start_leader_with(&workspace, "fresh", None, &mut ops)
4749
- .unwrap());
4837
+ assert!(bind_fresh_quick_start_leader_with(&workspace, "fresh", None, &mut ops).unwrap());
4750
4838
  assert_eq!(ops.attached_provider, Some(crate::provider::Provider::Pi));
4751
4839
  assert_eq!(ops.attach_calls, 1);
4752
4840
  assert_eq!(ops.register_calls, 1);
@@ -4803,12 +4891,10 @@ mod fresh_quick_start_leader_binding_tests {
4803
4891
  let _caller_pane = hermetic.with_env(CALLER_PANE_ENV, "%1");
4804
4892
  let _caller_endpoint = hermetic.with_env(CALLER_ENDPOINT_ENV, "/tmp/tmux.sock");
4805
4893
  let seed = seeded_runtime_owner(&workspace);
4806
- let mut state = crate::state::projection::resolve_runtime_team_scope(
4807
- &workspace,
4808
- Some("fresh"),
4809
- )
4810
- .unwrap()
4811
- .state;
4894
+ let mut state =
4895
+ crate::state::projection::resolve_runtime_team_scope(&workspace, Some("fresh"))
4896
+ .unwrap()
4897
+ .state;
4812
4898
  let expected_owner = state["team_owner"].clone();
4813
4899
  let expected_receiver = state["leader_receiver"].clone();
4814
4900
  let target = caller_target(parent.clone(), None);
@@ -4840,12 +4926,10 @@ mod fresh_quick_start_leader_binding_tests {
4840
4926
 
4841
4927
  let workspace = runtime_workspace_with_provider(&hermetic, "writer-failure", "pi");
4842
4928
  let seed = seeded_runtime_owner(&workspace);
4843
- let mut state = crate::state::projection::resolve_runtime_team_scope(
4844
- &workspace,
4845
- Some("fresh"),
4846
- )
4847
- .unwrap()
4848
- .state;
4929
+ let mut state =
4930
+ crate::state::projection::resolve_runtime_team_scope(&workspace, Some("fresh"))
4931
+ .unwrap()
4932
+ .state;
4849
4933
  let expected_owner = state["team_owner"].clone();
4850
4934
  let expected_receiver = state["leader_receiver"].clone();
4851
4935
  let target = caller_target(hermetic.root().join("parent"), None);