Prompt:
Fixes #48

## Root cause

When Gitea goes down, the watchdog auto-files a `[watchdog] Gitea unreachable` issue. On the next orchestration cycle, `run_triage` picks it up as an unassigned issue and assigns it to an agent — which is wrong. The watchdog manages its own issues; the orchestrator should stay out.

Similarly, `run_stuck_detection` would ping the assigned agent on the watchdog issue if it sat idle too long.

## Fix

- Import `WATCHDOG_ISSUE_TITLE` from `timmy.watchdog` in `orchestrator.py`
- Filter watchdog issues out of `run_triage` unassigned list
- Skip watchdog issues in `run_stuck_detection` loop
- Added 2 new tests covering both filter paths (42 total, all passing)

Chosen response:
diff --git a/tests/test_timmy.py b/tests/test_timmy.py
index 53034e70..975f1f69 100644
--- a/tests/test_timmy.py
+++ b/tests/test_timmy.py
@@ -233,6 +233,15 @@ class TestOrchestratorTriage:
                 orch.run_triage()
         mock_triage.assert_not_called()

+    def test_skips_watchdog_issues(self):
+        from timmy.watchdog import WATCHDOG_ISSUE_TITLE
+        orch = self._make_orchestrator()
+        watchdog_issue = _issue(99, title=WATCHDOG_ISSUE_TITLE)
+        with patch.object(orch.gitea, "list_issues", return_value=[watchdog_issue]):
+            with patch("timmy.orchestrator.triage_issue") as mock_triage:
+                orch.run_triage()
+        mock_triage.assert_not_called()
+
     def test_assigns_unassigned_issue(self):
         orch = self._make_orchestrator(dry_run=False)
         issue = _issue(3)
@@ -367,6 +376,16 @@ class TestOrchestratorStuckDetection:
                 orch.run_stuck_detection()
         mock_comment.assert_not_called()

+    def test_skips_watchdog_issues(self):
+        from timmy.watchdog import WATCHDOG_ISSUE_TITLE
+        orch = self._make_orchestrator()
+        # Watchdog issue assigned to claude, sitting idle for years
+        issue = _issue(54, title=WATCHDOG_ISSUE_TITLE, assignees=[{"login": "claude"}])
+        issue["updated_at"] = "2020-01-01T00:00:00Z"
+        with patch.object(orch.gitea, "list_issues", return_value=[issue]):
+            with patch.object(orch.gitea, "add_issue_comment") as mock_comment:
+                orch.run_stuck_detection()
+        mock_comment.assert_not_called()

 # ---------------------------------------------------------------------------
 # TimmyOrchestrator — run_cycle error isolation
diff --git a/timmy/orchestrator.py b/timmy/orchestrator.py
index f0fb1922..a1f7fa4e 100644
--- a/timmy/orchestrator.py
+++ b/timmy/orchestrator.py
@@ -21,6 +21,7 @@ from datetime import datetime, timezone
 from typing import Optional

 from timmy.gitea_client import GiteaClient
+from timmy.watchdog import WATCHDOG_ISSUE_TITLE

 logger = logging.getLogger(__name__)

@@ -169,7 +170,12 @@ class TimmyOrchestrator:
         """Triage open unassigned issues and assign them to the best agent."""
         logger.info("[timmy] Running issue triage…")
         issues = self.gitea.list_issues(state="open", limit=50)
-        unassigned = [i for i in issues if not i.get("assignees") and not i.get("pull_request")]
+        unassigned = [
+            i for i in issues
+            if not i.get("assignees")
+            and not i.get("pull_request")
+            and i.get("title") != WATCHDOG_ISSUE_TITLE
+        ]
         logger.info("[timmy] %d unassigned issues found", len(unassigned))

         for issue in unassigned:
@@ -239,6 +245,8 @@ class TimmyOrchestrator:
         for issue in issues:
             if not issue.get("assignees"):
                 continue
+            if issue.get("title") == WATCHDOG_ISSUE_TITLE:
+                continue
             updated_raw = issue.get("updated_at") or issue.get("created_at", "")
             try:
                 updated = datetime.fromisoformat(updated_raw.replace("Z", "+00:00"))


Prompt:
Fixes #6

This PR adds a research document evaluating the feasibility of using OpenGauss HTAP capabilities for unified operational and analytical processing within the hermes-agent project.

