mirror of
https://github.com/NousResearch/hermes-agent.git
synced 2026-07-15 14:22:43 +00:00
fix: descendant CTE must dedup (UNION) to survive parent-chain cycles
The #39140 CTE used UNION ALL, which recurses forever if a corrupted parent chain loops (a -> b -> a) — reproduced: query never returns. The old Python walk was cycle-safe via a seen-set. UNION dedups the working set and terminates. Regression test added and mutation-verified (UNION ALL hangs the test, UNION passes).
This commit is contained in:
parent
206c042392
commit
1e2ad17afd
2 changed files with 24 additions and 1 deletions
|
|
@ -9306,7 +9306,7 @@ def _session_latest_descendant(session_id: str, db):
|
|||
"""
|
||||
WITH RECURSIVE descendants(id, parent_session_id, started_at) AS (
|
||||
SELECT id, parent_session_id, started_at FROM sessions WHERE id = ?
|
||||
UNION ALL
|
||||
UNION
|
||||
SELECT s.id, s.parent_session_id, s.started_at
|
||||
FROM sessions s
|
||||
JOIN descendants d ON s.parent_session_id = d.id
|
||||
|
|
|
|||
|
|
@ -1138,6 +1138,29 @@ class TestWebServerEndpoints:
|
|||
assert worker_resp.status_code == 200
|
||||
assert worker_resp.json()["session_id"] == "worker-tip"
|
||||
|
||||
def test_latest_descendant_survives_parent_cycle(self):
|
||||
"""Regression for the #39140 CTE salvage: a corrupted parent chain
|
||||
that loops (a -> b -> a) must terminate (UNION dedup) instead of
|
||||
recursing forever like UNION ALL would."""
|
||||
from hermes_state import SessionDB
|
||||
|
||||
db = SessionDB()
|
||||
try:
|
||||
db.create_session(session_id="cyc-a", source="cli")
|
||||
db.create_session(
|
||||
session_id="cyc-b", source="cli", parent_session_id="cyc-a"
|
||||
)
|
||||
db._conn.execute(
|
||||
"UPDATE sessions SET parent_session_id='cyc-b' WHERE id='cyc-a'"
|
||||
)
|
||||
db._conn.commit()
|
||||
finally:
|
||||
db.close()
|
||||
|
||||
resp = self.client.get("/api/sessions/cyc-a/latest-descendant")
|
||||
assert resp.status_code == 200
|
||||
assert resp.json()["session_id"] == "cyc-b"
|
||||
|
||||
def test_analytics_endpoints_read_requested_profile(self):
|
||||
from hermes_state import SessionDB
|
||||
from hermes_cli import profiles as profiles_mod
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue