diff --git a/harbor/core.py b/harbor/core.py index df81669..24905e0 100644 --- a/harbor/core.py +++ b/harbor/core.py @@ -990,7 +990,13 @@ class Harbor(WorkMixin, ExtrasMixin, FlowMixin, LaunchMixin): (by, origin, reason, now, key)) return False if current and current["value"] == "off" and value == "off" and not until_at and not current.get("until"): - return False + if by != self.human: + return False + # the human resuming one agent under a later 'stop everyone': record the time, so this resume is + # the most recent decision for that agent (decision() compares set_at) + c.execute("UPDATE flags SET set_by=?, origin=?, relay_of=NULL, set_at=? WHERE key=?", + (by, origin, now, key)) + return True c.execute("INSERT INTO flags(key, value, set_by, origin, relay_of, reason, set_at, until) VALUES (?,?,?,?,?,?,?,?) " "ON CONFLICT(key) DO UPDATE SET value=excluded.value, set_by=excluded.set_by, " "origin=excluded.origin, relay_of=excluded.relay_of, reason=excluded.reason, set_at=excluded.set_at, " diff --git a/tests/test_core.py b/tests/test_core.py index 0fa6fc1..aadbd5f 100644 --- a/tests/test_core.py +++ b/tests/test_core.py @@ -225,6 +225,19 @@ class Review(HarborCase): class Control(HarborCase): + def test_resume_one_agent_under_stop_all(self): + """Resuming one agent whose own flag is already off still overrides a later 'stop everyone'.""" + self.h.set_flag("stop:Claude", "off", "User", "web") + self.clock.t += 60 + self.h.set_flag("stop:all", "on", "User", "web") + self.assertTrue(self.h.stopped("Claude")) + self.clock.t += 60 + self.h.set_flag("stop:Claude", "off", "User", "web") + self.assertFalse(self.h.stopped("Claude")) + self.assertTrue(self.h.stopped("Codex")) + with self.assertRaises(HarborError): + self.h.set_flag("stop:Codex", "off", "Claude", "cli") # still the human's alone + def test_stop_and_resume_rules(self): with self.assertRaises(HarborError): self.h.set_flag("stop:all", "on", "User", "cli")