hive-agent: fix login-detection race with a fixed-baseline check (#3057)

This commit is contained in:
damocles 2026-08-11 20:43:34 +02:00 committed by mara
commit 8fd4e5d658
3 changed files with 114 additions and 134 deletions

View file

@ -612,7 +612,14 @@ async fn serve_main<S: Surface>(socket: &Path, poll_ms: u64) -> Result<()> {
let (todo_wake, todos_store) =
spawn_todo_socket(reminder_store.clone(), question_store.clone(), &bus);
if matches!(initial, LoginState::NeedsLogin) {
login::wait_for_login(&claude_dir, login_state.clone(), &bus, poll_ms).await;
login::wait_for_login(
&claude_dir,
login_state.clone(),
&bus,
poll_ms,
login::NO_PRIOR_FAILURE,
)
.await;
} else {
// Clear any stale `hyperhive-needs-login` sentinel left over
// from a prior boot — `online` status writes the sentinel
@ -792,11 +799,16 @@ async fn serve_loop<S: Surface>(
apply_todo_wake_checked(ctrl.todo_wake_checked, &mut todo_miss_streak, &bus);
if ctrl.auth_failed {
*login_state.lock().unwrap() = LoginState::NeedsLogin;
// Baseline the resume check on *this instant*, not on a
// directory snapshot taken after `wait_for_login` starts
// polling — closes the race where a login lands between the
// 401 and the first poll. See `wait_for_login`'s doc comment.
login::wait_for_login(
&claude_dir,
login_state.clone(),
&bus,
u64::try_from(interval.as_millis()).unwrap_or(2000),
std::time::SystemTime::now(),
)
.await;
}