Require complete router configuration before veto
This commit is contained in:
parent
dccc52ae1c
commit
1bd2223431
3 changed files with 11 additions and 3 deletions
|
|
@ -17,8 +17,10 @@ COOLDOWN = 3600
|
||||||
def verdict(report):
|
def verdict(report):
|
||||||
url = os.environ.get("FLY_LOOP_ROUTER_URL")
|
url = os.environ.get("FLY_LOOP_ROUTER_URL")
|
||||||
model = os.environ.get("FLY_LOOP_MODEL")
|
model = os.environ.get("FLY_LOOP_MODEL")
|
||||||
if not url or not model:
|
if not url and not model:
|
||||||
return True
|
return True
|
||||||
|
if not url or not model:
|
||||||
|
return False
|
||||||
payload = {"model": model, "temperature": 0, "messages": [
|
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": "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")})},
|
{"role": "user", "content": json.dumps({key: report.get(key) for key in ("reason", "sequence", "window", "places", "milestone")})},
|
||||||
|
|
|
||||||
|
|
@ -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
|
`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
|
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
|
file permissions to `0640 root:fly`. Never put credentials in the unit or the
|
||||||
repository. When a router is configured, malformed or unavailable responses
|
repository. When either router setting is present, both must be set; malformed or
|
||||||
prevent recovery; the model may only return `{"stuck": true|false}` and cannot
|
unavailable responses prevent recovery. The model may only return `{"stuck": true|false}` and cannot
|
||||||
choose commands, buttons, or checkpoint paths. Confirm the model actually
|
choose commands, buttons, or checkpoint paths. Confirm the model actually
|
||||||
exists and is reachable from the release container before configuring it.
|
exists and is reachable from the release container before configuring it.
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -76,6 +76,12 @@ class RecoveryTests(unittest.TestCase):
|
||||||
self.assertIn("did not confirm", recover.run(1300))
|
self.assertIn("did not confirm", recover.run(1300))
|
||||||
restart.assert_not_called()
|
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):
|
def test_unconfigured_router_uses_deterministic_confirmation(self):
|
||||||
with patch.dict("os.environ", {}, clear=True):
|
with patch.dict("os.environ", {}, clear=True):
|
||||||
self.assertTrue(recover.verdict(self.report))
|
self.assertTrue(recover.verdict(self.report))
|
||||||
|
|
|
||||||
Loading…
Add table
Reference in a new issue