fix(supervisor): burst set/get via raw SQL, not new db helpers (host-lag-proof)
All checks were successful
G12 Leak-Guard / leak-guard (pull_request) Successful in 9s

The host pm2 supervisor imports legal_mcp.services.db from the host repo checkout,
which can lag main by many commits. Depending on the just-added db.set_drain_burst/
get_drain_burst would require the host checkout to be current. Use raw SQL via the
stable db.get_pool() instead — the supervisor now depends only on get_pool + the
drain_controls.burst_until column (the shared contract with the /operations API).
The container-side API keeps using the typed helpers (it ships the code in-image).

Invariants: G1/G2 unchanged (same single DB column, no parallel path).
This commit is contained in:
2026-06-12 11:16:38 +00:00
parent c7c402e7ef
commit 75a1b23972

View File

@@ -104,15 +104,28 @@ def db_snapshot() -> dict:
return json.loads(_venv_py(code).splitlines()[-1]) return json.loads(_venv_py(code).splitlines()[-1])
_SET_BURST_SQL = (
"INSERT INTO drain_controls (name, burst_until, updated_at) "
"VALUES ('legal-halacha-drain', $1, now()) "
"ON CONFLICT (name) DO UPDATE SET burst_until = $1, updated_at = now()"
)
def db_set_burst(until_iso): def db_set_burst(until_iso):
# Raw SQL via get_pool (NOT db.set_drain_burst): the host repo checkout can lag
# main, so the supervisor depends only on get_pool + the burst_until column —
# the column is the shared contract with the container-side /operations API.
code = ( code = (
"import sys,os,asyncio\n" "import sys,os,asyncio\n"
"sys.path.insert(0,'mcp-server/src'); os.environ.setdefault('HOME','/home/chaim')\n" "sys.path.insert(0,'mcp-server/src'); os.environ.setdefault('HOME','/home/chaim')\n"
"from datetime import datetime\n" "from datetime import datetime\n"
"from legal_mcp.services import db\n" "from legal_mcp.services import db\n"
f"v={until_iso!r}\n" f"v={until_iso!r}\n"
f"SQL={_SET_BURST_SQL!r}\n"
"async def m():\n" "async def m():\n"
" await db.set_drain_burst('legal-halacha-drain', datetime.fromisoformat(v) if v else None)\n" " pool=await db.get_pool()\n"
" async with pool.acquire() as c:\n"
" await c.execute(SQL, datetime.fromisoformat(v) if v else None)\n"
"asyncio.run(m())\n" "asyncio.run(m())\n"
) )
_venv_py(code, timeout=60) _venv_py(code, timeout=60)
@@ -124,7 +137,9 @@ def db_get_burst():
"sys.path.insert(0,'mcp-server/src'); os.environ.setdefault('HOME','/home/chaim')\n" "sys.path.insert(0,'mcp-server/src'); os.environ.setdefault('HOME','/home/chaim')\n"
"from legal_mcp.services import db\n" "from legal_mcp.services import db\n"
"async def m():\n" "async def m():\n"
" v=await db.get_drain_burst('legal-halacha-drain')\n" " pool=await db.get_pool()\n"
" async with pool.acquire() as c:\n"
" v=await c.fetchval(\"SELECT burst_until FROM drain_controls WHERE name='legal-halacha-drain'\")\n"
" print(v.isoformat() if v else '')\n" " print(v.isoformat() if v else '')\n"
"asyncio.run(m())\n" "asyncio.run(m())\n"
) )