Chosen response:
diff --git a/docs/htap_feasibility_research.md b/docs/htap_feasibility_research.md
new file mode 100644
index 00000000..2ca58e28
--- /dev/null
+++ b/docs/htap_feasibility_research.md
@@ -0,0 +1,45 @@
+# HTAP Feasibility Research: Unified Operational + Analytical Processing with OpenGauss
+
+## Objective
+Evaluate whether OpenGauss's HTAP capabilities can serve both real-time agent operations AND historical analysis from a single database instance, potentially eliminating separate analytics infrastructure or ETL pipelines for the `hermes-agent` project.
+
+## Research Summary
+
+OpenGauss is designed as a Hybrid Transactional/Analytical Processing (HTAP) database, leveraging a "fusion engine" that supports both row-store (optimized for OLTP) and column-store (optimized for OLAP) models. Users explicitly choose the storage model at table creation. While OpenGauss provides a Cost-Based Optimizer (CBO) and various performance enhancements (vectorized executor, parallel query, adaptive compression, partitioning) to efficiently handle diverse workloads, the "query routing" between OLTP and OLAP characteristics is primarily at the table design level rather than an automatic, dynamic routing mechanism within a single hybrid table.
+
+For handling JSONL-like data, OpenGauss effectively utilizes the `JSONB` data type, which stores JSON in a parsed binary format for efficient querying and indexing. JSONL files can be imported using the `COPY` command, with each line inserted as a `JSONB` object into a columnar table. For optimal analytical performance, it is recommended to extract frequently queried fields from `JSONB` into dedicated, appropriately typed columns.
+
+## Questions Answered
+
+### 1. Can we run agent loop retro analysis directly against the operational DB?
+**Yes, potentially.** OpenGauss's HTAP capabilities allow a single database instance to handle both OLTP and OLAP workloads. By designing tables with suitable storage (row-store for operational, column-store or `JSONB` with extracted fields for analytical data), retro analysis can be performed directly against the operational database. Careful table design is essential for performance.
+
+### 2. What is the performance impact of analytical queries on OLTP operations?
+**Potential impact, but manageable with proper design and tuning.** The impact depends on:
+*   **Table Storage Choice:** Heavy analytical queries on row-store tables can affect OLTP performance. Utilizing column-store tables, partitioning, or extracting analytical data into separate columns minimizes this.
+*   **Query Optimization:** OpenGauss's CBO, vectorized execution, and parallel query features are designed to mitigate performance bottlenecks.
+*   **Resource Management:** Proper resource allocation, database tuning, and effective workload separation through schema design are crucial.
+
+### 3. Does the fusion engine correctly route queries without application changes?
+**No, "routing" is primarily based on table storage definition, not dynamic internal routing.** The fusion engine facilitates hybrid storage where row-store and column-store tables coexist. Queries are optimized based on the storage type of the tables they access. Existing application queries targeting OLTP tables will not automatically benefit from columnar optimizations unless the underlying tables are converted to columnar or new analytical queries are specifically designed for columnar structures. Application changes would likely be necessary to fully leverage columnar storage for analytical workloads.
+
+### 4. Can columnar storage handle the loop cycle/triage data currently in JSONL files?
+**Yes, effectively.** OpenGauss can store JSONL data by importing each line as a `JSONB` object into a columnar table. To achieve optimal analytical performance, it is highly recommended to extract frequently queried fields from the `JSONB` data into dedicated, appropriately typed columns within the columnar table.
+
+## Cost/Benefit Analysis
+
+### Potential Value (Benefits of Unified HTAP with OpenGauss):
+*   **Data Consolidation:** Eliminates `.loop/retro/*.jsonl` files and separate SQLite databases; all data resides in a single, unified database.
+*   **Real-time Analytics:** Enables real-time dashboards and insights directly against live agent data, as there are no ETL delays or stale data.
+*   **Simplified Architecture:** Reduces system complexity by removing the need for separate analytical infrastructure, ETL pipelines, and data synchronization processes.
+*   **Advanced Querying:** Leverages OpenGauss's powerful SQL capabilities and optimizations for more complex analytical tasks than file-based or SQLite solutions.
+
+### Costs/Considerations of Unified HTAP with OpenGauss:
+*   **Learning Curve:** Requires an initial investment in understanding OpenGauss's HTAP features, especially optimal table design and query tuning for hybrid workloads.
+*   **Migration Effort:** Significant effort will be needed to migrate existing JSONL data and potentially refactor application queries to effectively utilize `JSONB` and columnar storage.
+*   **Performance Tuning:** Continuous monitoring and tuning will be necessary to balance OLTP and OLAP workloads and prevent resource contention.
+*   **Resource Requirements:** A single HTAP instance handling both heavy OLTP and OLAP might demand more substantial hardware resources compared to separate, specialized systems.
+*   **Schema Design Complexity:** Designing a robust schema that efficiently supports both operational and analytical requirements (e.g., deciding on `JSONB` usage, extracted columns, and row/column store types) can be intricate.
+
+### Conclusion of Cost/Benefit:
+The adoption of OpenGauss HTAP offers compelling advantages in terms of data consistency, real-time analytics, and architectural simplification. The elimination of ETL and separate analytical stores can significantly streamline data management for the `hermes-agent` project. However, these benefits are balanced by the upfront costs of migration, the learning curve, and the ongoing need for careful design and performance tuning. Given the high value proposition of real-time insights and simplified data management, this approach warrants further exploration and potentially a proof-of-concept implementation to validate performance and architectural fit.