{
  "generated_at": "2026-06-03T13:11:18+00:00",
  "mode": "hourly",
  "overall_status": "ok",
  "failure_count": 0,
  "summary": {
    "meeting_manifest_count": 515,
    "meeting_transcripts": 508,
    "youtube_uploads": 31,
    "youtube_channel_pull": 31,
    "youtube_captions": 0,
    "official_video_records": 515,
    "news_items": 72,
    "news_sources": 12,
    "search_records": 737,
    "finance_transcripts": 81,
    "agenda_packets": 24
  },
  "jobs": [
    {
      "name": "Discover agenda packets and build audit pages",
      "command": [
        "python3",
        "/usr/local/bin/exposemiamiok_agenda_packet_auto.py"
      ],
      "started_at": "2026-06-03T13:11:01+00:00",
      "status": "ok",
      "exit_code": 0,
      "duration_seconds": 4.99,
      "stdout_tail": "agenda packet auto: discovered=24 rendered=24\n",
      "stderr_tail": ""
    },
    {
      "name": "Crawl official Miami Web TV videos",
      "command": [
        "python3",
        "/opt/crawl_miamiok_videos.py"
      ],
      "started_at": "2026-06-03T13:11:06+00:00",
      "status": "ok",
      "exit_code": 0,
      "duration_seconds": 1.74,
      "stdout_tail": "Crawled 515 official Granicus videos\nMerged manifest now has 515 meetings\nWrote /opt/miamiok-granicus-videos.json\n",
      "stderr_tail": ""
    },
    {
      "name": "Rebuild official/YouTube video API",
      "command": [
        "python3",
        "/opt/gen_videos_json.py"
      ],
      "started_at": "2026-06-03T13:11:07+00:00",
      "status": "ok",
      "exit_code": 0,
      "duration_seconds": 0.07,
      "stdout_tail": "Generated /var/www/exposemiamiok/html/api/videos.json with 515 videos (31 YouTube uploads)\n",
      "stderr_tail": ""
    },
    {
      "name": "Pull YouTube channel uploads from YouTube API",
      "command": [
        "python3",
        "/usr/local/bin/exposemiamiok_youtube_feed_build.py"
      ],
      "started_at": "2026-06-03T13:11:08+00:00",
      "status": "ok",
      "exit_code": 0,
      "duration_seconds": 1.35,
      "stdout_tail": "youtube feed build: pulled=31 playlist=UUPEzVd4eQtJyVtOMt327PVA wrote=/var/www/exposemiamiok/html/youtube.html\n",
      "stderr_tail": ""
    },
    {
      "name": "Rebuild public videos page",
      "command": [
        "python3",
        "/opt/youtube_gallery.py"
      ],
      "started_at": "2026-06-03T13:11:09+00:00",
      "status": "ok",
      "exit_code": 0,
      "duration_seconds": 0.12,
      "stdout_tail": "Generated /var/www/exposemiamiok/html/api/videos.json with 515 videos (31 YouTube uploads)\nWrote /var/www/exposemiamiok/html/videos.html: 515 videos, 31 YouTube, 508 transcripts\n",
      "stderr_tail": ""
    },
    {
      "name": "Refresh local news RSS feeds",
      "command": [
        "python3",
        "/usr/local/bin/exposemiamiok_news_feed_build.py"
      ],
      "started_at": "2026-06-03T13:11:09+00:00",
      "status": "ok",
      "exit_code": 0,
      "duration_seconds": 6.53,
      "stdout_tail": "wrote /var/www/exposemiamiok/html/data/local-news-feeds.json items=72 sources=12\n",
      "stderr_tail": ""
    },
    {
      "name": "Rebuild site search index",
      "command": [
        "python3",
        "/usr/local/bin/exposemiamiok_search_index_build.py"
      ],
      "started_at": "2026-06-03T13:11:16+00:00",
      "status": "ok",
      "exit_code": 0,
      "duration_seconds": 2.23,
      "stdout_tail": "wrote /var/www/exposemiamiok/html/data/site-search-index.json records=737\n",
      "stderr_tail": ""
    },
    {
      "name": "Normalize menu and logo shell",
      "command": [
        "python3",
        "/usr/local/bin/exposemiamiok_navigation_update.py"
      ],
      "started_at": "2026-06-03T13:11:18+00:00",
      "status": "ok",
      "exit_code": 0,
      "duration_seconds": 0.42,
      "stdout_tail": "full menu updated checked=664 changed=29 version=20260601-unified-menu-agenda6\n",
      "stderr_tail": ""
    },
    {
      "name": "Final menu normalization after status page write",
      "command": [
        "python3",
        "/usr/local/bin/exposemiamiok_navigation_update.py"
      ],
      "started_at": "2026-06-03T13:11:18+00:00",
      "status": "ok",
      "exit_code": 0,
      "duration_seconds": 0.41,
      "stdout_tail": "full menu updated checked=664 changed=1 version=20260601-unified-menu-agenda6\n",
      "stderr_tail": ""
    }
  ]
}