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.