{
  "schema_version": 1,
  "status": "PASS",
  "mode": "OFFLINE_DEMO_ASSETS",
  "started_at": "2026-10-02T21:07:15.060041+00:00",
  "viewport": {
    "width": 1280,
    "height": 720
  },
  "audio": "NONE",
  "external_network": "BLOCKED",
  "outputs": {
    "backup.webm": {
      "sha256": "38b332ea7def079fb6605bc6c926513eecfe283bbd15913a15895e2951ff424f",
      "bytes": 1743972
    },
    "brief-slide-01.png": {
      "sha256": "b0173a501133a7c78057ebebbb21d79579e5029ec4574f62e101bcb351ee137b",
      "bytes": 71108
    },
    "brief-slide-02.png": {
      "sha256": "246eb22a3fbcb9f6094232747bfb4b1549156e0204d845edb508acf9224fb8ef",
      "bytes": 85787
    },
    "brief-slide-03.png": {
      "sha256": "fb5482ed69feedc4dfba0e0ac2e345df97f50cdbc9069bf4a47fd7a8d845f1b0",
      "bytes": 88699
    },
    "brief-slide-04.png": {
      "sha256": "f8e8874ef4648006bbd50a7ad3064302acff1e5e127dbc6ba6eb3c9590c11423",
      "bytes": 86691
    },
    "brief-slide-05.png": {
      "sha256": "11a88275276289f6177ab475b778ebe4fabf5e109d540a57827ba9254380a624",
      "bytes": 81739
    },
    "brief-slide-06.png": {
      "sha256": "5ac8f19c2e6916f09a40c549c5c38decbfee37fc1778765b733d1f73b04acd3b",
      "bytes": 70113
    },
    "brief-slide-07.png": {
      "sha256": "df1a969b74ac1b2474cb62f3f5d39f760b4e8f0172a18f64029d70153e890765",
      "bytes": 86552
    },
    "brief-slide-08.png": {
      "sha256": "6186e0da627ee61d290dbe60e4ccabb4a2f7619912d2e67546bfd48846db95f9",
      "bytes": 90867
    },
    "brief-slide-09.png": {
      "sha256": "c79f97d07726cf4583905c495a8196f859b07981e193169e265e72309944ab07",
      "bytes": 89055
    },
    "brief-slide-10.png": {
      "sha256": "b14a52de72036f6cf09a2fe3bdead7f5d680b2a06fb40421daca45ac5eafdb91",
      "bytes": 88614
    },
    "brief-slide-11.png": {
      "sha256": "adac2e6b058f12209ba06c58c261d6a156f49766fdfcb7887e04589031070e0f",
      "bytes": 90934
    },
    "brief-slide-12.png": {
      "sha256": "58a6790d65e2ff8df1139806b5ef407c24853e76e4565a78482b8cec352f4dab",
      "bytes": 92597
    },
    "brief.pdf": {
      "sha256": "5fa581299757b72fb0452d7b26302c87fdf45d5ae87ee8e0e8c9cbbe45a958a4",
      "bytes": 1126757
    },
    "demo-frame-01-historical_m0.png": {
      "sha256": "517de36be68e1fcb26ac3cc02ed2ea5de1c46ccf9a5e7a754e6b213a07d79965",
      "bytes": 109788
    },
    "demo-frame-02-historical_m1.png": {
      "sha256": "274d635ad7c7d9b8fc63777170da87fbed63a0aeb931d1bedfecf0eccb61187c",
      "bytes": 112937
    },
    "demo-frame-03-synthetic_interruption.png": {
      "sha256": "3c74c90ec16e1d1ef8b7a6051236d6f5e7d30af406149e2901bc1a797d20691a",
      "bytes": 128820
    },
    "demo-frame-04-fresh.png": {
      "sha256": "ddbf787a0e3c735dd90f6ffac715c2de3bca766e1d8338e7f1b8ec64e1da8005",
      "bytes": 118156
    },
    "demo-frame-05-stale.png": {
      "sha256": "683b002fb36561c2f39e202a5e136bd6f36b26d068509430ebd346ed8f98e0f1",
      "bytes": 114526
    },
    "demo-frame-06-missing.png": {
      "sha256": "826e4ea35dc2e5edd9e9bb64c43facdb488a82689d112707c12d028aa195f802",
      "bytes": 114395
    },
    "demo-frame-07-invalid.png": {
      "sha256": "94fb03a8dbe4ce7202e39afef18c93a08726aef7e178b9b83fd5aa772870de95",
      "bytes": 116972
    },
    "demo-frame-08-future.png": {
      "sha256": "6d91ccf8b3be8f05aadc8bd94a708941ff380e8513964659f1623a01bef0baea",
      "bytes": 116564
    },
    "demo-frame-09-error.png": {
      "sha256": "355c9014cab94408bf192a185fcd81493f35b0d54c97bc25883a18fb8d0c6fc0",
      "bytes": 116394
    },
    "demo-frame-10-recovered.png": {
      "sha256": "a71b06d8858906e9a802e8ba93470142d1ca0c2f755bc432a8de54daae22b484",
      "bytes": 117700
    },
    "proposal.pdf": {
      "sha256": "6ca6faf7d86644f4b6cfcf03638aac84caa4a71085381d52f720f43acf72d4c3",
      "bytes": 1030745
    },
    "proposal.png": {
      "sha256": "eb166dc42e6cd5bb6c801dceda5ec209c0498d4c930cdcc00f64ec114b005eac",
      "bytes": 620509
    },
    "video-capture/d9082235ac4ef85ae21ef1ee39cfc240.webm": {
      "sha256": "38b332ea7def079fb6605bc6c926513eecfe283bbd15913a15895e2951ff424f",
      "bytes": 1743972
    }
  },
  "limitations": [
    "固定離線快照，沒有登入、API寫入或真設備操作。",
    "M0/M1是同一事件的日曆代理；實際提前量與現場成效NOT_MEASURED。",
    "七種中斷／恢復是SIMULATED，來源fresh不是安全判定。",
    "無音訊影片；PDF與錄影為草案／備援，不表示已上傳或正式演練完成。"
  ],
  "input_hashes": {
    "offline": "680ef647801ac5773caf288c0311ae8a579abaa9c7c316757eb4e437aac20aa4",
    "snapshot": "007f5764c6aa9b1cf2a861780f2f9950e10f1150048ef503c499ebd4b15ee813",
    "receipt": "586ba87495602737ba9fa7a5d0f990f6da2c40583ab87c338f24b27ad0a3cf9f",
    "briefing": "88b218c4a565fcba30a9f762c08dbf8e2df0b76bfef52c3920755c3184fc6cf2",
    "proposal": "98ea05328ad7a2816e1f0b1e539ec719d4dd44d5cba9652ac51d9cce558c9e17"
  },
  "tool_sha256": "c07474c4d9317bc058a3a6d1c706c90d5ac7104521f492b6d5116c27327ae3fe",
  "authoring_source": {
    "commit": "869d7a0a081817f2f790e082b33bbd02c2471ebe",
    "working_tree_dirty": false
  },
  "snapshot_metadata": {
    "source_commit": "869d7a0a081817f2f790e082b33bbd02c2471ebe",
    "working_tree_dirty": true,
    "captured_at_utc": "2026-10-02T21:05:00.826855+00:00",
    "capture_started_at": "2026-10-02T21:05:00.334886+00:00",
    "source_changed_during_capture": false
  },
  "artifact_quality": "TEST_CAPTURE_DIRTY",
  "documents": {
    "briefing": {
      "pdf": "brief.pdf",
      "pages": 12,
      "width_points": 960.0,
      "height_points": 540.0,
      "screenshots": [
        "brief-slide-01.png",
        "brief-slide-02.png",
        "brief-slide-03.png",
        "brief-slide-04.png",
        "brief-slide-05.png",
        "brief-slide-06.png",
        "brief-slide-07.png",
        "brief-slide-08.png",
        "brief-slide-09.png",
        "brief-slide-10.png",
        "brief-slide-11.png",
        "brief-slide-12.png"
      ],
      "non_file_requests": 0,
      "blocked_requests": [],
      "js_errors": [],
      "console_errors": []
    },
    "proposal": {
      "pdf": "proposal.pdf",
      "pages": 3,
      "width_points": 595.92,
      "height_points": 842.88,
      "screenshots": [
        "proposal.png"
      ],
      "non_file_requests": 0,
      "blocked_requests": [],
      "js_errors": [],
      "console_errors": []
    }
  },
  "video": {
    "file": "backup.webm",
    "duration_seconds": 26.72,
    "audio_streams": 0,
    "video_streams": 1,
    "width": 1280,
    "height": 720,
    "audio_note": "無音訊：只錄製固定離線畫面，沒有麥克風或登入操作。",
    "viewport": {
      "width": 1280,
      "height": 720
    },
    "frames": [
      {
        "frame_id": "DEMO-01",
        "case_id": "historical_m0",
        "scenario_id": null,
        "synthetic": false,
        "expected_state": "OBSERVED_WARNING",
        "actual_state": "OBSERVED_WARNING",
        "rendered_text": "M0：歷史日曆警示觀測\n\n南迴線枋山＝枋野土石流淹軌，全日停駛 · 2026-08-25 · 恆春\n\n歷史已觀測到 warning+\n歷史逐日代理觀測；現場預警效果與實際提前時間 NOT_MEASURED。\n首警日期\n2026-08-22\n首警與事件日期的日曆差\n3 天日曆差\n實際可用提前時間\nNOT_MEASURED\n事件可用時間／精確事件時刻\n尚未取得\n\n完整日總雨量須於該日結束、發布並被取得後才可使用；缺可用時間與事件精確時刻，實際提前時間未測。\n\nM0／M1是同一既有事件的模型對照。搜尋窗完整：是；本頁展示不增加真值件數。",
        "screenshot": "demo-frame-01-historical_m0.png",
        "start_seconds_from_capture": 0.268,
        "hold_seconds": 2.5,
        "actual_hold_seconds": 2.501,
        "matches_expected": true
      },
      {
        "frame_id": "DEMO-02",
        "case_id": "historical_m1",
        "scenario_id": null,
        "synthetic": false,
        "expected_state": "NO_OBSERVED_WARNING",
        "actual_state": "NO_OBSERVED_WARNING",
        "rendered_text": "M1：未觀測到警示／漏報\n\n南迴線枋山＝枋野土石流淹軌，全日停駛 · 2026-08-25 · 恆春\n\n漏報：完整搜尋窗未觀測到 warning+\n歷史逐日代理觀測；現場預警效果與實際提前時間 NOT_MEASURED。\n首警日期\n未觀測到／未知\n首警與事件日期的日曆差\n未量測／無首警\n實際可用提前時間\nNOT_MEASURED\n事件可用時間／精確事件時刻\n尚未取得\n\n完整日總雨量須於該日結束、發布並被取得後才可使用；缺可用時間與事件精確時刻，實際提前時間未測。\n\nM0／M1是同一既有事件的模型對照。搜尋窗完整：是；本頁展示不增加真值件數。",
        "screenshot": "demo-frame-02-historical_m1.png",
        "start_seconds_from_capture": 2.909,
        "hold_seconds": 2.5,
        "actual_hold_seconds": 2.502,
        "matches_expected": true
      },
      {
        "frame_id": "DEMO-03",
        "case_id": "synthetic_interruption",
        "scenario_id": null,
        "synthetic": true,
        "expected_state": null,
        "actual_state": {},
        "rendered_text": "資料中斷／恢復：模擬健康評估\nSIMULATED · 固定資料模擬\n所有中斷與恢復均為模擬；沒有停止輪詢、拔線、寫入 live DB、注入事件或發送行車指令。fresh只表示來源時效，不表示現場安全。\n固定評估時間：2026-10-02T00:00:00Z；整體現場研判：unknown。\n資料仍在時效內\n雨量與QPE均過期\n未收到觀測時間\n觀測內容不合法\n觀測時間超前\n資料取得失敗\n模擬恢復接收\n雨量與QPE均過期\n\nunknown · 研判未知 · NOT_CONNECTED · 未接入 攝影機／臺鐵告警\n\n資料來源\t健康狀態\t模擬觀測時間（UTC）\t資料年齡\n10分鐘雨量\tstale · 過期\t2026-10-01T23:29:00Z\t31.0 分鐘\n雷達QPE\tstale · 過期\t2026-10-01T22:00:00Z\t120.0 分鐘\n\n雨量20分鐘／QPE90分鐘是產品時效設定，非官方行車門檻。模擬恢復後仍需人工核查，沒有下達行車或復駛命令。",
        "screenshot": "demo-frame-03-synthetic_interruption.png",
        "start_seconds_from_capture": 5.541,
        "hold_seconds": 2.5,
        "actual_hold_seconds": 2.501,
        "matches_expected": null
      },
      {
        "frame_id": "DEMO-04",
        "case_id": "synthetic_interruption",
        "scenario_id": "fresh",
        "synthetic": true,
        "expected_state": "fresh",
        "actual_state": {
          "rain": "fresh",
          "qpe": "fresh"
        },
        "rendered_text": "資料中斷／恢復：模擬健康評估\nSIMULATED · 固定資料模擬\n所有中斷與恢復均為模擬；沒有停止輪詢、拔線、寫入 live DB、注入事件或發送行車指令。fresh只表示來源時效，不表示現場安全。\n固定評估時間：2026-10-02T00:00:00Z；整體現場研判：unknown。\n資料仍在時效內\n雨量與QPE均過期\n未收到觀測時間\n觀測內容不合法\n觀測時間超前\n資料取得失敗\n模擬恢復接收\n資料仍在時效內\n\navailable · 資料可供研判 · NOT_CONNECTED · 未接入 攝影機／臺鐵告警\n\n資料來源\t健康狀態\t模擬觀測時間（UTC）\t資料年齡\n10分鐘雨量\tfresh · 來源時效內\t2026-10-01T23:50:00Z\t10.0 分鐘\n雷達QPE\tfresh · 來源時效內\t2026-10-01T23:30:00Z\t30.0 分鐘\n\n雨量20分鐘／QPE90分鐘是產品時效設定，非官方行車門檻。模擬恢復後仍需人工核查，沒有下達行車或復駛命令。",
        "screenshot": "demo-frame-04-fresh.png",
        "start_seconds_from_capture": 8.211,
        "hold_seconds": 2.5,
        "actual_hold_seconds": 2.501,
        "matches_expected": true
      },
      {
        "frame_id": "DEMO-05",
        "case_id": "synthetic_interruption",
        "scenario_id": "stale",
        "synthetic": true,
        "expected_state": "stale",
        "actual_state": {
          "rain": "stale",
          "qpe": "stale"
        },
        "rendered_text": "資料中斷／恢復：模擬健康評估\nSIMULATED · 固定資料模擬\n所有中斷與恢復均為模擬；沒有停止輪詢、拔線、寫入 live DB、注入事件或發送行車指令。fresh只表示來源時效，不表示現場安全。\n固定評估時間：2026-10-02T00:00:00Z；整體現場研判：unknown。\n資料仍在時效內\n雨量與QPE均過期\n未收到觀測時間\n觀測內容不合法\n觀測時間超前\n資料取得失敗\n模擬恢復接收\n雨量與QPE均過期\n\nunknown · 研判未知 · NOT_CONNECTED · 未接入 攝影機／臺鐵告警\n\n資料來源\t健康狀態\t模擬觀測時間（UTC）\t資料年齡\n10分鐘雨量\tstale · 過期\t2026-10-01T23:29:00Z\t31.0 分鐘\n雷達QPE\tstale · 過期\t2026-10-01T22:00:00Z\t120.0 分鐘\n\n雨量20分鐘／QPE90分鐘是產品時效設定，非官方行車門檻。模擬恢復後仍需人工核查，沒有下達行車或復駛命令。",
        "screenshot": "demo-frame-05-stale.png",
        "start_seconds_from_capture": 10.847,
        "hold_seconds": 2.5,
        "actual_hold_seconds": 2.501,
        "matches_expected": true
      },
      {
        "frame_id": "DEMO-06",
        "case_id": "synthetic_interruption",
        "scenario_id": "missing",
        "synthetic": true,
        "expected_state": "missing",
        "actual_state": {
          "rain": "missing",
          "qpe": "missing"
        },
        "rendered_text": "資料中斷／恢復：模擬健康評估\nSIMULATED · 固定資料模擬\n所有中斷與恢復均為模擬；沒有停止輪詢、拔線、寫入 live DB、注入事件或發送行車指令。fresh只表示來源時效，不表示現場安全。\n固定評估時間：2026-10-02T00:00:00Z；整體現場研判：unknown。\n資料仍在時效內\n雨量與QPE均過期\n未收到觀測時間\n觀測內容不合法\n觀測時間超前\n資料取得失敗\n模擬恢復接收\n未收到觀測時間\n\nunknown · 研判未知 · NOT_CONNECTED · 未接入 攝影機／臺鐵告警\n\n資料來源\t健康狀態\t模擬觀測時間（UTC）\t資料年齡\n10分鐘雨量\tmissing · 缺測\t缺測\t未量測\n雷達QPE\tmissing · 缺測\t缺測\t未量測\n\n雨量20分鐘／QPE90分鐘是產品時效設定，非官方行車門檻。模擬恢復後仍需人工核查，沒有下達行車或復駛命令。",
        "screenshot": "demo-frame-06-missing.png",
        "start_seconds_from_capture": 13.56,
        "hold_seconds": 2.5,
        "actual_hold_seconds": 2.501,
        "matches_expected": true
      },
      {
        "frame_id": "DEMO-07",
        "case_id": "synthetic_interruption",
        "scenario_id": "invalid",
        "synthetic": true,
        "expected_state": "invalid",
        "actual_state": {
          "rain": "invalid",
          "qpe": "invalid"
        },
        "rendered_text": "資料中斷／恢復：模擬健康評估\nSIMULATED · 固定資料模擬\n所有中斷與恢復均為模擬；沒有停止輪詢、拔線、寫入 live DB、注入事件或發送行車指令。fresh只表示來源時效，不表示現場安全。\n固定評估時間：2026-10-02T00:00:00Z；整體現場研判：unknown。\n資料仍在時效內\n雨量與QPE均過期\n未收到觀測時間\n觀測內容不合法\n觀測時間超前\n資料取得失敗\n模擬恢復接收\n觀測內容不合法\n\nunknown · 研判未知 · NOT_CONNECTED · 未接入 攝影機／臺鐵告警\n\n資料來源\t健康狀態\t模擬觀測時間（UTC）\t資料年齡\n10分鐘雨量\tinvalid · 非法資料\t2026-10-01T23:58:00Z\t2.0 分鐘\n雷達QPE\tinvalid · 非法資料\t2026-10-01T23:45:00Z\t15.0 分鐘\n\n雨量20分鐘／QPE90分鐘是產品時效設定，非官方行車門檻。模擬恢復後仍需人工核查，沒有下達行車或復駛命令。",
        "screenshot": "demo-frame-07-invalid.png",
        "start_seconds_from_capture": 16.204,
        "hold_seconds": 2.5,
        "actual_hold_seconds": 2.502,
        "matches_expected": true
      },
      {
        "frame_id": "DEMO-08",
        "case_id": "synthetic_interruption",
        "scenario_id": "future",
        "synthetic": true,
        "expected_state": "future",
        "actual_state": {
          "rain": "future",
          "qpe": "future"
        },
        "rendered_text": "資料中斷／恢復：模擬健康評估\nSIMULATED · 固定資料模擬\n所有中斷與恢復均為模擬；沒有停止輪詢、拔線、寫入 live DB、注入事件或發送行車指令。fresh只表示來源時效，不表示現場安全。\n固定評估時間：2026-10-02T00:00:00Z；整體現場研判：unknown。\n資料仍在時效內\n雨量與QPE均過期\n未收到觀測時間\n觀測內容不合法\n觀測時間超前\n資料取得失敗\n模擬恢復接收\n觀測時間超前\n\nunknown · 研判未知 · NOT_CONNECTED · 未接入 攝影機／臺鐵告警\n\n資料來源\t健康狀態\t模擬觀測時間（UTC）\t資料年齡\n10分鐘雨量\tfuture · 時間超前\t2026-10-02T00:30:00Z\t-30.0 分鐘\n雷達QPE\tfuture · 時間超前\t2026-10-02T00:30:00Z\t-30.0 分鐘\n\n雨量20分鐘／QPE90分鐘是產品時效設定，非官方行車門檻。模擬恢復後仍需人工核查，沒有下達行車或復駛命令。",
        "screenshot": "demo-frame-08-future.png",
        "start_seconds_from_capture": 18.944,
        "hold_seconds": 2.5,
        "actual_hold_seconds": 2.502,
        "matches_expected": true
      },
      {
        "frame_id": "DEMO-09",
        "case_id": "synthetic_interruption",
        "scenario_id": "error",
        "synthetic": true,
        "expected_state": "error",
        "actual_state": {
          "rain": "error",
          "qpe": "error"
        },
        "rendered_text": "資料中斷／恢復：模擬健康評估\nSIMULATED · 固定資料模擬\n所有中斷與恢復均為模擬；沒有停止輪詢、拔線、寫入 live DB、注入事件或發送行車指令。fresh只表示來源時效，不表示現場安全。\n固定評估時間：2026-10-02T00:00:00Z；整體現場研判：unknown。\n資料仍在時效內\n雨量與QPE均過期\n未收到觀測時間\n觀測內容不合法\n觀測時間超前\n資料取得失敗\n模擬恢復接收\n資料取得失敗\n\nunknown · 研判未知 · NOT_CONNECTED · 未接入 攝影機／臺鐵告警\n\n資料來源\t健康狀態\t模擬觀測時間（UTC）\t資料年齡\n10分鐘雨量\terror · 無法取得\t2026-10-01T23:58:00Z\t2.0 分鐘\n雷達QPE\terror · 無法取得\t2026-10-01T23:45:00Z\t15.0 分鐘\n\n雨量20分鐘／QPE90分鐘是產品時效設定，非官方行車門檻。模擬恢復後仍需人工核查，沒有下達行車或復駛命令。",
        "screenshot": "demo-frame-09-error.png",
        "start_seconds_from_capture": 21.58,
        "hold_seconds": 2.5,
        "actual_hold_seconds": 2.5,
        "matches_expected": true
      },
      {
        "frame_id": "DEMO-10",
        "case_id": "synthetic_interruption",
        "scenario_id": "recovered",
        "synthetic": true,
        "expected_state": "fresh",
        "actual_state": {
          "rain": "fresh",
          "qpe": "fresh"
        },
        "rendered_text": "資料中斷／恢復：模擬健康評估\nSIMULATED · 固定資料模擬\n所有中斷與恢復均為模擬；沒有停止輪詢、拔線、寫入 live DB、注入事件或發送行車指令。fresh只表示來源時效，不表示現場安全。\n固定評估時間：2026-10-02T00:00:00Z；整體現場研判：unknown。\n資料仍在時效內\n雨量與QPE均過期\n未收到觀測時間\n觀測內容不合法\n觀測時間超前\n資料取得失敗\n模擬恢復接收\n模擬恢復接收\n\navailable · 資料可供研判 · NOT_CONNECTED · 未接入 攝影機／臺鐵告警\n\n資料來源\t健康狀態\t模擬觀測時間（UTC）\t資料年齡\n10分鐘雨量\tfresh · 來源時效內\t2026-10-01T23:58:00Z\t2.0 分鐘\n雷達QPE\tfresh · 來源時效內\t2026-10-01T23:45:00Z\t15.0 分鐘\n\n雨量20分鐘／QPE90分鐘是產品時效設定，非官方行車門檻。模擬恢復後仍需人工核查，沒有下達行車或復駛命令。",
        "screenshot": "demo-frame-10-recovered.png",
        "start_seconds_from_capture": 24.233,
        "hold_seconds": 2.5,
        "actual_hold_seconds": 2.501,
        "matches_expected": true
      }
    ],
    "frame_count": 10,
    "refresh_fixed": true,
    "non_file_requests": 0,
    "blocked_requests": [],
    "js_errors": [],
    "console_errors": []
  },
  "source_changed_during_generation": false,
  "finished_at": "2026-10-02T21:07:44.690865+00:00",
  "duration_seconds": 29.631,
  "publication": {
    "kind": "VERIFIED_CURRENT_SNAPSHOT",
    "engineering_run_id": "7e3d6235c2c245a0a76e3a49e3a29bcf",
    "verified_program_commit": "869d7a0a081817f2f790e082b33bbd02c2471ebe",
    "program_source_hashes_verified": 110,
    "captured_worktree_note": "snapshot dirty=true includes preserved untracked cache; code hashes match committed implementation; authoring worktree clean is separate",
    "files": {
      "brief.pdf": "/static/slope-briefing.pdf",
      "proposal.pdf": "/proposals/slopeguard.pdf",
      "backup.webm": "/static/slope-demo-backup.webm"
    }
  }
}
