Require complete router configuration before veto

This commit is contained in:
acamilo 2026-09-26 01:23:31 +00:00
parent dccc52ae1c
commit 1bd2223431
3 changed files with 11 additions and 3 deletions

View file

@ -17,8 +17,10 @@ COOLDOWN = 3600
def verdict(report):
url = os.environ.get("FLY_LOOP_ROUTER_URL")
model = os.environ.get("FLY_LOOP_MODEL")
if not url or not model:
if not url and not model:
return True
if not url or not model:
return False
payload = {"model": model, "temperature": 0, "messages": [
{"role": "system", "content": "Classify whether a suspected repeating game macro loop is truly stuck. Return only JSON {\"stuck\":true|false}. No instructions or commands."},
{"role": "user", "content": json.dumps({key: report.get(key) for key in ("reason", "sequence", "window", "places", "milestone")})},

View file

@ -18,8 +18,8 @@ containing `FLY_LOOP_ROUTER_URL` (base URL ending in `/v1`) and
`FLY_LOOP_MODEL` (an available free-tier model). A private router can additionally
use `FLY_LOOP_ROUTER_KEY`; provision it outside this public checkout and limit
file permissions to `0640 root:fly`. Never put credentials in the unit or the
repository. When a router is configured, malformed or unavailable responses
prevent recovery; the model may only return `{"stuck": true|false}` and cannot
repository. When either router setting is present, both must be set; malformed or
unavailable responses prevent recovery. The model may only return `{"stuck": true|false}` and cannot
choose commands, buttons, or checkpoint paths. Confirm the model actually
exists and is reachable from the release container before configuring it.

View file

@ -76,6 +76,12 @@ class RecoveryTests(unittest.TestCase):
self.assertIn("did not confirm", recover.run(1300))
restart.assert_not_called()
def test_partial_router_configuration_cannot_bypass_veto(self):
with patch.dict("os.environ", {"FLY_LOOP_ROUTER_URL": "http://router/v1"}, clear=True):
self.assertFalse(recover.verdict(self.report))
with patch.dict("os.environ", {"FLY_LOOP_MODEL": "free"}, clear=True):
self.assertFalse(recover.verdict(self.report))
def test_unconfigured_router_uses_deterministic_confirmation(self):
with patch.dict("os.environ", {}, clear=True):
self.assertTrue(recover.verdict(self.report))