"""Shared isolated database fixture for Hermes execution-safety regressions.""" from __future__ import annotations import json import os import sys import tempfile import unittest from pathlib import Path from types import SimpleNamespace from unittest import mock _HERMES_HOME = tempfile.TemporaryDirectory(prefix="hermes-execution-test-home-") os.environ["HERMES_HOME"] = _HERMES_HOME.name _LANE_SOURCE = Path( os.environ.get("HERMES_CLI_LANE_SOURCE", "/tmp/hermes-lane-regression") ) sys.path.insert(0, str(_LANE_SOURCE)) from agent import auxiliary_client # noqa: E402 from cli_lane_config import TerminalIdentity # noqa: E402 from cli_lane_finalization import _finalize_document_db # noqa: E402 from hermes_cli import kanban_db # noqa: E402 from hermes_cli import kanban_decompose # noqa: E402 __all__ = ("ExecutionSafetyTestCase", "TerminalIdentity", "_finalize_document_db") class _FakeCompletions: def __init__(self, payload: dict, before_response=None) -> None: self.payload = payload self.before_response = before_response self.calls = 0 def create(self, **_kwargs): self.calls += 1 if self.before_response is not None: self.before_response() return SimpleNamespace( choices=[ SimpleNamespace( message=SimpleNamespace(content=json.dumps(self.payload)) ) ] ) class _FakeClient: def __init__(self, completions: _FakeCompletions) -> None: self.chat = SimpleNamespace(completions=completions) class ExecutionSafetyTestCase(unittest.TestCase): """Exercise patched upstream APIs against an isolated real database.""" def setUp(self) -> None: self.connection = kanban_db.connect() self.patches = [ mock.patch.object( kanban_decompose, "_build_roster", return_value=([], {"default"}), ), mock.patch.object( kanban_decompose, "_load_config", return_value={"kanban": {"auto_promote_children": True}}, ), mock.patch.object( auxiliary_client, "get_auxiliary_extra_body", return_value={}, ), ] for patch in self.patches: patch.start() def tearDown(self) -> None: for patch in reversed(self.patches): patch.stop() self.connection.close() def _client(self, payload: dict, before_response=None) -> _FakeCompletions: completions = _FakeCompletions(payload, before_response) client = _FakeClient(completions) patch = mock.patch.object( auxiliary_client, "get_text_auxiliary_client", return_value=(client, "test-decomposer"), ) patch.start() self.addCleanup(patch.stop) return completions def _status(self, task_id: str) -> str: task = kanban_db.get_task(self.connection, task_id) self.assertIsNotNone(task) return task.status def _route_executed_task_to_triage(self) -> str: task_id = kanban_db.create_task( self.connection, title="already implemented parent", ) for attempt in range(kanban_db.BLOCK_RECURRENCE_LIMIT): if attempt: self.assertTrue(kanban_db.unblock_task(self.connection, task_id)) self.assertIsNotNone(kanban_db.claim_task(self.connection, task_id)) self.assertTrue( kanban_db.block_task( self.connection, task_id, reason="same unavailable capability", kind="capability", ) ) self.assertEqual(self._status(task_id), "triage") self.assertEqual( len(kanban_db.list_runs(self.connection, task_id)), kanban_db.BLOCK_RECURRENCE_LIMIT, ) return task_id def _insert_run(self, task_id: str) -> None: with kanban_db.connect_closing() as connection: kanban_db._synthesize_ended_run( connection, task_id, outcome="reclaimed", summary="concurrent execution evidence", )