Skip to main content

DASHBOARD_JSON

Constant DASHBOARD_JSON 

Source
pub const DASHBOARD_JSON: &str = "{\n  \"panels\": [\n    {\n      \"collapsed\": false,\n      \"gridPos\": {\n        \"h\": 1,\n        \"w\": 24,\n        \"x\": 0,\n        \"y\": 0\n      },\n      \"id\": 100,\n      \"title\": \"Session Overview\",\n      \"type\": \"row\"\n    },\n    {\n      \"datasource\": {\n        \"type\": \"frser-sqlite-datasource\",\n        \"uid\": \"batty-telemetry\"\n      },\n      \"fieldConfig\": {\n        \"defaults\": {\n          \"thresholds\": {\n            \"steps\": [\n              {\n                \"color\": \"green\",\n                \"value\": null\n              }\n            ]\n          }\n        }\n      },\n      \"gridPos\": {\n        \"h\": 4,\n        \"w\": 4,\n        \"x\": 0,\n        \"y\": 1\n      },\n      \"id\": 1,\n      \"targets\": [\n        {\n          \"datasource\": {\n            \"type\": \"frser-sqlite-datasource\",\n            \"uid\": \"batty-telemetry\"\n          },\n          \"queryText\": \"SELECT COUNT(*) as value FROM events;\",\n          \"queryType\": \"table\",\n          \"rawQueryText\": \"SELECT COUNT(*) as value FROM events;\",\n          \"rawSql\": \"SELECT COUNT(*) as value FROM events;\",\n          \"refId\": \"A\"\n        }\n      ],\n      \"title\": \"Total Events\",\n      \"type\": \"stat\"\n    },\n    {\n      \"datasource\": {\n        \"type\": \"frser-sqlite-datasource\",\n        \"uid\": \"batty-telemetry\"\n      },\n      \"fieldConfig\": {\n        \"defaults\": {\n          \"thresholds\": {\n            \"steps\": [\n              {\n                \"color\": \"green\",\n                \"value\": null\n              }\n            ]\n          }\n        }\n      },\n      \"gridPos\": {\n        \"h\": 4,\n        \"w\": 4,\n        \"x\": 4,\n        \"y\": 1\n      },\n      \"id\": 2,\n      \"targets\": [\n        {\n          \"datasource\": {\n            \"type\": \"frser-sqlite-datasource\",\n            \"uid\": \"batty-telemetry\"\n          },\n          \"queryText\": \"SELECT COUNT(*) as value FROM events WHERE event_type=\'task_completed\';\",\n          \"queryType\": \"table\",\n          \"rawQueryText\": \"SELECT COUNT(*) as value FROM events WHERE event_type=\'task_completed\';\",\n          \"rawSql\": \"SELECT COUNT(*) as value FROM events WHERE event_type=\'task_completed\';\",\n          \"refId\": \"A\"\n        }\n      ],\n      \"title\": \"Tasks Completed\",\n      \"type\": \"stat\"\n    },\n    {\n      \"datasource\": {\n        \"type\": \"frser-sqlite-datasource\",\n        \"uid\": \"batty-telemetry\"\n      },\n      \"fieldConfig\": {\n        \"defaults\": {\n          \"thresholds\": {\n            \"steps\": [\n              {\n                \"color\": \"green\",\n                \"value\": null\n              }\n            ]\n          }\n        }\n      },\n      \"gridPos\": {\n        \"h\": 4,\n        \"w\": 4,\n        \"x\": 8,\n        \"y\": 1\n      },\n      \"id\": 3,\n      \"targets\": [\n        {\n          \"datasource\": {\n            \"type\": \"frser-sqlite-datasource\",\n            \"uid\": \"batty-telemetry\"\n          },\n          \"queryText\": \"SELECT COUNT(*) as value FROM events WHERE event_type=\'task_auto_merged\';\",\n          \"queryType\": \"table\",\n          \"rawQueryText\": \"SELECT COUNT(*) as value FROM events WHERE event_type=\'task_auto_merged\';\",\n          \"rawSql\": \"SELECT COUNT(*) as value FROM events WHERE event_type=\'task_auto_merged\';\",\n          \"refId\": \"A\"\n        }\n      ],\n      \"title\": \"Auto-Merged\",\n      \"type\": \"stat\"\n    },\n    {\n      \"datasource\": {\n        \"type\": \"frser-sqlite-datasource\",\n        \"uid\": \"batty-telemetry\"\n      },\n      \"fieldConfig\": {\n        \"defaults\": {\n          \"thresholds\": {\n            \"steps\": [\n              {\n                \"color\": \"green\",\n                \"value\": null\n              }\n            ]\n          }\n        }\n      },\n      \"gridPos\": {\n        \"h\": 4,\n        \"w\": 4,\n        \"x\": 12,\n        \"y\": 1\n      },\n      \"id\": 4,\n      \"targets\": [\n        {\n          \"datasource\": {\n            \"type\": \"frser-sqlite-datasource\",\n            \"uid\": \"batty-telemetry\"\n          },\n          \"queryText\": \"SELECT COALESCE(SUM(discord_events_sent), 0) as value FROM session_summary;\",\n          \"queryType\": \"table\",\n          \"rawQueryText\": \"SELECT COALESCE(SUM(discord_events_sent), 0) as value FROM session_summary;\",\n          \"rawSql\": \"SELECT COALESCE(SUM(discord_events_sent), 0) as value FROM session_summary;\",\n          \"refId\": \"A\"\n        }\n      ],\n      \"title\": \"Discord Events Sent\",\n      \"type\": \"stat\"\n    },\n    {\n      \"datasource\": {\n        \"type\": \"frser-sqlite-datasource\",\n        \"uid\": \"batty-telemetry\"\n      },\n      \"fieldConfig\": {\n        \"defaults\": {\n          \"thresholds\": {\n            \"steps\": [\n              {\n                \"color\": \"red\",\n                \"value\": null\n              }\n            ]\n          }\n        }\n      },\n      \"gridPos\": {\n        \"h\": 4,\n        \"w\": 4,\n        \"x\": 16,\n        \"y\": 1\n      },\n      \"id\": 5,\n      \"targets\": [\n        {\n          \"datasource\": {\n            \"type\": \"frser-sqlite-datasource\",\n            \"uid\": \"batty-telemetry\"\n          },\n          \"queryText\": \"SELECT COUNT(*) as value FROM task_metrics tm WHERE tm.completed_at IS NOT NULL AND NOT EXISTS (SELECT 1 FROM events e WHERE e.task_id = tm.task_id AND e.event_type IN (\'task_auto_merged\', \'task_manual_merged\', \'task_reworked\') AND e.timestamp >= tm.completed_at);\",\n          \"queryType\": \"table\",\n          \"rawQueryText\": \"SELECT COUNT(*) as value FROM task_metrics tm WHERE tm.completed_at IS NOT NULL AND NOT EXISTS (SELECT 1 FROM events e WHERE e.task_id = tm.task_id AND e.event_type IN (\'task_auto_merged\', \'task_manual_merged\', \'task_reworked\') AND e.timestamp >= tm.completed_at);\",\n          \"rawSql\": \"SELECT COUNT(*) as value FROM task_metrics tm WHERE tm.completed_at IS NOT NULL AND NOT EXISTS (SELECT 1 FROM events e WHERE e.task_id = tm.task_id AND e.event_type IN (\'task_auto_merged\', \'task_manual_merged\', \'task_reworked\') AND e.timestamp >= tm.completed_at);\",\n          \"refId\": \"A\"\n        }\n      ],\n      \"title\": \"Merge Queue Depth\",\n      \"type\": \"stat\"\n    },\n    {\n      \"datasource\": {\n        \"type\": \"frser-sqlite-datasource\",\n        \"uid\": \"batty-telemetry\"\n      },\n      \"fieldConfig\": {\n        \"defaults\": {\n          \"thresholds\": {\n            \"steps\": [\n              {\n                \"color\": \"green\",\n                \"value\": null\n              }\n            ]\n          }\n        }\n      },\n      \"gridPos\": {\n        \"h\": 4,\n        \"w\": 4,\n        \"x\": 20,\n        \"y\": 1\n      },\n      \"id\": 6,\n      \"targets\": [\n        {\n          \"datasource\": {\n            \"type\": \"frser-sqlite-datasource\",\n            \"uid\": \"batty-telemetry\"\n          },\n          \"queryText\": \"SELECT ROUND(MAX(json_extract(payload, \'$.uptime_secs\')) / 3600.0, 1) as value FROM events WHERE event_type=\'daemon_heartbeat\';\",\n          \"queryType\": \"table\",\n          \"rawQueryText\": \"SELECT ROUND(MAX(json_extract(payload, \'$.uptime_secs\')) / 3600.0, 1) as value FROM events WHERE event_type=\'daemon_heartbeat\';\",\n          \"rawSql\": \"SELECT ROUND(MAX(json_extract(payload, \'$.uptime_secs\')) / 3600.0, 1) as value FROM events WHERE event_type=\'daemon_heartbeat\';\",\n          \"refId\": \"A\"\n        }\n      ],\n      \"title\": \"Uptime (hrs)\",\n      \"type\": \"stat\"\n    },\n    {\n      \"collapsed\": false,\n      \"gridPos\": {\n        \"h\": 1,\n        \"w\": 24,\n        \"x\": 0,\n        \"y\": 5\n      },\n      \"id\": 101,\n      \"title\": \"Pipeline Health\",\n      \"type\": \"row\"\n    },\n    {\n      \"datasource\": {\n        \"type\": \"frser-sqlite-datasource\",\n        \"uid\": \"batty-telemetry\"\n      },\n      \"fieldConfig\": {\n        \"defaults\": {\n          \"max\": 100,\n          \"min\": 0,\n          \"thresholds\": {\n            \"steps\": [\n              {\n                \"color\": \"red\",\n                \"value\": null\n              },\n              {\n                \"color\": \"yellow\",\n                \"value\": 50\n              },\n              {\n                \"color\": \"green\",\n                \"value\": 80\n              }\n            ]\n          }\n        }\n      },\n      \"gridPos\": {\n        \"h\": 4,\n        \"w\": 6,\n        \"x\": 0,\n        \"y\": 6\n      },\n      \"id\": 7,\n      \"targets\": [\n        {\n          \"datasource\": {\n            \"type\": \"frser-sqlite-datasource\",\n            \"uid\": \"batty-telemetry\"\n          },\n          \"queryText\": \"SELECT ROUND(1.0 * SUM(notification_latency_total_secs) / NULLIF(SUM(notification_latency_samples), 0), 1) as value FROM session_summary;\",\n          \"queryType\": \"table\",\n          \"rawQueryText\": \"SELECT ROUND(1.0 * SUM(notification_latency_total_secs) / NULLIF(SUM(notification_latency_samples), 0), 1) as value FROM session_summary;\",\n          \"rawSql\": \"SELECT ROUND(1.0 * SUM(notification_latency_total_secs) / NULLIF(SUM(notification_latency_samples), 0), 1) as value FROM session_summary;\",\n          \"refId\": \"A\"\n        }\n      ],\n      \"title\": \"Notification Delivery Latency\",\n      \"type\": \"gauge\"\n    },\n    {\n      \"datasource\": {\n        \"type\": \"frser-sqlite-datasource\",\n        \"uid\": \"batty-telemetry\"\n      },\n      \"fieldConfig\": {\n        \"defaults\": {\n          \"max\": 100,\n          \"min\": 0,\n          \"thresholds\": {\n            \"steps\": [\n              {\n                \"color\": \"red\",\n                \"value\": null\n              },\n              {\n                \"color\": \"yellow\",\n                \"value\": 50\n              },\n              {\n                \"color\": \"green\",\n                \"value\": 80\n              }\n            ]\n          }\n        }\n      },\n      \"gridPos\": {\n        \"h\": 4,\n        \"w\": 6,\n        \"x\": 6,\n        \"y\": 6\n      },\n      \"id\": 8,\n      \"targets\": [\n        {\n          \"datasource\": {\n            \"type\": \"frser-sqlite-datasource\",\n            \"uid\": \"batty-telemetry\"\n          },\n          \"queryText\": \"SELECT ROUND(100.0 * CAST((SELECT COUNT(*) FROM events WHERE event_type=\'task_auto_merged\') AS REAL) / MAX(1, (SELECT COUNT(*) FROM events WHERE event_type=\'task_completed\')), 1) as value;\",\n          \"queryType\": \"table\",\n          \"rawQueryText\": \"SELECT ROUND(100.0 * CAST((SELECT COUNT(*) FROM events WHERE event_type=\'task_auto_merged\') AS REAL) / MAX(1, (SELECT COUNT(*) FROM events WHERE event_type=\'task_completed\')), 1) as value;\",\n          \"rawSql\": \"SELECT ROUND(100.0 * CAST((SELECT COUNT(*) FROM events WHERE event_type=\'task_auto_merged\') AS REAL) / MAX(1, (SELECT COUNT(*) FROM events WHERE event_type=\'task_completed\')), 1) as value;\",\n          \"refId\": \"A\"\n        }\n      ],\n      \"title\": \"Auto-Merge Rate\",\n      \"type\": \"gauge\"\n    },\n    {\n      \"datasource\": {\n        \"type\": \"frser-sqlite-datasource\",\n        \"uid\": \"batty-telemetry\"\n      },\n      \"fieldConfig\": {\n        \"defaults\": {\n          \"max\": 100,\n          \"min\": 0,\n          \"thresholds\": {\n            \"steps\": [\n              {\n                \"color\": \"red\",\n                \"value\": null\n              },\n              {\n                \"color\": \"yellow\",\n                \"value\": 50\n              },\n              {\n                \"color\": \"green\",\n                \"value\": 80\n              }\n            ]\n          }\n        }\n      },\n      \"gridPos\": {\n        \"h\": 4,\n        \"w\": 6,\n        \"x\": 12,\n        \"y\": 6\n      },\n      \"id\": 9,\n      \"targets\": [\n        {\n          \"datasource\": {\n            \"type\": \"frser-sqlite-datasource\",\n            \"uid\": \"batty-telemetry\"\n          },\n          \"queryText\": \"SELECT ROUND(100.0 * CAST((SELECT COUNT(*) FROM events WHERE event_type=\'task_completed\') AS REAL) / MAX(1, (SELECT COUNT(*) FROM events WHERE event_type=\'task_assigned\')), 1) as value;\",\n          \"queryType\": \"table\",\n          \"rawQueryText\": \"SELECT ROUND(100.0 * CAST((SELECT COUNT(*) FROM events WHERE event_type=\'task_completed\') AS REAL) / MAX(1, (SELECT COUNT(*) FROM events WHERE event_type=\'task_assigned\')), 1) as value;\",\n          \"rawSql\": \"SELECT ROUND(100.0 * CAST((SELECT COUNT(*) FROM events WHERE event_type=\'task_completed\') AS REAL) / MAX(1, (SELECT COUNT(*) FROM events WHERE event_type=\'task_assigned\')), 1) as value;\",\n          \"refId\": \"A\"\n        }\n      ],\n      \"title\": \"Completion Rate\",\n      \"type\": \"gauge\"\n    },\n    {\n      \"datasource\": {\n        \"type\": \"frser-sqlite-datasource\",\n        \"uid\": \"batty-telemetry\"\n      },\n      \"fieldConfig\": {\n        \"defaults\": {\n          \"max\": 100,\n          \"min\": 0,\n          \"thresholds\": {\n            \"steps\": [\n              {\n                \"color\": \"red\",\n                \"value\": null\n              },\n              {\n                \"color\": \"yellow\",\n                \"value\": 50\n              },\n              {\n                \"color\": \"green\",\n                \"value\": 80\n              }\n            ]\n          }\n        }\n      },\n      \"gridPos\": {\n        \"h\": 4,\n        \"w\": 6,\n        \"x\": 18,\n        \"y\": 6\n      },\n      \"id\": 10,\n      \"targets\": [\n        {\n          \"datasource\": {\n            \"type\": \"frser-sqlite-datasource\",\n            \"uid\": \"batty-telemetry\"\n          },\n          \"queryText\": \"SELECT ROUND(100.0 * (1.0 - CAST((SELECT COUNT(*) FROM events WHERE event_type=\'member_crashed\') AS REAL) / MAX(1, (SELECT COUNT(*) FROM events WHERE event_type=\'agent_spawned\'))), 1) as value;\",\n          \"queryType\": \"table\",\n          \"rawQueryText\": \"SELECT ROUND(100.0 * (1.0 - CAST((SELECT COUNT(*) FROM events WHERE event_type=\'member_crashed\') AS REAL) / MAX(1, (SELECT COUNT(*) FROM events WHERE event_type=\'agent_spawned\'))), 1) as value;\",\n          \"rawSql\": \"SELECT ROUND(100.0 * (1.0 - CAST((SELECT COUNT(*) FROM events WHERE event_type=\'member_crashed\') AS REAL) / MAX(1, (SELECT COUNT(*) FROM events WHERE event_type=\'agent_spawned\'))), 1) as value;\",\n          \"refId\": \"A\"\n        }\n      ],\n      \"title\": \"Agent Survival\",\n      \"type\": \"gauge\"\n    },\n    {\n      \"collapsed\": false,\n      \"gridPos\": {\n        \"h\": 1,\n        \"w\": 24,\n        \"x\": 0,\n        \"y\": 10\n      },\n      \"id\": 102,\n      \"title\": \"Activity Over Time\",\n      \"type\": \"row\"\n    },\n    {\n      \"datasource\": {\n        \"type\": \"frser-sqlite-datasource\",\n        \"uid\": \"batty-telemetry\"\n      },\n      \"fieldConfig\": {\n        \"defaults\": {\n          \"custom\": {\n            \"fillOpacity\": 10,\n            \"lineWidth\": 2\n          }\n        }\n      },\n      \"gridPos\": {\n        \"h\": 8,\n        \"w\": 12,\n        \"x\": 0,\n        \"y\": 11\n      },\n      \"id\": 11,\n      \"targets\": [\n        {\n          \"datasource\": {\n            \"type\": \"frser-sqlite-datasource\",\n            \"uid\": \"batty-telemetry\"\n          },\n          \"queryText\": \"WITH RECURSIVE hours(h) AS (\\n  SELECT MIN(timestamp) / 3600 FROM events\\n  UNION ALL\\n  SELECT h + 1 FROM hours WHERE h < (SELECT MAX(timestamp) / 3600 FROM events)\\n) SELECT h * 3600 as time, COALESCE(e.cnt, 0) as events FROM hours LEFT JOIN (SELECT timestamp / 3600 as hr, COUNT(*) as cnt FROM events GROUP BY hr) e ON hours.h = e.hr ORDER BY time;\",\n          \"queryType\": \"table\",\n          \"rawQueryText\": \"WITH RECURSIVE hours(h) AS (\\n  SELECT MIN(timestamp) / 3600 FROM events\\n  UNION ALL\\n  SELECT h + 1 FROM hours WHERE h < (SELECT MAX(timestamp) / 3600 FROM events)\\n) SELECT h * 3600 as time, COALESCE(e.cnt, 0) as events FROM hours LEFT JOIN (SELECT timestamp / 3600 as hr, COUNT(*) as cnt FROM events GROUP BY hr) e ON hours.h = e.hr ORDER BY time;\",\n          \"rawSql\": \"WITH RECURSIVE hours(h) AS (\\n  SELECT MIN(timestamp) / 3600 FROM events\\n  UNION ALL\\n  SELECT h + 1 FROM hours WHERE h < (SELECT MAX(timestamp) / 3600 FROM events)\\n) SELECT h * 3600 as time, COALESCE(e.cnt, 0) as events FROM hours LEFT JOIN (SELECT timestamp / 3600 as hr, COUNT(*) as cnt FROM events GROUP BY hr) e ON hours.h = e.hr ORDER BY time;\",\n          \"refId\": \"A\",\n          \"timeColumns\": [\n            \"time\"\n          ]\n        }\n      ],\n      \"title\": \"Events Per Hour\",\n      \"type\": \"timeseries\"\n    },\n    {\n      \"datasource\": {\n        \"type\": \"frser-sqlite-datasource\",\n        \"uid\": \"batty-telemetry\"\n      },\n      \"fieldConfig\": {\n        \"defaults\": {\n          \"custom\": {\n            \"fillOpacity\": 10,\n            \"lineWidth\": 2\n          }\n        }\n      },\n      \"gridPos\": {\n        \"h\": 8,\n        \"w\": 12,\n        \"x\": 12,\n        \"y\": 11\n      },\n      \"id\": 12,\n      \"targets\": [\n        {\n          \"datasource\": {\n            \"type\": \"frser-sqlite-datasource\",\n            \"uid\": \"batty-telemetry\"\n          },\n          \"queryText\": \"WITH RECURSIVE hours(h) AS (\\n  SELECT MIN(timestamp) / 3600 FROM events\\n  UNION ALL\\n  SELECT h + 1 FROM hours WHERE h < (SELECT MAX(timestamp) / 3600 FROM events)\\n) SELECT h * 3600 as time, COALESCE(e.cnt, 0) as completions FROM hours LEFT JOIN (SELECT timestamp / 3600 as hr, COUNT(*) as cnt FROM events WHERE event_type=\'task_completed\' GROUP BY hr) e ON hours.h = e.hr ORDER BY time;\",\n          \"queryType\": \"table\",\n          \"rawQueryText\": \"WITH RECURSIVE hours(h) AS (\\n  SELECT MIN(timestamp) / 3600 FROM events\\n  UNION ALL\\n  SELECT h + 1 FROM hours WHERE h < (SELECT MAX(timestamp) / 3600 FROM events)\\n) SELECT h * 3600 as time, COALESCE(e.cnt, 0) as completions FROM hours LEFT JOIN (SELECT timestamp / 3600 as hr, COUNT(*) as cnt FROM events WHERE event_type=\'task_completed\' GROUP BY hr) e ON hours.h = e.hr ORDER BY time;\",\n          \"rawSql\": \"WITH RECURSIVE hours(h) AS (\\n  SELECT MIN(timestamp) / 3600 FROM events\\n  UNION ALL\\n  SELECT h + 1 FROM hours WHERE h < (SELECT MAX(timestamp) / 3600 FROM events)\\n) SELECT h * 3600 as time, COALESCE(e.cnt, 0) as completions FROM hours LEFT JOIN (SELECT timestamp / 3600 as hr, COUNT(*) as cnt FROM events WHERE event_type=\'task_completed\' GROUP BY hr) e ON hours.h = e.hr ORDER BY time;\",\n          \"refId\": \"A\",\n          \"timeColumns\": [\n            \"time\"\n          ]\n        },\n        {\n          \"datasource\": {\n            \"type\": \"frser-sqlite-datasource\",\n            \"uid\": \"batty-telemetry\"\n          },\n          \"queryText\": \"WITH RECURSIVE hours(h) AS (\\n  SELECT MIN(timestamp) / 3600 FROM events\\n  UNION ALL\\n  SELECT h + 1 FROM hours WHERE h < (SELECT MAX(timestamp) / 3600 FROM events)\\n) SELECT h * 3600 as time, COALESCE(e.cnt, 0) as crashes FROM hours LEFT JOIN (SELECT timestamp / 3600 as hr, COUNT(*) as cnt FROM events WHERE event_type=\'member_crashed\' GROUP BY hr) e ON hours.h = e.hr ORDER BY time;\",\n          \"queryType\": \"table\",\n          \"rawQueryText\": \"WITH RECURSIVE hours(h) AS (\\n  SELECT MIN(timestamp) / 3600 FROM events\\n  UNION ALL\\n  SELECT h + 1 FROM hours WHERE h < (SELECT MAX(timestamp) / 3600 FROM events)\\n) SELECT h * 3600 as time, COALESCE(e.cnt, 0) as crashes FROM hours LEFT JOIN (SELECT timestamp / 3600 as hr, COUNT(*) as cnt FROM events WHERE event_type=\'member_crashed\' GROUP BY hr) e ON hours.h = e.hr ORDER BY time;\",\n          \"rawSql\": \"WITH RECURSIVE hours(h) AS (\\n  SELECT MIN(timestamp) / 3600 FROM events\\n  UNION ALL\\n  SELECT h + 1 FROM hours WHERE h < (SELECT MAX(timestamp) / 3600 FROM events)\\n) SELECT h * 3600 as time, COALESCE(e.cnt, 0) as crashes FROM hours LEFT JOIN (SELECT timestamp / 3600 as hr, COUNT(*) as cnt FROM events WHERE event_type=\'member_crashed\' GROUP BY hr) e ON hours.h = e.hr ORDER BY time;\",\n          \"refId\": \"B\",\n          \"timeColumns\": [\n            \"time\"\n          ]\n        }\n      ],\n      \"title\": \"Completions & Crashes Per Hour\",\n      \"type\": \"timeseries\"\n    },\n    {\n      \"datasource\": {\n        \"type\": \"frser-sqlite-datasource\",\n        \"uid\": \"batty-telemetry\"\n      },\n      \"fieldConfig\": {\n        \"defaults\": {\n          \"custom\": {\n            \"fillOpacity\": 10,\n            \"lineWidth\": 2\n          }\n        }\n      },\n      \"gridPos\": {\n        \"h\": 8,\n        \"w\": 12,\n        \"x\": 0,\n        \"y\": 19\n      },\n      \"id\": 13,\n      \"targets\": [\n        {\n          \"datasource\": {\n            \"type\": \"frser-sqlite-datasource\",\n            \"uid\": \"batty-telemetry\"\n          },\n          \"queryText\": \"WITH RECURSIVE hours(h) AS (\\n  SELECT MIN(timestamp) / 3600 FROM events\\n  UNION ALL\\n  SELECT h + 1 FROM hours WHERE h < (SELECT MAX(timestamp) / 3600 FROM events)\\n) SELECT h * 3600 as time, COALESCE(e.cnt, 0) as messages FROM hours LEFT JOIN (SELECT timestamp / 3600 as hr, COUNT(*) as cnt FROM events WHERE event_type=\'message_routed\' GROUP BY hr) e ON hours.h = e.hr ORDER BY time;\",\n          \"queryType\": \"table\",\n          \"rawQueryText\": \"WITH RECURSIVE hours(h) AS (\\n  SELECT MIN(timestamp) / 3600 FROM events\\n  UNION ALL\\n  SELECT h + 1 FROM hours WHERE h < (SELECT MAX(timestamp) / 3600 FROM events)\\n) SELECT h * 3600 as time, COALESCE(e.cnt, 0) as messages FROM hours LEFT JOIN (SELECT timestamp / 3600 as hr, COUNT(*) as cnt FROM events WHERE event_type=\'message_routed\' GROUP BY hr) e ON hours.h = e.hr ORDER BY time;\",\n          \"rawSql\": \"WITH RECURSIVE hours(h) AS (\\n  SELECT MIN(timestamp) / 3600 FROM events\\n  UNION ALL\\n  SELECT h + 1 FROM hours WHERE h < (SELECT MAX(timestamp) / 3600 FROM events)\\n) SELECT h * 3600 as time, COALESCE(e.cnt, 0) as messages FROM hours LEFT JOIN (SELECT timestamp / 3600 as hr, COUNT(*) as cnt FROM events WHERE event_type=\'message_routed\' GROUP BY hr) e ON hours.h = e.hr ORDER BY time;\",\n          \"refId\": \"A\",\n          \"timeColumns\": [\n            \"time\"\n          ]\n        }\n      ],\n      \"title\": \"Messages Per Hour\",\n      \"type\": \"timeseries\"\n    },\n    {\n      \"datasource\": {\n        \"type\": \"frser-sqlite-datasource\",\n        \"uid\": \"batty-telemetry\"\n      },\n      \"fieldConfig\": {\n        \"defaults\": {\n          \"custom\": {\n            \"fillOpacity\": 10,\n            \"lineWidth\": 2\n          }\n        }\n      },\n      \"gridPos\": {\n        \"h\": 8,\n        \"w\": 12,\n        \"x\": 12,\n        \"y\": 19\n      },\n      \"id\": 14,\n      \"targets\": [\n        {\n          \"datasource\": {\n            \"type\": \"frser-sqlite-datasource\",\n            \"uid\": \"batty-telemetry\"\n          },\n          \"queryText\": \"WITH RECURSIVE hours(h) AS (\\n  SELECT MIN(timestamp) / 3600 FROM events\\n  UNION ALL\\n  SELECT h + 1 FROM hours WHERE h < (SELECT MAX(timestamp) / 3600 FROM events)\\n) SELECT h * 3600 as time, COALESCE(e.cnt, 0) as assigned FROM hours LEFT JOIN (SELECT timestamp / 3600 as hr, COUNT(*) as cnt FROM events WHERE event_type=\'task_assigned\' GROUP BY hr) e ON hours.h = e.hr ORDER BY time;\",\n          \"queryType\": \"table\",\n          \"rawQueryText\": \"WITH RECURSIVE hours(h) AS (\\n  SELECT MIN(timestamp) / 3600 FROM events\\n  UNION ALL\\n  SELECT h + 1 FROM hours WHERE h < (SELECT MAX(timestamp) / 3600 FROM events)\\n) SELECT h * 3600 as time, COALESCE(e.cnt, 0) as assigned FROM hours LEFT JOIN (SELECT timestamp / 3600 as hr, COUNT(*) as cnt FROM events WHERE event_type=\'task_assigned\' GROUP BY hr) e ON hours.h = e.hr ORDER BY time;\",\n          \"rawSql\": \"WITH RECURSIVE hours(h) AS (\\n  SELECT MIN(timestamp) / 3600 FROM events\\n  UNION ALL\\n  SELECT h + 1 FROM hours WHERE h < (SELECT MAX(timestamp) / 3600 FROM events)\\n) SELECT h * 3600 as time, COALESCE(e.cnt, 0) as assigned FROM hours LEFT JOIN (SELECT timestamp / 3600 as hr, COUNT(*) as cnt FROM events WHERE event_type=\'task_assigned\' GROUP BY hr) e ON hours.h = e.hr ORDER BY time;\",\n          \"refId\": \"A\",\n          \"timeColumns\": [\n            \"time\"\n          ]\n        },\n        {\n          \"datasource\": {\n            \"type\": \"frser-sqlite-datasource\",\n            \"uid\": \"batty-telemetry\"\n          },\n          \"queryText\": \"WITH RECURSIVE hours(h) AS (\\n  SELECT MIN(timestamp) / 3600 FROM events\\n  UNION ALL\\n  SELECT h + 1 FROM hours WHERE h < (SELECT MAX(timestamp) / 3600 FROM events)\\n) SELECT h * 3600 as time, COALESCE(e.cnt, 0) as merged FROM hours LEFT JOIN (SELECT timestamp / 3600 as hr, COUNT(*) as cnt FROM events WHERE event_type=\'task_auto_merged\' GROUP BY hr) e ON hours.h = e.hr ORDER BY time;\",\n          \"queryType\": \"table\",\n          \"rawQueryText\": \"WITH RECURSIVE hours(h) AS (\\n  SELECT MIN(timestamp) / 3600 FROM events\\n  UNION ALL\\n  SELECT h + 1 FROM hours WHERE h < (SELECT MAX(timestamp) / 3600 FROM events)\\n) SELECT h * 3600 as time, COALESCE(e.cnt, 0) as merged FROM hours LEFT JOIN (SELECT timestamp / 3600 as hr, COUNT(*) as cnt FROM events WHERE event_type=\'task_auto_merged\' GROUP BY hr) e ON hours.h = e.hr ORDER BY time;\",\n          \"rawSql\": \"WITH RECURSIVE hours(h) AS (\\n  SELECT MIN(timestamp) / 3600 FROM events\\n  UNION ALL\\n  SELECT h + 1 FROM hours WHERE h < (SELECT MAX(timestamp) / 3600 FROM events)\\n) SELECT h * 3600 as time, COALESCE(e.cnt, 0) as merged FROM hours LEFT JOIN (SELECT timestamp / 3600 as hr, COUNT(*) as cnt FROM events WHERE event_type=\'task_auto_merged\' GROUP BY hr) e ON hours.h = e.hr ORDER BY time;\",\n          \"refId\": \"B\",\n          \"timeColumns\": [\n            \"time\"\n          ]\n        }\n      ],\n      \"title\": \"Assignments & Merges Per Hour\",\n      \"type\": \"timeseries\"\n    },\n    {\n      \"collapsed\": false,\n      \"gridPos\": {\n        \"h\": 1,\n        \"w\": 24,\n        \"x\": 0,\n        \"y\": 27\n      },\n      \"id\": 103,\n      \"title\": \"Agent Performance\",\n      \"type\": \"row\"\n    },\n    {\n      \"datasource\": {\n        \"type\": \"frser-sqlite-datasource\",\n        \"uid\": \"batty-telemetry\"\n      },\n      \"gridPos\": {\n        \"h\": 8,\n        \"w\": 12,\n        \"x\": 0,\n        \"y\": 28\n      },\n      \"id\": 15,\n      \"targets\": [\n        {\n          \"datasource\": {\n            \"type\": \"frser-sqlite-datasource\",\n            \"uid\": \"batty-telemetry\"\n          },\n          \"queryText\": \"SELECT role, completions, failures, restarts, idle_polls, working_polls FROM agent_metrics ORDER BY completions DESC;\",\n          \"queryType\": \"table\",\n          \"rawQueryText\": \"SELECT role, completions, failures, restarts, idle_polls, working_polls FROM agent_metrics ORDER BY completions DESC;\",\n          \"rawSql\": \"SELECT role, completions, failures, restarts, idle_polls, working_polls FROM agent_metrics ORDER BY completions DESC;\",\n          \"refId\": \"A\"\n        }\n      ],\n      \"title\": \"Agent Metrics\",\n      \"type\": \"table\"\n    },\n    {\n      \"datasource\": {\n        \"type\": \"frser-sqlite-datasource\",\n        \"uid\": \"batty-telemetry\"\n      },\n      \"gridPos\": {\n        \"h\": 8,\n        \"w\": 12,\n        \"x\": 12,\n        \"y\": 28\n      },\n      \"id\": 16,\n      \"targets\": [\n        {\n          \"datasource\": {\n            \"type\": \"frser-sqlite-datasource\",\n            \"uid\": \"batty-telemetry\"\n          },\n          \"queryText\": \"SELECT json_extract(payload, \'$.from\') || \' -> \' || json_extract(payload, \'$.to\') as route, COUNT(*) as count FROM events WHERE event_type=\'message_routed\' GROUP BY route ORDER BY count DESC LIMIT 10;\",\n          \"queryType\": \"table\",\n          \"rawQueryText\": \"SELECT json_extract(payload, \'$.from\') || \' -> \' || json_extract(payload, \'$.to\') as route, COUNT(*) as count FROM events WHERE event_type=\'message_routed\' GROUP BY route ORDER BY count DESC LIMIT 10;\",\n          \"rawSql\": \"SELECT json_extract(payload, \'$.from\') || \' -> \' || json_extract(payload, \'$.to\') as route, COUNT(*) as count FROM events WHERE event_type=\'message_routed\' GROUP BY route ORDER BY count DESC LIMIT 10;\",\n          \"refId\": \"A\"\n        }\n      ],\n      \"title\": \"Top Message Routes\",\n      \"type\": \"barchart\"\n    },\n    {\n      \"collapsed\": false,\n      \"gridPos\": {\n        \"h\": 1,\n        \"w\": 24,\n        \"x\": 0,\n        \"y\": 36\n      },\n      \"id\": 104,\n      \"title\": \"Event Breakdown\",\n      \"type\": \"row\"\n    },\n    {\n      \"datasource\": {\n        \"type\": \"frser-sqlite-datasource\",\n        \"uid\": \"batty-telemetry\"\n      },\n      \"gridPos\": {\n        \"h\": 8,\n        \"w\": 8,\n        \"x\": 0,\n        \"y\": 37\n      },\n      \"id\": 17,\n      \"targets\": [\n        {\n          \"datasource\": {\n            \"type\": \"frser-sqlite-datasource\",\n            \"uid\": \"batty-telemetry\"\n          },\n          \"queryText\": \"SELECT event_type, COUNT(*) as count FROM events GROUP BY event_type ORDER BY count DESC;\",\n          \"queryType\": \"table\",\n          \"rawQueryText\": \"SELECT event_type, COUNT(*) as count FROM events GROUP BY event_type ORDER BY count DESC;\",\n          \"rawSql\": \"SELECT event_type, COUNT(*) as count FROM events GROUP BY event_type ORDER BY count DESC;\",\n          \"refId\": \"A\"\n        }\n      ],\n      \"title\": \"Event Type Distribution\",\n      \"type\": \"piechart\"\n    },\n    {\n      \"datasource\": {\n        \"type\": \"frser-sqlite-datasource\",\n        \"uid\": \"batty-telemetry\"\n      },\n      \"gridPos\": {\n        \"h\": 8,\n        \"w\": 8,\n        \"x\": 8,\n        \"y\": 37\n      },\n      \"id\": 18,\n      \"targets\": [\n        {\n          \"datasource\": {\n            \"type\": \"frser-sqlite-datasource\",\n            \"uid\": \"batty-telemetry\"\n          },\n          \"queryText\": \"SELECT role as agent, COUNT(*) as tasks FROM events WHERE event_type=\'task_completed\' GROUP BY role ORDER BY tasks DESC;\",\n          \"queryType\": \"table\",\n          \"rawQueryText\": \"SELECT role as agent, COUNT(*) as tasks FROM events WHERE event_type=\'task_completed\' GROUP BY role ORDER BY tasks DESC;\",\n          \"rawSql\": \"SELECT role as agent, COUNT(*) as tasks FROM events WHERE event_type=\'task_completed\' GROUP BY role ORDER BY tasks DESC;\",\n          \"refId\": \"A\"\n        }\n      ],\n      \"title\": \"Completions by Agent\",\n      \"type\": \"piechart\"\n    },\n    {\n      \"datasource\": {\n        \"type\": \"frser-sqlite-datasource\",\n        \"uid\": \"batty-telemetry\"\n      },\n      \"gridPos\": {\n        \"h\": 8,\n        \"w\": 8,\n        \"x\": 16,\n        \"y\": 37\n      },\n      \"id\": 19,\n      \"targets\": [\n        {\n          \"datasource\": {\n            \"type\": \"frser-sqlite-datasource\",\n            \"uid\": \"batty-telemetry\"\n          },\n          \"queryText\": \"SELECT role as agent, COUNT(*) as crashes FROM events WHERE event_type=\'member_crashed\' GROUP BY role ORDER BY crashes DESC;\",\n          \"queryType\": \"table\",\n          \"rawQueryText\": \"SELECT role as agent, COUNT(*) as crashes FROM events WHERE event_type=\'member_crashed\' GROUP BY role ORDER BY crashes DESC;\",\n          \"rawSql\": \"SELECT role as agent, COUNT(*) as crashes FROM events WHERE event_type=\'member_crashed\' GROUP BY role ORDER BY crashes DESC;\",\n          \"refId\": \"A\"\n        }\n      ],\n      \"title\": \"Crashes by Agent\",\n      \"type\": \"piechart\"\n    },\n    {\n      \"collapsed\": false,\n      \"gridPos\": {\n        \"h\": 1,\n        \"w\": 24,\n        \"x\": 0,\n        \"y\": 45\n      },\n      \"id\": 105,\n      \"title\": \"Recent Activity\",\n      \"type\": \"row\"\n    },\n    {\n      \"datasource\": {\n        \"type\": \"frser-sqlite-datasource\",\n        \"uid\": \"batty-telemetry\"\n      },\n      \"gridPos\": {\n        \"h\": 8,\n        \"w\": 12,\n        \"x\": 0,\n        \"y\": 46\n      },\n      \"id\": 20,\n      \"targets\": [\n        {\n          \"datasource\": {\n            \"type\": \"frser-sqlite-datasource\",\n            \"uid\": \"batty-telemetry\"\n          },\n          \"queryText\": \"SELECT datetime(timestamp, \'unixepoch\', \'localtime\') as time, role, task_id FROM events WHERE event_type=\'task_completed\' ORDER BY timestamp DESC LIMIT 20;\",\n          \"queryType\": \"table\",\n          \"rawQueryText\": \"SELECT datetime(timestamp, \'unixepoch\', \'localtime\') as time, role, task_id FROM events WHERE event_type=\'task_completed\' ORDER BY timestamp DESC LIMIT 20;\",\n          \"rawSql\": \"SELECT datetime(timestamp, \'unixepoch\', \'localtime\') as time, role, task_id FROM events WHERE event_type=\'task_completed\' ORDER BY timestamp DESC LIMIT 20;\",\n          \"refId\": \"A\"\n        }\n      ],\n      \"title\": \"Recent Completions\",\n      \"type\": \"table\"\n    },\n    {\n      \"datasource\": {\n        \"type\": \"frser-sqlite-datasource\",\n        \"uid\": \"batty-telemetry\"\n      },\n      \"gridPos\": {\n        \"h\": 8,\n        \"w\": 12,\n        \"x\": 12,\n        \"y\": 46\n      },\n      \"id\": 21,\n      \"targets\": [\n        {\n          \"datasource\": {\n            \"type\": \"frser-sqlite-datasource\",\n            \"uid\": \"batty-telemetry\"\n          },\n          \"queryText\": \"SELECT datetime(timestamp, \'unixepoch\', \'localtime\') as time, role, task_id, ROUND(json_extract(payload, \'$.load\'), 2) as confidence, json_extract(payload, \'$.reason\') as reason FROM events WHERE event_type=\'merge_confidence_scored\' ORDER BY timestamp DESC LIMIT 20;\",\n          \"queryType\": \"table\",\n          \"rawQueryText\": \"SELECT datetime(timestamp, \'unixepoch\', \'localtime\') as time, role, task_id, ROUND(json_extract(payload, \'$.load\'), 2) as confidence, json_extract(payload, \'$.reason\') as reason FROM events WHERE event_type=\'merge_confidence_scored\' ORDER BY timestamp DESC LIMIT 20;\",\n          \"rawSql\": \"SELECT datetime(timestamp, \'unixepoch\', \'localtime\') as time, role, task_id, ROUND(json_extract(payload, \'$.load\'), 2) as confidence, json_extract(payload, \'$.reason\') as reason FROM events WHERE event_type=\'merge_confidence_scored\' ORDER BY timestamp DESC LIMIT 20;\",\n          \"refId\": \"A\"\n        }\n      ],\n      \"title\": \"Recent Confidence Scores\",\n      \"type\": \"table\"\n    },\n    {\n      \"collapsed\": false,\n      \"gridPos\": {\n        \"h\": 1,\n        \"w\": 24,\n        \"x\": 0,\n        \"y\": 54\n      },\n      \"id\": 106,\n      \"title\": \"Throughput Over Time\",\n      \"type\": \"row\"\n    },\n    {\n      \"datasource\": {\n        \"type\": \"frser-sqlite-datasource\",\n        \"uid\": \"batty-telemetry\"\n      },\n      \"fieldConfig\": {\n        \"defaults\": {\n          \"custom\": {\n            \"fillOpacity\": 15,\n            \"lineWidth\": 2\n          },\n          \"max\": 100,\n          \"min\": 0,\n          \"unit\": \"percent\"\n        }\n      },\n      \"gridPos\": {\n        \"h\": 8,\n        \"w\": 12,\n        \"x\": 0,\n        \"y\": 55\n      },\n      \"id\": 107,\n      \"targets\": [\n        {\n          \"datasource\": {\n            \"type\": \"frser-sqlite-datasource\",\n            \"uid\": \"batty-telemetry\"\n          },\n          \"queryText\": \"WITH RECURSIVE hours(h) AS (\\n  SELECT COALESCE((SELECT MIN(completed_at) / 3600 FROM task_cycle_times), strftime(\'%s\', \'now\') / 3600)\\n  UNION ALL\\n  SELECT h + 1 FROM hours WHERE h < COALESCE((SELECT MAX(completed_at) / 3600 FROM task_cycle_times), strftime(\'%s\', \'now\') / 3600)\\n) SELECT h * 3600 as time, ROUND(metrics.avg_cycle_time_mins, 1) as cycle_time_minutes, ROUND(metrics.avg_lead_time_mins, 1) as lead_time_minutes FROM hours LEFT JOIN (SELECT (completed_at / 3600) * 3600 as hour_start, AVG(cycle_time_mins) as avg_cycle_time_mins, AVG(lead_time_mins) as avg_lead_time_mins FROM task_cycle_times GROUP BY 1) metrics ON metrics.hour_start = h * 3600 ORDER BY time;\",\n          \"queryType\": \"table\",\n          \"rawQueryText\": \"WITH RECURSIVE hours(h) AS (\\n  SELECT COALESCE((SELECT MIN(completed_at) / 3600 FROM task_cycle_times), strftime(\'%s\', \'now\') / 3600)\\n  UNION ALL\\n  SELECT h + 1 FROM hours WHERE h < COALESCE((SELECT MAX(completed_at) / 3600 FROM task_cycle_times), strftime(\'%s\', \'now\') / 3600)\\n) SELECT h * 3600 as time, ROUND(metrics.avg_cycle_time_mins, 1) as cycle_time_minutes, ROUND(metrics.avg_lead_time_mins, 1) as lead_time_minutes FROM hours LEFT JOIN (SELECT (completed_at / 3600) * 3600 as hour_start, AVG(cycle_time_mins) as avg_cycle_time_mins, AVG(lead_time_mins) as avg_lead_time_mins FROM task_cycle_times GROUP BY 1) metrics ON metrics.hour_start = h * 3600 ORDER BY time;\",\n          \"rawSql\": \"WITH RECURSIVE hours(h) AS (\\n  SELECT COALESCE((SELECT MIN(completed_at) / 3600 FROM task_cycle_times), strftime(\'%s\', \'now\') / 3600)\\n  UNION ALL\\n  SELECT h + 1 FROM hours WHERE h < COALESCE((SELECT MAX(completed_at) / 3600 FROM task_cycle_times), strftime(\'%s\', \'now\') / 3600)\\n) SELECT h * 3600 as time, ROUND(metrics.avg_cycle_time_mins, 1) as cycle_time_minutes, ROUND(metrics.avg_lead_time_mins, 1) as lead_time_minutes FROM hours LEFT JOIN (SELECT (completed_at / 3600) * 3600 as hour_start, AVG(cycle_time_mins) as avg_cycle_time_mins, AVG(lead_time_mins) as avg_lead_time_mins FROM task_cycle_times GROUP BY 1) metrics ON metrics.hour_start = h * 3600 ORDER BY time;\",\n          \"refId\": \"A\",\n          \"timeColumns\": [\n            \"time\"\n          ]\n        }\n      ],\n      \"title\": \"Average Cycle and Lead Time Per Hour\",\n      \"type\": \"timeseries\"\n    },\n    {\n      \"datasource\": {\n        \"type\": \"frser-sqlite-datasource\",\n        \"uid\": \"batty-telemetry\"\n      },\n      \"fieldConfig\": {\n        \"defaults\": {\n          \"custom\": {\n            \"fillOpacity\": 10,\n            \"lineWidth\": 2\n          }\n        }\n      },\n      \"gridPos\": {\n        \"h\": 8,\n        \"w\": 12,\n        \"x\": 12,\n        \"y\": 55\n      },\n      \"id\": 108,\n      \"targets\": [\n        {\n          \"datasource\": {\n            \"type\": \"frser-sqlite-datasource\",\n            \"uid\": \"batty-telemetry\"\n          },\n          \"queryText\": \"WITH RECURSIVE hours(h) AS (\\n  SELECT COALESCE((SELECT MIN(completed_at) / 3600 FROM task_cycle_times), strftime(\'%s\', \'now\') / 3600)\\n  UNION ALL\\n  SELECT h + 1 FROM hours WHERE h < COALESCE((SELECT MAX(completed_at) / 3600 FROM task_cycle_times), strftime(\'%s\', \'now\') / 3600)\\n) SELECT h * 3600 as time, COALESCE(counts.completed, 0) as completed FROM hours LEFT JOIN (SELECT (completed_at / 3600) * 3600 as hour_start, COUNT(*) as completed FROM task_cycle_times GROUP BY 1) counts ON counts.hour_start = h * 3600 ORDER BY time;\",\n          \"queryType\": \"table\",\n          \"rawQueryText\": \"WITH RECURSIVE hours(h) AS (\\n  SELECT COALESCE((SELECT MIN(completed_at) / 3600 FROM task_cycle_times), strftime(\'%s\', \'now\') / 3600)\\n  UNION ALL\\n  SELECT h + 1 FROM hours WHERE h < COALESCE((SELECT MAX(completed_at) / 3600 FROM task_cycle_times), strftime(\'%s\', \'now\') / 3600)\\n) SELECT h * 3600 as time, COALESCE(counts.completed, 0) as completed FROM hours LEFT JOIN (SELECT (completed_at / 3600) * 3600 as hour_start, COUNT(*) as completed FROM task_cycle_times GROUP BY 1) counts ON counts.hour_start = h * 3600 ORDER BY time;\",\n          \"rawSql\": \"WITH RECURSIVE hours(h) AS (\\n  SELECT COALESCE((SELECT MIN(completed_at) / 3600 FROM task_cycle_times), strftime(\'%s\', \'now\') / 3600)\\n  UNION ALL\\n  SELECT h + 1 FROM hours WHERE h < COALESCE((SELECT MAX(completed_at) / 3600 FROM task_cycle_times), strftime(\'%s\', \'now\') / 3600)\\n) SELECT h * 3600 as time, COALESCE(counts.completed, 0) as completed FROM hours LEFT JOIN (SELECT (completed_at / 3600) * 3600 as hour_start, COUNT(*) as completed FROM task_cycle_times GROUP BY 1) counts ON counts.hour_start = h * 3600 ORDER BY time;\",\n          \"refId\": \"A\",\n          \"timeColumns\": [\n            \"time\"\n          ]\n        }\n      ],\n      \"title\": \"Tasks Completed Per Hour\",\n      \"type\": \"timeseries\"\n    },\n    {\n      \"datasource\": {\n        \"type\": \"frser-sqlite-datasource\",\n        \"uid\": \"batty-telemetry\"\n      },\n      \"fieldConfig\": {\n        \"defaults\": {\n          \"custom\": {\n            \"fillOpacity\": 20,\n            \"gradientMode\": \"scheme\",\n            \"lineWidth\": 2\n          }\n        }\n      },\n      \"gridPos\": {\n        \"h\": 8,\n        \"w\": 12,\n        \"x\": 0,\n        \"y\": 63\n      },\n      \"id\": 109,\n      \"targets\": [\n        {\n          \"datasource\": {\n            \"type\": \"frser-sqlite-datasource\",\n            \"uid\": \"batty-telemetry\"\n          },\n          \"queryText\": \"WITH RECURSIVE hours(h) AS (\\n  SELECT COALESCE((SELECT MIN(completed_at) / 3600 FROM task_cycle_times), strftime(\'%s\', \'now\') / 3600)\\n  UNION ALL\\n  SELECT h + 1 FROM hours WHERE h < COALESCE((SELECT MAX(completed_at) / 3600 FROM task_cycle_times), strftime(\'%s\', \'now\') / 3600)\\n) SELECT h * 3600 as time, (SELECT COUNT(*) FROM task_cycle_times t2 WHERE t2.completed_at <= (h + 1) * 3600) as total_completed FROM hours ORDER BY time;\",\n          \"queryType\": \"table\",\n          \"rawQueryText\": \"WITH RECURSIVE hours(h) AS (\\n  SELECT COALESCE((SELECT MIN(completed_at) / 3600 FROM task_cycle_times), strftime(\'%s\', \'now\') / 3600)\\n  UNION ALL\\n  SELECT h + 1 FROM hours WHERE h < COALESCE((SELECT MAX(completed_at) / 3600 FROM task_cycle_times), strftime(\'%s\', \'now\') / 3600)\\n) SELECT h * 3600 as time, (SELECT COUNT(*) FROM task_cycle_times t2 WHERE t2.completed_at <= (h + 1) * 3600) as total_completed FROM hours ORDER BY time;\",\n          \"rawSql\": \"WITH RECURSIVE hours(h) AS (\\n  SELECT COALESCE((SELECT MIN(completed_at) / 3600 FROM task_cycle_times), strftime(\'%s\', \'now\') / 3600)\\n  UNION ALL\\n  SELECT h + 1 FROM hours WHERE h < COALESCE((SELECT MAX(completed_at) / 3600 FROM task_cycle_times), strftime(\'%s\', \'now\') / 3600)\\n) SELECT h * 3600 as time, (SELECT COUNT(*) FROM task_cycle_times t2 WHERE t2.completed_at <= (h + 1) * 3600) as total_completed FROM hours ORDER BY time;\",\n          \"refId\": \"A\",\n          \"timeColumns\": [\n            \"time\"\n          ]\n        }\n      ],\n      \"title\": \"Cumulative Tasks Completed\",\n      \"type\": \"timeseries\"\n    },\n    {\n      \"datasource\": {\n        \"type\": \"frser-sqlite-datasource\",\n        \"uid\": \"batty-telemetry\"\n      },\n      \"fieldConfig\": {\n        \"defaults\": {\n          \"custom\": {\n            \"drawStyle\": \"points\",\n            \"lineWidth\": 1,\n            \"pointSize\": 5\n          },\n          \"max\": 1,\n          \"min\": 0,\n          \"unit\": \"percentunit\"\n        }\n      },\n      \"gridPos\": {\n        \"h\": 8,\n        \"w\": 12,\n        \"x\": 12,\n        \"y\": 63\n      },\n      \"id\": 110,\n      \"targets\": [\n        {\n          \"datasource\": {\n            \"type\": \"frser-sqlite-datasource\",\n            \"uid\": \"batty-telemetry\"\n          },\n          \"queryText\": \"SELECT timestamp as time, CAST(json_extract(payload, \'$.load\') AS REAL) as confidence FROM events WHERE event_type=\'merge_confidence_scored\' ORDER BY time;\",\n          \"queryType\": \"table\",\n          \"rawQueryText\": \"SELECT timestamp as time, CAST(json_extract(payload, \'$.load\') AS REAL) as confidence FROM events WHERE event_type=\'merge_confidence_scored\' ORDER BY time;\",\n          \"rawSql\": \"SELECT timestamp as time, CAST(json_extract(payload, \'$.load\') AS REAL) as confidence FROM events WHERE event_type=\'merge_confidence_scored\' ORDER BY time;\",\n          \"refId\": \"A\",\n          \"timeColumns\": [\n            \"time\"\n          ]\n        }\n      ],\n      \"title\": \"Merge Confidence Over Time\",\n      \"type\": \"timeseries\"\n    },\n    {\n      \"datasource\": {\n        \"type\": \"frser-sqlite-datasource\",\n        \"uid\": \"batty-telemetry\"\n      },\n      \"fieldConfig\": {\n        \"defaults\": {\n          \"custom\": {\n            \"fillOpacity\": 10,\n            \"lineWidth\": 2\n          }\n        }\n      },\n      \"gridPos\": {\n        \"h\": 8,\n        \"w\": 12,\n        \"x\": 0,\n        \"y\": 71\n      },\n      \"id\": 111,\n      \"targets\": [\n        {\n          \"datasource\": {\n            \"type\": \"frser-sqlite-datasource\",\n            \"uid\": \"batty-telemetry\"\n          },\n          \"queryText\": \"WITH RECURSIVE hours(h) AS (\\n  SELECT MIN(timestamp) / 3600 FROM events\\n  UNION ALL\\n  SELECT h + 1 FROM hours WHERE h < (SELECT MAX(timestamp) / 3600 FROM events)\\n) SELECT h * 3600 as time, COALESCE(e.cnt, 0) as spawned FROM hours LEFT JOIN (SELECT timestamp / 3600 as hr, COUNT(*) as cnt FROM events WHERE event_type=\'agent_spawned\' GROUP BY hr) e ON hours.h = e.hr ORDER BY time;\",\n          \"queryType\": \"table\",\n          \"rawQueryText\": \"WITH RECURSIVE hours(h) AS (\\n  SELECT MIN(timestamp) / 3600 FROM events\\n  UNION ALL\\n  SELECT h + 1 FROM hours WHERE h < (SELECT MAX(timestamp) / 3600 FROM events)\\n) SELECT h * 3600 as time, COALESCE(e.cnt, 0) as spawned FROM hours LEFT JOIN (SELECT timestamp / 3600 as hr, COUNT(*) as cnt FROM events WHERE event_type=\'agent_spawned\' GROUP BY hr) e ON hours.h = e.hr ORDER BY time;\",\n          \"rawSql\": \"WITH RECURSIVE hours(h) AS (\\n  SELECT MIN(timestamp) / 3600 FROM events\\n  UNION ALL\\n  SELECT h + 1 FROM hours WHERE h < (SELECT MAX(timestamp) / 3600 FROM events)\\n) SELECT h * 3600 as time, COALESCE(e.cnt, 0) as spawned FROM hours LEFT JOIN (SELECT timestamp / 3600 as hr, COUNT(*) as cnt FROM events WHERE event_type=\'agent_spawned\' GROUP BY hr) e ON hours.h = e.hr ORDER BY time;\",\n          \"refId\": \"A\",\n          \"timeColumns\": [\n            \"time\"\n          ]\n        },\n        {\n          \"datasource\": {\n            \"type\": \"frser-sqlite-datasource\",\n            \"uid\": \"batty-telemetry\"\n          },\n          \"queryText\": \"WITH RECURSIVE hours(h) AS (\\n  SELECT MIN(timestamp) / 3600 FROM events\\n  UNION ALL\\n  SELECT h + 1 FROM hours WHERE h < (SELECT MAX(timestamp) / 3600 FROM events)\\n) SELECT h * 3600 as time, COALESCE(e.cnt, 0) as crashed FROM hours LEFT JOIN (SELECT timestamp / 3600 as hr, COUNT(*) as cnt FROM events WHERE event_type=\'member_crashed\' GROUP BY hr) e ON hours.h = e.hr ORDER BY time;\",\n          \"queryType\": \"table\",\n          \"rawQueryText\": \"WITH RECURSIVE hours(h) AS (\\n  SELECT MIN(timestamp) / 3600 FROM events\\n  UNION ALL\\n  SELECT h + 1 FROM hours WHERE h < (SELECT MAX(timestamp) / 3600 FROM events)\\n) SELECT h * 3600 as time, COALESCE(e.cnt, 0) as crashed FROM hours LEFT JOIN (SELECT timestamp / 3600 as hr, COUNT(*) as cnt FROM events WHERE event_type=\'member_crashed\' GROUP BY hr) e ON hours.h = e.hr ORDER BY time;\",\n          \"rawSql\": \"WITH RECURSIVE hours(h) AS (\\n  SELECT MIN(timestamp) / 3600 FROM events\\n  UNION ALL\\n  SELECT h + 1 FROM hours WHERE h < (SELECT MAX(timestamp) / 3600 FROM events)\\n) SELECT h * 3600 as time, COALESCE(e.cnt, 0) as crashed FROM hours LEFT JOIN (SELECT timestamp / 3600 as hr, COUNT(*) as cnt FROM events WHERE event_type=\'member_crashed\' GROUP BY hr) e ON hours.h = e.hr ORDER BY time;\",\n          \"refId\": \"B\",\n          \"timeColumns\": [\n            \"time\"\n          ]\n        }\n      ],\n      \"title\": \"Agent Spawns vs Crashes Per Hour\",\n      \"type\": \"timeseries\"\n    },\n    {\n      \"datasource\": {\n        \"type\": \"frser-sqlite-datasource\",\n        \"uid\": \"batty-telemetry\"\n      },\n      \"fieldConfig\": {\n        \"defaults\": {\n          \"custom\": {\n            \"fillOpacity\": 10,\n            \"lineWidth\": 2\n          }\n        }\n      },\n      \"gridPos\": {\n        \"h\": 8,\n        \"w\": 12,\n        \"x\": 12,\n        \"y\": 71\n      },\n      \"id\": 112,\n      \"targets\": [\n        {\n          \"datasource\": {\n            \"type\": \"frser-sqlite-datasource\",\n            \"uid\": \"batty-telemetry\"\n          },\n          \"queryText\": \"WITH RECURSIVE hours(h) AS (\\n  SELECT MIN(timestamp) / 3600 FROM events\\n  UNION ALL\\n  SELECT h + 1 FROM hours WHERE h < (SELECT MAX(timestamp) / 3600 FROM events)\\n) SELECT h * 3600 as time, COALESCE(e.cnt, 0) as completed FROM hours LEFT JOIN (SELECT timestamp / 3600 as hr, COUNT(*) as cnt FROM events WHERE event_type=\'task_completed\' GROUP BY hr) e ON hours.h = e.hr ORDER BY time;\",\n          \"queryType\": \"table\",\n          \"rawQueryText\": \"WITH RECURSIVE hours(h) AS (\\n  SELECT MIN(timestamp) / 3600 FROM events\\n  UNION ALL\\n  SELECT h + 1 FROM hours WHERE h < (SELECT MAX(timestamp) / 3600 FROM events)\\n) SELECT h * 3600 as time, COALESCE(e.cnt, 0) as completed FROM hours LEFT JOIN (SELECT timestamp / 3600 as hr, COUNT(*) as cnt FROM events WHERE event_type=\'task_completed\' GROUP BY hr) e ON hours.h = e.hr ORDER BY time;\",\n          \"rawSql\": \"WITH RECURSIVE hours(h) AS (\\n  SELECT MIN(timestamp) / 3600 FROM events\\n  UNION ALL\\n  SELECT h + 1 FROM hours WHERE h < (SELECT MAX(timestamp) / 3600 FROM events)\\n) SELECT h * 3600 as time, COALESCE(e.cnt, 0) as completed FROM hours LEFT JOIN (SELECT timestamp / 3600 as hr, COUNT(*) as cnt FROM events WHERE event_type=\'task_completed\' GROUP BY hr) e ON hours.h = e.hr ORDER BY time;\",\n          \"refId\": \"A\",\n          \"timeColumns\": [\n            \"time\"\n          ]\n        }\n      ],\n      \"title\": \"Messages Per Task (Efficiency)\",\n      \"type\": \"timeseries\"\n    },\n    {\n      \"datasource\": {\n        \"type\": \"frser-sqlite-datasource\",\n        \"uid\": \"batty-telemetry\"\n      },\n      \"fieldConfig\": {\n        \"defaults\": {\n          \"custom\": {\n            \"fillOpacity\": 10,\n            \"lineWidth\": 2\n          },\n          \"max\": 1,\n          \"min\": 0,\n          \"unit\": \"percentunit\"\n        }\n      },\n      \"gridPos\": {\n        \"h\": 8,\n        \"w\": 12,\n        \"x\": 0,\n        \"y\": 79\n      },\n      \"id\": 113,\n      \"targets\": [\n        {\n          \"datasource\": {\n            \"type\": \"frser-sqlite-datasource\",\n            \"uid\": \"batty-telemetry\"\n          },\n          \"queryText\": \"WITH RECURSIVE hours(h) AS (\\n  SELECT COALESCE(MIN(timestamp) / 3600, strftime(\'%s\', \'now\') / 3600) FROM events\\n  UNION ALL\\n  SELECT h + 1 FROM hours WHERE h < (SELECT COALESCE(MAX(timestamp) / 3600, strftime(\'%s\', \'now\') / 3600) FROM events)\\n), narration AS (\\n  SELECT timestamp / 3600 AS hr, COUNT(*) AS cnt FROM events WHERE event_type=\'narration_rejection\' GROUP BY hr\\n), claims AS (\\n  SELECT timestamp / 3600 AS hr, COUNT(*) AS cnt FROM events WHERE event_type IN (\'narration_rejection\', \'task_completed\') GROUP BY hr\\n) SELECT h * 3600 AS time, CASE WHEN COALESCE(claims.cnt, 0) = 0 THEN 0.0 ELSE CAST(COALESCE(narration.cnt, 0) AS REAL) / claims.cnt END AS narration_rejection_rate FROM hours LEFT JOIN narration ON hours.h = narration.hr LEFT JOIN claims ON hours.h = claims.hr ORDER BY time;\",\n          \"queryType\": \"table\",\n          \"rawQueryText\": \"WITH RECURSIVE hours(h) AS (\\n  SELECT COALESCE(MIN(timestamp) / 3600, strftime(\'%s\', \'now\') / 3600) FROM events\\n  UNION ALL\\n  SELECT h + 1 FROM hours WHERE h < (SELECT COALESCE(MAX(timestamp) / 3600, strftime(\'%s\', \'now\') / 3600) FROM events)\\n), narration AS (\\n  SELECT timestamp / 3600 AS hr, COUNT(*) AS cnt FROM events WHERE event_type=\'narration_rejection\' GROUP BY hr\\n), claims AS (\\n  SELECT timestamp / 3600 AS hr, COUNT(*) AS cnt FROM events WHERE event_type IN (\'narration_rejection\', \'task_completed\') GROUP BY hr\\n) SELECT h * 3600 AS time, CASE WHEN COALESCE(claims.cnt, 0) = 0 THEN 0.0 ELSE CAST(COALESCE(narration.cnt, 0) AS REAL) / claims.cnt END AS narration_rejection_rate FROM hours LEFT JOIN narration ON hours.h = narration.hr LEFT JOIN claims ON hours.h = claims.hr ORDER BY time;\",\n          \"rawSql\": \"WITH RECURSIVE hours(h) AS (\\n  SELECT COALESCE(MIN(timestamp) / 3600, strftime(\'%s\', \'now\') / 3600) FROM events\\n  UNION ALL\\n  SELECT h + 1 FROM hours WHERE h < (SELECT COALESCE(MAX(timestamp) / 3600, strftime(\'%s\', \'now\') / 3600) FROM events)\\n), narration AS (\\n  SELECT timestamp / 3600 AS hr, COUNT(*) AS cnt FROM events WHERE event_type=\'narration_rejection\' GROUP BY hr\\n), claims AS (\\n  SELECT timestamp / 3600 AS hr, COUNT(*) AS cnt FROM events WHERE event_type IN (\'narration_rejection\', \'task_completed\') GROUP BY hr\\n) SELECT h * 3600 AS time, CASE WHEN COALESCE(claims.cnt, 0) = 0 THEN 0.0 ELSE CAST(COALESCE(narration.cnt, 0) AS REAL) / claims.cnt END AS narration_rejection_rate FROM hours LEFT JOIN narration ON hours.h = narration.hr LEFT JOIN claims ON hours.h = claims.hr ORDER BY time;\",\n          \"refId\": \"A\",\n          \"timeColumns\": [\n            \"time\"\n          ]\n        }\n      ],\n      \"title\": \"Narration Rejection Rate Per Hour (%)\",\n      \"type\": \"timeseries\"\n    },\n    {\n      \"datasource\": {\n        \"type\": \"frser-sqlite-datasource\",\n        \"uid\": \"batty-telemetry\"\n      },\n      \"fieldConfig\": {\n        \"defaults\": {\n          \"custom\": {\n            \"fillOpacity\": 10,\n            \"lineWidth\": 2\n          },\n          \"max\": 1,\n          \"min\": 0,\n          \"unit\": \"percentunit\"\n        }\n      },\n      \"gridPos\": {\n        \"h\": 8,\n        \"w\": 12,\n        \"x\": 12,\n        \"y\": 79\n      },\n      \"id\": 114,\n      \"targets\": [\n        {\n          \"datasource\": {\n            \"type\": \"frser-sqlite-datasource\",\n            \"uid\": \"batty-telemetry\"\n          },\n          \"queryText\": \"WITH RECURSIVE hours(h) AS (\\n  SELECT COALESCE((SELECT MIN(started_at) / 3600 FROM session_summary), strftime(\'%s\', \'now\') / 3600)\\n  UNION ALL\\n  SELECT h + 1 FROM hours WHERE h < COALESCE((SELECT MAX(started_at) / 3600 FROM session_summary), strftime(\'%s\', \'now\') / 3600)\\n), summary AS (\\n  SELECT (started_at / 3600) * 3600 AS hour_start,\\n         SUM(verification_passes) AS passes,\\n         SUM(verification_failures) AS failures\\n  FROM session_summary\\n  GROUP BY 1\\n) SELECT h * 3600 AS time,\\n         CASE\\n           WHEN COALESCE(summary.passes, 0) + COALESCE(summary.failures, 0) = 0 THEN 100.0\\n           ELSE ROUND(100.0 * COALESCE(summary.passes, 0) / (COALESCE(summary.passes, 0) + COALESCE(summary.failures, 0)), 1)\\n         END AS verification_pass_rate\\nFROM hours\\nLEFT JOIN summary ON hours.h * 3600 = summary.hour_start\\nORDER BY time;\",\n          \"queryType\": \"table\",\n          \"rawQueryText\": \"WITH RECURSIVE hours(h) AS (\\n  SELECT COALESCE((SELECT MIN(started_at) / 3600 FROM session_summary), strftime(\'%s\', \'now\') / 3600)\\n  UNION ALL\\n  SELECT h + 1 FROM hours WHERE h < COALESCE((SELECT MAX(started_at) / 3600 FROM session_summary), strftime(\'%s\', \'now\') / 3600)\\n), summary AS (\\n  SELECT (started_at / 3600) * 3600 AS hour_start,\\n         SUM(verification_passes) AS passes,\\n         SUM(verification_failures) AS failures\\n  FROM session_summary\\n  GROUP BY 1\\n) SELECT h * 3600 AS time,\\n         CASE\\n           WHEN COALESCE(summary.passes, 0) + COALESCE(summary.failures, 0) = 0 THEN 100.0\\n           ELSE ROUND(100.0 * COALESCE(summary.passes, 0) / (COALESCE(summary.passes, 0) + COALESCE(summary.failures, 0)), 1)\\n         END AS verification_pass_rate\\nFROM hours\\nLEFT JOIN summary ON hours.h * 3600 = summary.hour_start\\nORDER BY time;\",\n          \"rawSql\": \"WITH RECURSIVE hours(h) AS (\\n  SELECT COALESCE((SELECT MIN(started_at) / 3600 FROM session_summary), strftime(\'%s\', \'now\') / 3600)\\n  UNION ALL\\n  SELECT h + 1 FROM hours WHERE h < COALESCE((SELECT MAX(started_at) / 3600 FROM session_summary), strftime(\'%s\', \'now\') / 3600)\\n), summary AS (\\n  SELECT (started_at / 3600) * 3600 AS hour_start,\\n         SUM(verification_passes) AS passes,\\n         SUM(verification_failures) AS failures\\n  FROM session_summary\\n  GROUP BY 1\\n) SELECT h * 3600 AS time,\\n         CASE\\n           WHEN COALESCE(summary.passes, 0) + COALESCE(summary.failures, 0) = 0 THEN 100.0\\n           ELSE ROUND(100.0 * COALESCE(summary.passes, 0) / (COALESCE(summary.passes, 0) + COALESCE(summary.failures, 0)), 1)\\n         END AS verification_pass_rate\\nFROM hours\\nLEFT JOIN summary ON hours.h * 3600 = summary.hour_start\\nORDER BY time;\",\n          \"refId\": \"A\",\n          \"timeColumns\": [\n            \"time\"\n          ]\n        }\n      ],\n      \"title\": \"Verification Pass Rate Over Time\",\n      \"type\": \"timeseries\"\n    },\n    {\n      \"collapsed\": false,\n      \"gridPos\": {\n        \"h\": 1,\n        \"w\": 24,\n        \"x\": 0,\n        \"y\": 87\n      },\n      \"id\": 115,\n      \"title\": \"Tact Engine\",\n      \"type\": \"row\"\n    },\n    {\n      \"datasource\": {\n        \"type\": \"frser-sqlite-datasource\",\n        \"uid\": \"batty-telemetry\"\n      },\n      \"fieldConfig\": {\n        \"defaults\": {\n          \"custom\": {\n            \"fillOpacity\": 12,\n            \"lineWidth\": 2\n          }\n        }\n      },\n      \"gridPos\": {\n        \"h\": 8,\n        \"w\": 12,\n        \"x\": 0,\n        \"y\": 88\n      },\n      \"id\": 116,\n      \"targets\": [\n        {\n          \"datasource\": {\n            \"type\": \"frser-sqlite-datasource\",\n            \"uid\": \"batty-telemetry\"\n          },\n          \"queryText\": \"WITH RECURSIVE hours(h) AS ( SELECT COALESCE(MIN(timestamp) / 3600, strftime(\'%s\', \'now\') / 3600) FROM events UNION ALL SELECT h + 1 FROM hours WHERE h < (SELECT COALESCE(MAX(timestamp) / 3600, strftime(\'%s\', \'now\') / 3600) FROM events) ) SELECT h * 3600 AS time, COALESCE(e.cnt, 0) AS triggered FROM hours LEFT JOIN (SELECT timestamp / 3600 AS hr, COUNT(*) AS cnt FROM events WHERE event_type=\'tact_cycle_triggered\' GROUP BY hr) e ON hours.h = e.hr ORDER BY time;\",\n          \"queryType\": \"table\",\n          \"rawQueryText\": \"WITH RECURSIVE hours(h) AS ( SELECT COALESCE(MIN(timestamp) / 3600, strftime(\'%s\', \'now\') / 3600) FROM events UNION ALL SELECT h + 1 FROM hours WHERE h < (SELECT COALESCE(MAX(timestamp) / 3600, strftime(\'%s\', \'now\') / 3600) FROM events) ) SELECT h * 3600 AS time, COALESCE(e.cnt, 0) AS triggered FROM hours LEFT JOIN (SELECT timestamp / 3600 AS hr, COUNT(*) AS cnt FROM events WHERE event_type=\'tact_cycle_triggered\' GROUP BY hr) e ON hours.h = e.hr ORDER BY time;\",\n          \"rawSql\": \"WITH RECURSIVE hours(h) AS ( SELECT COALESCE(MIN(timestamp) / 3600, strftime(\'%s\', \'now\') / 3600) FROM events UNION ALL SELECT h + 1 FROM hours WHERE h < (SELECT COALESCE(MAX(timestamp) / 3600, strftime(\'%s\', \'now\') / 3600) FROM events) ) SELECT h * 3600 AS time, COALESCE(e.cnt, 0) AS triggered FROM hours LEFT JOIN (SELECT timestamp / 3600 AS hr, COUNT(*) AS cnt FROM events WHERE event_type=\'tact_cycle_triggered\' GROUP BY hr) e ON hours.h = e.hr ORDER BY time;\",\n          \"refId\": \"A\",\n          \"timeColumns\": [\n            \"time\"\n          ]\n        }\n      ],\n      \"title\": \"Planning Cycles Triggered Per Hour\",\n      \"type\": \"timeseries\"\n    },\n    {\n      \"datasource\": {\n        \"type\": \"frser-sqlite-datasource\",\n        \"uid\": \"batty-telemetry\"\n      },\n      \"fieldConfig\": {\n        \"defaults\": {}\n      },\n      \"gridPos\": {\n        \"h\": 8,\n        \"w\": 12,\n        \"x\": 12,\n        \"y\": 88\n      },\n      \"id\": 117,\n      \"targets\": [\n        {\n          \"datasource\": {\n            \"type\": \"frser-sqlite-datasource\",\n            \"uid\": \"batty-telemetry\"\n          },\n          \"queryText\": \"SELECT timestamp AS time, COALESCE(CAST(json_extract(payload, \'$.restart_count\') AS INTEGER), 0) AS tasks_created FROM events WHERE event_type=\'tact_tasks_created\' AND json_extract(payload, \'$.reason\')=\'success\' ORDER BY time;\",\n          \"queryType\": \"table\",\n          \"rawQueryText\": \"SELECT timestamp AS time, COALESCE(CAST(json_extract(payload, \'$.restart_count\') AS INTEGER), 0) AS tasks_created FROM events WHERE event_type=\'tact_tasks_created\' AND json_extract(payload, \'$.reason\')=\'success\' ORDER BY time;\",\n          \"rawSql\": \"SELECT timestamp AS time, COALESCE(CAST(json_extract(payload, \'$.restart_count\') AS INTEGER), 0) AS tasks_created FROM events WHERE event_type=\'tact_tasks_created\' AND json_extract(payload, \'$.reason\')=\'success\' ORDER BY time;\",\n          \"refId\": \"A\"\n        }\n      ],\n      \"title\": \"Tasks Created Per Planning Cycle\",\n      \"type\": \"barchart\"\n    },\n    {\n      \"datasource\": {\n        \"type\": \"frser-sqlite-datasource\",\n        \"uid\": \"batty-telemetry\"\n      },\n      \"fieldConfig\": {\n        \"defaults\": {\n          \"custom\": {\n            \"fillOpacity\": 10,\n            \"lineWidth\": 2\n          },\n          \"unit\": \"s\"\n        }\n      },\n      \"gridPos\": {\n        \"h\": 8,\n        \"w\": 12,\n        \"x\": 0,\n        \"y\": 96\n      },\n      \"id\": 118,\n      \"targets\": [\n        {\n          \"datasource\": {\n            \"type\": \"frser-sqlite-datasource\",\n            \"uid\": \"batty-telemetry\"\n          },\n          \"queryText\": \"SELECT timestamp AS time, COALESCE(CAST(json_extract(payload, \'$.uptime_secs\') AS INTEGER), 0) AS latency_secs FROM events WHERE event_type=\'tact_tasks_created\' ORDER BY time;\",\n          \"queryType\": \"table\",\n          \"rawQueryText\": \"SELECT timestamp AS time, COALESCE(CAST(json_extract(payload, \'$.uptime_secs\') AS INTEGER), 0) AS latency_secs FROM events WHERE event_type=\'tact_tasks_created\' ORDER BY time;\",\n          \"rawSql\": \"SELECT timestamp AS time, COALESCE(CAST(json_extract(payload, \'$.uptime_secs\') AS INTEGER), 0) AS latency_secs FROM events WHERE event_type=\'tact_tasks_created\' ORDER BY time;\",\n          \"refId\": \"A\",\n          \"timeColumns\": [\n            \"time\"\n          ]\n        }\n      ],\n      \"title\": \"Planning Cycle Latency\",\n      \"type\": \"timeseries\"\n    },\n    {\n      \"datasource\": {\n        \"type\": \"frser-sqlite-datasource\",\n        \"uid\": \"batty-telemetry\"\n      },\n      \"fieldConfig\": {\n        \"defaults\": {}\n      },\n      \"gridPos\": {\n        \"h\": 8,\n        \"w\": 12,\n        \"x\": 12,\n        \"y\": 96\n      },\n      \"id\": 119,\n      \"targets\": [\n        {\n          \"datasource\": {\n            \"type\": \"frser-sqlite-datasource\",\n            \"uid\": \"batty-telemetry\"\n          },\n          \"queryText\": \"SELECT CASE COALESCE(json_extract(payload, \'$.reason\'), \'unknown\') WHEN \'success\' THEN \'success\' WHEN \'failure\' THEN \'failure\' ELSE \'unknown\' END AS metric, COUNT(*) AS value FROM events WHERE event_type=\'tact_tasks_created\' GROUP BY metric ORDER BY value DESC;\",\n          \"queryType\": \"table\",\n          \"rawQueryText\": \"SELECT CASE COALESCE(json_extract(payload, \'$.reason\'), \'unknown\') WHEN \'success\' THEN \'success\' WHEN \'failure\' THEN \'failure\' ELSE \'unknown\' END AS metric, COUNT(*) AS value FROM events WHERE event_type=\'tact_tasks_created\' GROUP BY metric ORDER BY value DESC;\",\n          \"rawSql\": \"SELECT CASE COALESCE(json_extract(payload, \'$.reason\'), \'unknown\') WHEN \'success\' THEN \'success\' WHEN \'failure\' THEN \'failure\' ELSE \'unknown\' END AS metric, COUNT(*) AS value FROM events WHERE event_type=\'tact_tasks_created\' GROUP BY metric ORDER BY value DESC;\",\n          \"refId\": \"A\"\n        }\n      ],\n      \"title\": \"Planning Cycle Success vs Failure\",\n      \"type\": \"piechart\"\n    },\n    {\n      \"collapsed\": false,\n      \"gridPos\": {\n        \"h\": 1,\n        \"w\": 24,\n        \"x\": 0,\n        \"y\": 104\n      },\n      \"id\": 120,\n      \"title\": \"Health Signals\",\n      \"type\": \"row\"\n    },\n    {\n      \"datasource\": {\n        \"type\": \"frser-sqlite-datasource\",\n        \"uid\": \"batty-telemetry\"\n      },\n      \"fieldConfig\": {\n        \"defaults\": {\n          \"custom\": {\n            \"drawStyle\": \"line\",\n            \"fillOpacity\": 10,\n            \"lineWidth\": 2,\n            \"stacking\": {\n              \"mode\": \"normal\",\n              \"group\": \"A\"\n            }\n          }\n        }\n      },\n      \"gridPos\": {\n        \"h\": 8,\n        \"w\": 12,\n        \"x\": 0,\n        \"y\": 105\n      },\n      \"id\": 121,\n      \"targets\": [\n        {\n          \"datasource\": {\n            \"type\": \"frser-sqlite-datasource\",\n            \"uid\": \"batty-telemetry\"\n          },\n          \"queryText\": \"SELECT timestamp AS time, COUNT(*) AS detections, role AS metric FROM events WHERE event_type=\'narration_loop_detected\' GROUP BY timestamp, role ORDER BY time;\",\n          \"queryType\": \"table\",\n          \"rawQueryText\": \"SELECT timestamp AS time, COUNT(*) AS detections, role AS metric FROM events WHERE event_type=\'narration_loop_detected\' GROUP BY timestamp, role ORDER BY time;\",\n          \"rawSql\": \"SELECT timestamp AS time, COUNT(*) AS detections, role AS metric FROM events WHERE event_type=\'narration_loop_detected\' GROUP BY timestamp, role ORDER BY time;\",\n          \"refId\": \"A\",\n          \"timeColumns\": [\n            \"time\"\n          ]\n        }\n      ],\n      \"title\": \"Narration Events Detected Per Agent\",\n      \"type\": \"timeseries\"\n    },\n    {\n      \"datasource\": {\n        \"type\": \"frser-sqlite-datasource\",\n        \"uid\": \"batty-telemetry\"\n      },\n      \"fieldConfig\": {\n        \"defaults\": {\n          \"custom\": {\n            \"fillOpacity\": 12,\n            \"lineWidth\": 2\n          }\n        }\n      },\n      \"gridPos\": {\n        \"h\": 8,\n        \"w\": 12,\n        \"x\": 12,\n        \"y\": 105\n      },\n      \"id\": 122,\n      \"targets\": [\n        {\n          \"datasource\": {\n            \"type\": \"frser-sqlite-datasource\",\n            \"uid\": \"batty-telemetry\"\n          },\n          \"queryText\": \"WITH RECURSIVE hours(h) AS ( SELECT COALESCE(MIN(timestamp) / 3600, strftime(\'%s\', \'now\') / 3600) FROM events UNION ALL SELECT h + 1 FROM hours WHERE h < (SELECT COALESCE(MAX(timestamp) / 3600, strftime(\'%s\', \'now\') / 3600) FROM events) ) SELECT h * 3600 AS time, COALESCE(e.cnt, 0) AS restarts FROM hours LEFT JOIN (SELECT timestamp / 3600 AS hr, COUNT(*) AS cnt FROM events WHERE event_type=\'agent_restarted\' AND json_extract(payload, \'$.reason\')=\'narration\' GROUP BY hr) e ON hours.h = e.hr ORDER BY time;\",\n          \"queryType\": \"table\",\n          \"rawQueryText\": \"WITH RECURSIVE hours(h) AS ( SELECT COALESCE(MIN(timestamp) / 3600, strftime(\'%s\', \'now\') / 3600) FROM events UNION ALL SELECT h + 1 FROM hours WHERE h < (SELECT COALESCE(MAX(timestamp) / 3600, strftime(\'%s\', \'now\') / 3600) FROM events) ) SELECT h * 3600 AS time, COALESCE(e.cnt, 0) AS restarts FROM hours LEFT JOIN (SELECT timestamp / 3600 AS hr, COUNT(*) AS cnt FROM events WHERE event_type=\'agent_restarted\' AND json_extract(payload, \'$.reason\')=\'narration\' GROUP BY hr) e ON hours.h = e.hr ORDER BY time;\",\n          \"rawSql\": \"WITH RECURSIVE hours(h) AS ( SELECT COALESCE(MIN(timestamp) / 3600, strftime(\'%s\', \'now\') / 3600) FROM events UNION ALL SELECT h + 1 FROM hours WHERE h < (SELECT COALESCE(MAX(timestamp) / 3600, strftime(\'%s\', \'now\') / 3600) FROM events) ) SELECT h * 3600 AS time, COALESCE(e.cnt, 0) AS restarts FROM hours LEFT JOIN (SELECT timestamp / 3600 AS hr, COUNT(*) AS cnt FROM events WHERE event_type=\'agent_restarted\' AND json_extract(payload, \'$.reason\')=\'narration\' GROUP BY hr) e ON hours.h = e.hr ORDER BY time;\",\n          \"refId\": \"A\",\n          \"timeColumns\": [\n            \"time\"\n          ]\n        }\n      ],\n      \"title\": \"Narration-Triggered Restarts Per Hour\",\n      \"type\": \"timeseries\"\n    },\n    {\n      \"datasource\": {\n        \"type\": \"frser-sqlite-datasource\",\n        \"uid\": \"batty-telemetry\"\n      },\n      \"fieldConfig\": {\n        \"defaults\": {\n          \"unit\": \"s\",\n          \"min\": 0\n        }\n      },\n      \"gridPos\": {\n        \"h\": 8,\n        \"w\": 12,\n        \"x\": 0,\n        \"y\": 113\n      },\n      \"id\": 123,\n      \"targets\": [\n        {\n          \"datasource\": {\n            \"type\": \"frser-sqlite-datasource\",\n            \"uid\": \"batty-telemetry\"\n          },\n          \"queryText\": \"SELECT COALESCE(ROUND(AVG(n.timestamp - a.timestamp), 1), 0) AS value FROM events n LEFT JOIN events a ON a.role = n.role AND a.task_id = n.task_id AND a.event_type=\'task_assigned\' AND a.timestamp <= n.timestamp WHERE n.event_type=\'narration_loop_detected\';\",\n          \"queryType\": \"table\",\n          \"rawQueryText\": \"SELECT COALESCE(ROUND(AVG(n.timestamp - a.timestamp), 1), 0) AS value FROM events n LEFT JOIN events a ON a.role = n.role AND a.task_id = n.task_id AND a.event_type=\'task_assigned\' AND a.timestamp <= n.timestamp WHERE n.event_type=\'narration_loop_detected\';\",\n          \"rawSql\": \"SELECT COALESCE(ROUND(AVG(n.timestamp - a.timestamp), 1), 0) AS value FROM events n LEFT JOIN events a ON a.role = n.role AND a.task_id = n.task_id AND a.event_type=\'task_assigned\' AND a.timestamp <= n.timestamp WHERE n.event_type=\'narration_loop_detected\';\",\n          \"refId\": \"A\"\n        }\n      ],\n      \"title\": \"Average Narration Duration Before Detection\",\n      \"type\": \"gauge\"\n    },\n    {\n      \"datasource\": {\n        \"type\": \"frser-sqlite-datasource\",\n        \"uid\": \"batty-telemetry\"\n      },\n      \"fieldConfig\": {\n        \"defaults\": {\n          \"custom\": {\n            \"drawStyle\": \"line\",\n            \"fillOpacity\": 10,\n            \"lineWidth\": 2,\n            \"stacking\": {\n              \"mode\": \"normal\",\n              \"group\": \"B\"\n            }\n          }\n        }\n      },\n      \"gridPos\": {\n        \"h\": 8,\n        \"w\": 12,\n        \"x\": 12,\n        \"y\": 113\n      },\n      \"id\": 124,\n      \"targets\": [\n        {\n          \"datasource\": {\n            \"type\": \"frser-sqlite-datasource\",\n            \"uid\": \"batty-telemetry\"\n          },\n          \"queryText\": \"SELECT timestamp AS time, COUNT(*) AS warnings, role AS metric FROM events WHERE event_type=\'context_pressure_warning\' GROUP BY timestamp, role ORDER BY time;\",\n          \"queryType\": \"table\",\n          \"rawQueryText\": \"SELECT timestamp AS time, COUNT(*) AS warnings, role AS metric FROM events WHERE event_type=\'context_pressure_warning\' GROUP BY timestamp, role ORDER BY time;\",\n          \"rawSql\": \"SELECT timestamp AS time, COUNT(*) AS warnings, role AS metric FROM events WHERE event_type=\'context_pressure_warning\' GROUP BY timestamp, role ORDER BY time;\",\n          \"refId\": \"A\",\n          \"timeColumns\": [\n            \"time\"\n          ]\n        }\n      ],\n      \"title\": \"Context Pressure Warnings Per Agent\",\n      \"type\": \"timeseries\"\n    },\n    {\n      \"datasource\": {\n        \"type\": \"frser-sqlite-datasource\",\n        \"uid\": \"batty-telemetry\"\n      },\n      \"fieldConfig\": {\n        \"defaults\": {\n          \"custom\": {\n            \"fillOpacity\": 12,\n            \"lineWidth\": 2\n          }\n        }\n      },\n      \"gridPos\": {\n        \"h\": 8,\n        \"w\": 12,\n        \"x\": 0,\n        \"y\": 121\n      },\n      \"id\": 125,\n      \"targets\": [\n        {\n          \"datasource\": {\n            \"type\": \"frser-sqlite-datasource\",\n            \"uid\": \"batty-telemetry\"\n          },\n          \"queryText\": \"WITH RECURSIVE hours(h) AS ( SELECT COALESCE(MIN(timestamp) / 3600, strftime(\'%s\', \'now\') / 3600) FROM events UNION ALL SELECT h + 1 FROM hours WHERE h < (SELECT COALESCE(MAX(timestamp) / 3600, strftime(\'%s\', \'now\') / 3600) FROM events) ) SELECT h * 3600 AS time, COALESCE(e.cnt, 0) AS restarts FROM hours LEFT JOIN (SELECT timestamp / 3600 AS hr, COUNT(*) AS cnt FROM events WHERE event_type=\'agent_restarted\' AND json_extract(payload, \'$.reason\')=\'context_pressure\' GROUP BY hr) e ON hours.h = e.hr ORDER BY time;\",\n          \"queryType\": \"table\",\n          \"rawQueryText\": \"WITH RECURSIVE hours(h) AS ( SELECT COALESCE(MIN(timestamp) / 3600, strftime(\'%s\', \'now\') / 3600) FROM events UNION ALL SELECT h + 1 FROM hours WHERE h < (SELECT COALESCE(MAX(timestamp) / 3600, strftime(\'%s\', \'now\') / 3600) FROM events) ) SELECT h * 3600 AS time, COALESCE(e.cnt, 0) AS restarts FROM hours LEFT JOIN (SELECT timestamp / 3600 AS hr, COUNT(*) AS cnt FROM events WHERE event_type=\'agent_restarted\' AND json_extract(payload, \'$.reason\')=\'context_pressure\' GROUP BY hr) e ON hours.h = e.hr ORDER BY time;\",\n          \"rawSql\": \"WITH RECURSIVE hours(h) AS ( SELECT COALESCE(MIN(timestamp) / 3600, strftime(\'%s\', \'now\') / 3600) FROM events UNION ALL SELECT h + 1 FROM hours WHERE h < (SELECT COALESCE(MAX(timestamp) / 3600, strftime(\'%s\', \'now\') / 3600) FROM events) ) SELECT h * 3600 AS time, COALESCE(e.cnt, 0) AS restarts FROM hours LEFT JOIN (SELECT timestamp / 3600 AS hr, COUNT(*) AS cnt FROM events WHERE event_type=\'agent_restarted\' AND json_extract(payload, \'$.reason\')=\'context_pressure\' GROUP BY hr) e ON hours.h = e.hr ORDER BY time;\",\n          \"refId\": \"A\",\n          \"timeColumns\": [\n            \"time\"\n          ]\n        }\n      ],\n      \"title\": \"Context-Triggered Restarts Per Hour\",\n      \"type\": \"timeseries\"\n    },\n    {\n      \"datasource\": {\n        \"type\": \"frser-sqlite-datasource\",\n        \"uid\": \"batty-telemetry\"\n      },\n      \"fieldConfig\": {\n        \"defaults\": {\n          \"custom\": {\n            \"drawStyle\": \"line\",\n            \"fillOpacity\": 8,\n            \"lineWidth\": 2\n          }\n        }\n      },\n      \"gridPos\": {\n        \"h\": 8,\n        \"w\": 12,\n        \"x\": 12,\n        \"y\": 121\n      },\n      \"id\": 126,\n      \"targets\": [\n        {\n          \"datasource\": {\n            \"type\": \"frser-sqlite-datasource\",\n            \"uid\": \"batty-telemetry\"\n          },\n          \"queryText\": \"SELECT timestamp AS time, COALESCE(CAST(json_extract(payload, \'$.load\') AS REAL), 0) AS pressure_score, role AS metric FROM events WHERE event_type=\'context_pressure_warning\' ORDER BY time;\",\n          \"queryType\": \"table\",\n          \"rawQueryText\": \"SELECT timestamp AS time, COALESCE(CAST(json_extract(payload, \'$.load\') AS REAL), 0) AS pressure_score, role AS metric FROM events WHERE event_type=\'context_pressure_warning\' ORDER BY time;\",\n          \"rawSql\": \"SELECT timestamp AS time, COALESCE(CAST(json_extract(payload, \'$.load\') AS REAL), 0) AS pressure_score, role AS metric FROM events WHERE event_type=\'context_pressure_warning\' ORDER BY time;\",\n          \"refId\": \"A\",\n          \"timeColumns\": [\n            \"time\"\n          ]\n        }\n      ],\n      \"title\": \"Context Pressure Score\",\n      \"type\": \"timeseries\"\n    },\n    {\n      \"collapsed\": false,\n      \"gridPos\": {\n        \"h\": 1,\n        \"w\": 24,\n        \"x\": 0,\n        \"y\": 129\n      },\n      \"id\": 127,\n      \"title\": \"Board Health\",\n      \"type\": \"row\"\n    },\n    {\n      \"datasource\": {\n        \"type\": \"frser-sqlite-datasource\",\n        \"uid\": \"batty-telemetry\"\n      },\n      \"fieldConfig\": {\n        \"defaults\": {\n          \"custom\": {\n            \"fillOpacity\": 14,\n            \"lineWidth\": 2,\n            \"stacking\": {\n              \"mode\": \"normal\",\n              \"group\": \"C\"\n            }\n          }\n        }\n      },\n      \"gridPos\": {\n        \"h\": 8,\n        \"w\": 12,\n        \"x\": 0,\n        \"y\": 130\n      },\n      \"id\": 128,\n      \"targets\": [\n        {\n          \"datasource\": {\n            \"type\": \"frser-sqlite-datasource\",\n            \"uid\": \"batty-telemetry\"\n          },\n          \"queryText\": \"WITH RECURSIVE hours(h) AS ( SELECT COALESCE(MIN(timestamp) / 3600, strftime(\'%s\', \'now\') / 3600) FROM events UNION ALL SELECT h + 1 FROM hours WHERE h < (SELECT COALESCE(MAX(timestamp) / 3600, strftime(\'%s\', \'now\') / 3600) FROM events) ) SELECT h * 3600 AS time, (SELECT COUNT(*) FROM events e2 WHERE e2.event_type=\'task_assigned\' AND e2.timestamp <= (h + 1) * 3600) - (SELECT COUNT(*) FROM events e3 WHERE e3.event_type=\'task_completed\' AND e3.timestamp <= (h + 1) * 3600) AS in_progress FROM hours ORDER BY time;\",\n          \"queryType\": \"table\",\n          \"rawQueryText\": \"WITH RECURSIVE hours(h) AS ( SELECT COALESCE(MIN(timestamp) / 3600, strftime(\'%s\', \'now\') / 3600) FROM events UNION ALL SELECT h + 1 FROM hours WHERE h < (SELECT COALESCE(MAX(timestamp) / 3600, strftime(\'%s\', \'now\') / 3600) FROM events) ) SELECT h * 3600 AS time, (SELECT COUNT(*) FROM events e2 WHERE e2.event_type=\'task_assigned\' AND e2.timestamp <= (h + 1) * 3600) - (SELECT COUNT(*) FROM events e3 WHERE e3.event_type=\'task_completed\' AND e3.timestamp <= (h + 1) * 3600) AS in_progress FROM hours ORDER BY time;\",\n          \"rawSql\": \"WITH RECURSIVE hours(h) AS ( SELECT COALESCE(MIN(timestamp) / 3600, strftime(\'%s\', \'now\') / 3600) FROM events UNION ALL SELECT h + 1 FROM hours WHERE h < (SELECT COALESCE(MAX(timestamp) / 3600, strftime(\'%s\', \'now\') / 3600) FROM events) ) SELECT h * 3600 AS time, (SELECT COUNT(*) FROM events e2 WHERE e2.event_type=\'task_assigned\' AND e2.timestamp <= (h + 1) * 3600) - (SELECT COUNT(*) FROM events e3 WHERE e3.event_type=\'task_completed\' AND e3.timestamp <= (h + 1) * 3600) AS in_progress FROM hours ORDER BY time;\",\n          \"refId\": \"A\",\n          \"timeColumns\": [\n            \"time\"\n          ]\n        },\n        {\n          \"datasource\": {\n            \"type\": \"frser-sqlite-datasource\",\n            \"uid\": \"batty-telemetry\"\n          },\n          \"queryText\": \"WITH RECURSIVE hours(h) AS ( SELECT COALESCE(MIN(timestamp) / 3600, strftime(\'%s\', \'now\') / 3600) FROM events UNION ALL SELECT h + 1 FROM hours WHERE h < (SELECT COALESCE(MAX(timestamp) / 3600, strftime(\'%s\', \'now\') / 3600) FROM events) ) SELECT h * 3600 AS time, (SELECT COUNT(*) FROM events e2 WHERE e2.event_type=\'task_completed\' AND e2.timestamp <= (h + 1) * 3600) - (SELECT COUNT(*) FROM events e3 WHERE e3.event_type=\'board_task_archived\' AND e3.timestamp <= (h + 1) * 3600) AS done FROM hours ORDER BY time;\",\n          \"queryType\": \"table\",\n          \"rawQueryText\": \"WITH RECURSIVE hours(h) AS ( SELECT COALESCE(MIN(timestamp) / 3600, strftime(\'%s\', \'now\') / 3600) FROM events UNION ALL SELECT h + 1 FROM hours WHERE h < (SELECT COALESCE(MAX(timestamp) / 3600, strftime(\'%s\', \'now\') / 3600) FROM events) ) SELECT h * 3600 AS time, (SELECT COUNT(*) FROM events e2 WHERE e2.event_type=\'task_completed\' AND e2.timestamp <= (h + 1) * 3600) - (SELECT COUNT(*) FROM events e3 WHERE e3.event_type=\'board_task_archived\' AND e3.timestamp <= (h + 1) * 3600) AS done FROM hours ORDER BY time;\",\n          \"rawSql\": \"WITH RECURSIVE hours(h) AS ( SELECT COALESCE(MIN(timestamp) / 3600, strftime(\'%s\', \'now\') / 3600) FROM events UNION ALL SELECT h + 1 FROM hours WHERE h < (SELECT COALESCE(MAX(timestamp) / 3600, strftime(\'%s\', \'now\') / 3600) FROM events) ) SELECT h * 3600 AS time, (SELECT COUNT(*) FROM events e2 WHERE e2.event_type=\'task_completed\' AND e2.timestamp <= (h + 1) * 3600) - (SELECT COUNT(*) FROM events e3 WHERE e3.event_type=\'board_task_archived\' AND e3.timestamp <= (h + 1) * 3600) AS done FROM hours ORDER BY time;\",\n          \"refId\": \"B\",\n          \"timeColumns\": [\n            \"time\"\n          ]\n        },\n        {\n          \"datasource\": {\n            \"type\": \"frser-sqlite-datasource\",\n            \"uid\": \"batty-telemetry\"\n          },\n          \"queryText\": \"WITH RECURSIVE hours(h) AS ( SELECT COALESCE(MIN(timestamp) / 3600, strftime(\'%s\', \'now\') / 3600) FROM events UNION ALL SELECT h + 1 FROM hours WHERE h < (SELECT COALESCE(MAX(timestamp) / 3600, strftime(\'%s\', \'now\') / 3600) FROM events) ) SELECT h * 3600 AS time, (SELECT COUNT(*) FROM events e2 WHERE e2.event_type=\'board_task_archived\' AND e2.timestamp <= (h + 1) * 3600) AS archived FROM hours ORDER BY time;\",\n          \"queryType\": \"table\",\n          \"rawQueryText\": \"WITH RECURSIVE hours(h) AS ( SELECT COALESCE(MIN(timestamp) / 3600, strftime(\'%s\', \'now\') / 3600) FROM events UNION ALL SELECT h + 1 FROM hours WHERE h < (SELECT COALESCE(MAX(timestamp) / 3600, strftime(\'%s\', \'now\') / 3600) FROM events) ) SELECT h * 3600 AS time, (SELECT COUNT(*) FROM events e2 WHERE e2.event_type=\'board_task_archived\' AND e2.timestamp <= (h + 1) * 3600) AS archived FROM hours ORDER BY time;\",\n          \"rawSql\": \"WITH RECURSIVE hours(h) AS ( SELECT COALESCE(MIN(timestamp) / 3600, strftime(\'%s\', \'now\') / 3600) FROM events UNION ALL SELECT h + 1 FROM hours WHERE h < (SELECT COALESCE(MAX(timestamp) / 3600, strftime(\'%s\', \'now\') / 3600) FROM events) ) SELECT h * 3600 AS time, (SELECT COUNT(*) FROM events e2 WHERE e2.event_type=\'board_task_archived\' AND e2.timestamp <= (h + 1) * 3600) AS archived FROM hours ORDER BY time;\",\n          \"refId\": \"C\",\n          \"timeColumns\": [\n            \"time\"\n          ]\n        }\n      ],\n      \"title\": \"Board Task Count by Status Over Time\",\n      \"type\": \"timeseries\"\n    },\n    {\n      \"datasource\": {\n        \"type\": \"frser-sqlite-datasource\",\n        \"uid\": \"batty-telemetry\"\n      },\n      \"fieldConfig\": {\n        \"defaults\": {\n          \"unit\": \"s\"\n        }\n      },\n      \"gridPos\": {\n        \"h\": 8,\n        \"w\": 12,\n        \"x\": 12,\n        \"y\": 130\n      },\n      \"id\": 129,\n      \"targets\": [\n        {\n          \"datasource\": {\n            \"type\": \"frser-sqlite-datasource\",\n            \"uid\": \"batty-telemetry\"\n          },\n          \"queryText\": \"WITH stage_metrics AS ( SELECT \'in_progress\' AS stage, AVG(completed_at - started_at) AS avg_secs FROM task_metrics WHERE started_at IS NOT NULL AND completed_at IS NOT NULL UNION ALL SELECT \'done\' AS stage, AVG(a.timestamp - tm.completed_at) AS avg_secs FROM task_metrics tm JOIN events a ON a.task_id = tm.task_id AND a.event_type=\'board_task_archived\' WHERE tm.completed_at IS NOT NULL ) SELECT stage, ROUND(COALESCE(avg_secs, 0), 1) AS value FROM stage_metrics;\",\n          \"queryType\": \"table\",\n          \"rawQueryText\": \"WITH stage_metrics AS ( SELECT \'in_progress\' AS stage, AVG(completed_at - started_at) AS avg_secs FROM task_metrics WHERE started_at IS NOT NULL AND completed_at IS NOT NULL UNION ALL SELECT \'done\' AS stage, AVG(a.timestamp - tm.completed_at) AS avg_secs FROM task_metrics tm JOIN events a ON a.task_id = tm.task_id AND a.event_type=\'board_task_archived\' WHERE tm.completed_at IS NOT NULL ) SELECT stage, ROUND(COALESCE(avg_secs, 0), 1) AS value FROM stage_metrics;\",\n          \"rawSql\": \"WITH stage_metrics AS ( SELECT \'in_progress\' AS stage, AVG(completed_at - started_at) AS avg_secs FROM task_metrics WHERE started_at IS NOT NULL AND completed_at IS NOT NULL UNION ALL SELECT \'done\' AS stage, AVG(a.timestamp - tm.completed_at) AS avg_secs FROM task_metrics tm JOIN events a ON a.task_id = tm.task_id AND a.event_type=\'board_task_archived\' WHERE tm.completed_at IS NOT NULL ) SELECT stage, ROUND(COALESCE(avg_secs, 0), 1) AS value FROM stage_metrics;\",\n          \"refId\": \"A\"\n        }\n      ],\n      \"title\": \"Average Time in Status by Lifecycle Stage\",\n      \"type\": \"barchart\"\n    },\n    {\n      \"datasource\": {\n        \"type\": \"frser-sqlite-datasource\",\n        \"uid\": \"batty-telemetry\"\n      },\n      \"fieldConfig\": {\n        \"defaults\": {\n          \"custom\": {\n            \"fillOpacity\": 12,\n            \"lineWidth\": 2\n          }\n        }\n      },\n      \"gridPos\": {\n        \"h\": 8,\n        \"w\": 12,\n        \"x\": 0,\n        \"y\": 138\n      },\n      \"id\": 130,\n      \"targets\": [\n        {\n          \"datasource\": {\n            \"type\": \"frser-sqlite-datasource\",\n            \"uid\": \"batty-telemetry\"\n          },\n          \"queryText\": \"WITH RECURSIVE hours(h) AS ( SELECT COALESCE(MIN(timestamp) / 3600, strftime(\'%s\', \'now\') / 3600) FROM events UNION ALL SELECT h + 1 FROM hours WHERE h < (SELECT COALESCE(MAX(timestamp) / 3600, strftime(\'%s\', \'now\') / 3600) FROM events) ) SELECT h * 3600 AS time, COALESCE(e.cnt, 0) AS archived FROM hours LEFT JOIN (SELECT timestamp / 3600 AS hr, COUNT(*) AS cnt FROM events WHERE event_type=\'board_task_archived\' GROUP BY hr) e ON hours.h = e.hr ORDER BY time;\",\n          \"queryType\": \"table\",\n          \"rawQueryText\": \"WITH RECURSIVE hours(h) AS ( SELECT COALESCE(MIN(timestamp) / 3600, strftime(\'%s\', \'now\') / 3600) FROM events UNION ALL SELECT h + 1 FROM hours WHERE h < (SELECT COALESCE(MAX(timestamp) / 3600, strftime(\'%s\', \'now\') / 3600) FROM events) ) SELECT h * 3600 AS time, COALESCE(e.cnt, 0) AS archived FROM hours LEFT JOIN (SELECT timestamp / 3600 AS hr, COUNT(*) AS cnt FROM events WHERE event_type=\'board_task_archived\' GROUP BY hr) e ON hours.h = e.hr ORDER BY time;\",\n          \"rawSql\": \"WITH RECURSIVE hours(h) AS ( SELECT COALESCE(MIN(timestamp) / 3600, strftime(\'%s\', \'now\') / 3600) FROM events UNION ALL SELECT h + 1 FROM hours WHERE h < (SELECT COALESCE(MAX(timestamp) / 3600, strftime(\'%s\', \'now\') / 3600) FROM events) ) SELECT h * 3600 AS time, COALESCE(e.cnt, 0) AS archived FROM hours LEFT JOIN (SELECT timestamp / 3600 AS hr, COUNT(*) AS cnt FROM events WHERE event_type=\'board_task_archived\' GROUP BY hr) e ON hours.h = e.hr ORDER BY time;\",\n          \"refId\": \"A\",\n          \"timeColumns\": [\n            \"time\"\n          ]\n        }\n      ],\n      \"title\": \"Tasks Archived Per Hour\",\n      \"type\": \"timeseries\"\n    }\n  ],\n  \"refresh\": \"30s\",\n  \"schemaVersion\": 39,\n  \"time\": {\n    \"from\": \"now-24h\",\n    \"to\": \"now\"\n  },\n  \"title\": \"Batty \u{2014} Nether Earth\",\n  \"uid\": \"batty-project\"\n}\n";
Expand description

Raw JSON for the Grafana dashboard template.