Briefings v2: owner's Perplexity format + Taiwan mil/transport sources
Recreates the owner's Perplexity daily-report inside the pipeline's own
rules - the model still never searches the web; instead the owner's
search list became scheduled fetch queries:
- New sources: Simple Flying (official RSS), CNA politics wire
(official feedburner feed + new per-source keyword filter in fetch.py
so only aviation/military-air/transport items survive - 3/20 kept on
the live probe), MND/軍聞社 via Google News proxy (direct RSS is 403),
and a Taiwan rail/metro/maritime Google News query. CNA + MND hosts
added to the fulltext allowlist (robots still honored).
- Briefing format per the owner's template: ✈️ title, emoji section
headers (🚨 flight safety / 🇹🇼 Taiwan civil+military / 🌐 industry /
🚄 ground & maritime), per-item severity marks (⚠️/🔴), 🇹🇼 and ⚔️
flags from the stored item metadata, 📡 sources block, and a
conservative per-section empty note (never "nothing happened
worldwide" claims - the owner's own briefing spec bans those).
- Classification dictionaries extended: 共機/中共機艦/解放軍 → military
flag, 國防部/臺海 → Taiwan, 小三通/船班/出軌 → ground & maritime.
Not done, by design: no Perplexity output is ever ingested and no model
performs its own web search - both are banned by the owner's briefing
spec (sections 1 and 19) and the published methodology page.
tests: test_briefing.py 58 checks (classification + marks); all 8
suites green; live fetch probe of every new feed succeeded.
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Full diff
@@ -9,7 +9,7 @@\n "window_end": "2026-07-27T07:00:00+08:00",\n "cutoff_time": "2026-07-27T07:00:00+08:00",\n "scheduled_time": "2026-07-27T07:15:00+08:00",\n- "generated_at": "2026-07-27T04:57:47.979216+08:00",\n+ "generated_at": "2026-07-27T06:45:12.332665+08:00",\n "status": "published",\n "item_count": 2,\n "sections": {\n@@ -94,47 +94,67 @@\n {\n "name": "FAA",\n "ok": true,\n- "last_fetch_utc": "2026-07-26T20:57Z"\n+ "last_fetch_utc": "2026-07-26T22:43Z"\n },\n {\n "name": "NTSB",\n "ok": true,\n- "last_fetch_utc": "2026-07-26T20:57Z"\n+ "last_fetch_utc": "2026-07-26T22:43Z"\n },\n {\n "name": "ICAO",\n "ok": true,\n- "last_fetch_utc": "2026-07-26T20:57Z"\n+ "last_fetch_utc": "2026-07-26T22:43Z"\n },\n {\n "name": "IATA",\n "ok": true,\n- "last_fetch_utc": "2026-07-26T20:57Z"\n+ "last_fetch_utc": "2026-07-26T22:43Z"\n },\n {\n "name": "EASA",\n "ok": true,\n- "last_fetch_utc": "2026-07-26T20:57Z"\n+ "last_fetch_utc": "2026-07-26T22:43Z"\n },\n {\n "name": "Eurocontrol",\n "ok": true,\n- "last_fetch_utc": "2026-07-26T20:57Z"\n+ "last_fetch_utc": "2026-07-26T22:43Z"\n },\n {\n "name": "Reuters",\n "ok": true,\n- "last_fetch_utc": "2026-07-26T20:57Z"\n+ "last_fetch_utc": "2026-07-26T22:43Z"\n },\n {\n "name": "The Aviation Herald",\n "ok": true,\n- "last_fetch_utc": "2026-07-26T20:57Z"\n+ "last_fetch_utc": "2026-07-26T22:43Z"\n },\n {\n "name": "CAA Taiwan",\n "ok": true,\n- "last_fetch_utc": "2026-07-26T20:57Z"\n+ "last_fetch_utc": "2026-07-26T22:43Z"\n+ },\n+ {\n+ "name": "Simple Flying",\n+ "ok": true,\n+ "last_fetch_utc": "2026-07-26T22:43Z"\n+ },\n+ {\n+ "name": "中央社 CNA",\n+ "ok": true,\n+ "last_fetch_utc": "2026-07-26T22:44Z"\n+ },\n+ {\n+ "name": "國防部・軍聞社",\n+ "ok": true,\n+ "last_fetch_utc": "2026-07-26T22:44Z"\n+ },\n+ {\n+ "name": "臺灣交通要聞",\n+ "ok": true,\n+ "last_fetch_utc": "2026-07-26T22:44Z"\n }\n ],\n "warnings": [],\n@@ -6,7 +6,7 @@\n "edition": "morning",\n "status": "published",\n "cutoff_time": "2026-07-27T07:00:00+08:00",\n- "generated_at": "2026-07-27T04:57:47.979216+08:00",\n+ "generated_at": "2026-07-27T06:45:12.332665+08:00",\n "item_count": 2\n }\n ]\n@@ -16,5 +16,9 @@\n "eurocontrol": {\n "url": "https://www.eurocontrol.int/newsroom",\n "last_modified": "Sun, 26 Jul 2026 22:27:15 GMT"\n+ },\n+ "cnataiwan": {\n+ "url": "https://feeds.feedburner.com/rsscna/politics",\n+ "last_modified": "Sun, 26 Jul 2026 22:34:38 GMT"\n }\n }\n@@ -1,6 +1,6 @@\n {\n "source": "avherald",\n- "fetchedUtc": "2026-07-26T22:37Z",\n+ "fetchedUtc": "2026-07-26T22:43Z",\n "ok": true,\n "error": null,\n "items": [\n@@ -1,6 +1,6 @@\n {\n "source": "caataiwan",\n- "fetchedUtc": "2026-07-26T22:37Z",\n+ "fetchedUtc": "2026-07-26T22:43Z",\n "ok": true,\n "error": null,\n "items": [\n@@ -0,0 +1,29 @@\n+{\n+ "source": "cnataiwan",\n+ "fetchedUtc": "2026-07-26T22:44Z",\n+ "ok": true,\n+ "error": null,\n+ "items": [\n+ {\n+ "title": "聯合防禦操演 驗證直屬參謀本部戰略預備隊應變能量",\n+ "url": "https://www.cna.com.tw/news/aipl/202607260100.aspx",\n+ "publishedUtc": "2026-07-26T06:56Z",\n+ "summary": "(中央社記者游凱翔台北26日電)國軍聯合防禦操演日前結束,知情人士指出,此次操演已驗證直屬參謀本部的戰略預備隊應變能量;學者推測,在漢光實兵等聯合作戰想定下,由具備跨海陸空機動能力的部隊擔任戰略預備隊,成為關鍵打擊戰力。",\n+ "image": null\n+ },\n+ {\n+ "title": "蔡其昌率團赴台灣日僑宴 前紐約市長亞當斯出席支持",\n+ "url": "https://www.cna.com.tw/news/aipl/202607260033.aspx",\n+ "publishedUtc": "2026-07-26T02:54Z",\n+ "summary": "(中央社記者廖漢原紐約25日專電)美國職棒大聯盟紐約大都會台灣日明天舉行,擔任雙開球嘉賓的美國國家航空暨太空總署太空人林琪兒及中華職棒大聯盟會長蔡其昌等,今天出席賽前僑宴,前紐約市長亞當斯出席對台僑社群表達支持。",\n+ "image": null\n+ },\n+ {\n+ "title": "7艘共艦3艘公務船擾台 國軍監控",\n+ "url": "https://www.cna.com.tw/news/aipl/202607260022.aspx",\n+ "publishedUtc": "2026-07-26T01:57Z",\n+ "summary": "(中央社記者游凱翔台北26日電)國防部今天發布共機艦動態,統計自昨天上午6時起至今天上午6時止,偵獲7艘共艦、3艘公務船,及4架次共機,國軍運用任務機艦及岸置飛彈系統嚴密監控與應處。",\n+ "image": null\n+ }\n+ ]\n+}\n@@ -1,6 +1,6 @@\n {\n "source": "easa",\n- "fetchedUtc": "2026-07-26T22:37Z",\n+ "fetchedUtc": "2026-07-26T22:43Z",\n "ok": true,\n "error": null,\n "items": [\n@@ -1,6 +1,6 @@\n {\n "source": "eurocontrol",\n- "fetchedUtc": "2026-07-26T22:37Z",\n+ "fetchedUtc": "2026-07-26T22:43Z",\n "ok": true,\n "error": null,\n "items": [\n@@ -1,6 +1,6 @@\n {\n "source": "faa",\n- "fetchedUtc": "2026-07-26T22:37Z",\n+ "fetchedUtc": "2026-07-26T22:43Z",\n "ok": true,\n "error": null,\n "items": [\n@@ -1,6 +1,6 @@\n {\n "source": "flightaware",\n- "fetchedUtc": "2026-07-26T22:37Z",\n+ "fetchedUtc": "2026-07-26T22:43Z",\n "ok": false,\n "error": "AEROAPI_KEY not set",\n "items": []\n@@ -1,6 +1,6 @@\n {\n "source": "iata",\n- "fetchedUtc": "2026-07-26T22:37Z",\n+ "fetchedUtc": "2026-07-26T22:43Z",\n "ok": true,\n "error": null,\n "items": [\n@@ -1,6 +1,6 @@\n {\n "source": "icao",\n- "fetchedUtc": "2026-07-26T22:37Z",\n+ "fetchedUtc": "2026-07-26T22:43Z",\n "ok": true,\n "error": null,\n "items": [\n@@ -0,0 +1,183 @@\n+{\n+ "source": "mndnews",\n+ "fetchedUtc": "2026-07-26T22:44Z",\n+ "ok": true,\n+ "error": null,\n+ "items": [\n+ {\n+ "title": "全球資訊網 - 新聞與公告 - 區域動態 - 中共解放軍臺海周邊海、空域動態",\n+ "url": "https://news.google.com/rss/articles/CBMiUkFVX3lxTFB3Vk5FcEgyaGZBVU1ncFdmMktpdVN1dTF5cDlHeWlsaExGWFViRThjeHA2OGpkcUo2ZW90LTJaNk1XYmFRcGloWGNQRmMyMlQ4bkE?oc=5",\n+ "publishedUtc": "2026-07-25T01:10Z",\n+ "summary": "",\n+ "image": null\n+ },\n+ {\n+ "title": "emergency-supplies.zh-Hant.pdf - 臺灣全民安全指引- 國防部",\n+ "url": "https://news.google.com/rss/articles/CBMid0FVX3lxTE9EUk5ybFpUM01JMFltdXV4SUtRai13ZEpYT0cxUm5VeGZ4b0YyV19yY1hZNTcwUVdQdDZfRFJiMFlNaXBMWlpiMTJBR0s4UWlBblZyenAyNjhyZVNYRjB2NTVQc1ppd01QZC1JZmh4dmw3V0RUQ3Vr?oc=5",\n+ "publishedUtc": "2026-07-25T09:45Z",\n+ "summary": "",\n+ "image": null\n+ },\n+ {\n+ "title": "國防部軍醫院全球資訊網-軍事院校",\n+ "url": "https://news.google.com/rss/articles/CBMinwFBVV95cUxPU1NLVi1sYzNIeVVHMmZUZG02SXlCNTA1UEFHSW4wU1c4ZWlHZmsxTFNENzdkdGxHNGVaaHJRdmNxaFNSR1ZvZ2U2U2RMUm9hdTA0TWZFdngyVTJRR2JpcXVlRGNDTHp3OERUaFJuZzgwaGZHaG8tTlJMU2cyYll5MGlWTmk0anNHRTFPa0ZZV1RIZlNlR3NrY3lnb21mZEk?oc=5",\n+ "publishedUtc": "2022-06-29T19:46Z",\n+ "summary": "",\n+ "image": null\n+ },\n+ {\n+ "title": "全球資訊網 - 首頁 - 首頁即時軍事動態列表",\n+ "url": "https://news.google.com/rss/articles/CBMiRkFVX3lxTE1WN2RpV0tQMzVGUExFcXJ4aXlXRXU3WElfbV9TNzBSQ3Z1dGtTbTZ5Q1lKdkY0MWhXQmUzZEFEUngweV9YU3c?oc=5",\n+ "publishedUtc": "2025-12-01T16:52Z",\n+ "summary": "",\n+ "image": null\n+ },\n+ {\n+ "title": "確認預約掛號",\n+ "url": "https://news.google.com/rss/articles/CBMipwFBVV95cUxQMVQyY1BXWE1NZWlkNE9oUVhRaXNwNHk2Slg4QUpXc2UtQnhzaHRzdTFfNHZERVNBU3RWS2hEcF9NYkFndmVVYUhzd0tTVjZWOHN1Y3VDenN5d0xHc2xIc01QcTc1Y2JWa3N5YlNZZ1o4TjN0VHAxRTNQTTB2ZFIyOGFaUHVSZ29lb1ktcko0SzBrMUpqUnFpb1h4WUhTRGpTenM4akhLYw?oc=5",\n+ "publishedUtc": "2026-07-26T17:47Z",\n+ "summary": "",\n+ "image": null\n+ },\n+ {\n+ "title": "全球資訊網 - 標籤 - NM No.62---Kaohsiung Harbor–Unloading Work (May 6",\n+ "url": "https://news.google.com/rss/articles/CBMipAFBVV95cUxQQkJrNTlpOXNDTFlHY0pRSGsyV2hhdEpEZDNWSDRxdDBnN2w3ZGlBbUg0aXlBOV9lVnhNSklseTRXM1k3bV9aVFRfNVJTSHF0VU5vT28wX19faHV2a3lHQUEwRnowbk94OGFRd1NQd0xpSHVOZGFXcDRadWRHc2h5OWJibDBrQzc4RkdZcjhzUS0xTUc1VlVKYXE3YmRwaUlzWmh5Yw?oc=5",\n+ "publishedUtc": "2026-07-25T17:21Z",\n+ "summary": "",\n+ "image": null\n+ },\n+ {\n+ "title": "全球資訊網- News Channel - PLA Activities - PLA activities in the waters and airspace around Taiwan",\n+ "url": "https://news.google.com/rss/articles/CBMiUkFVX3lxTE4zMVNnX2RWTklTbzBqRDlQeWhHdkxuMWhTVFZnNWZLRW5fUkJIdlNycXpGd0xSMmRtdlZvbVZCUDlqZ0JfbndUQXh2ckxLcDBGbnc?oc=5",\n+ "publishedUtc": "2026-07-25T02:16Z",\n+ "summary": "",\n+ "image": null\n+ },\n+ {\n+ "title": "全文檢索",\n+ "url": "https://news.google.com/rss/articles/CBMiVEFVX3lxTE9DTHhid0w4cHRDbHRkQW05YmxVSGJ6MHAzUG5taWsxb2FlZGU4OFlPSG1adzNlcjY4a2llZG5PNU85aktfancxVUJKaFVSRXZ1c0lJSQ?oc=5",\n+ "publishedUtc": "2026-07-25T00:08Z",\n+ "summary": "",\n+ "image": null\n+ },\n+ {\n+ "title": "全文檢索",\n+ "url": "https://news.google.com/rss/articles/CBMirgFBVV95cUxNQnRscWYwbUN2bl9LQ0JZbENIYkJrSTB2QW40ejhEcVVfRUhzUWVIemVBRjJzM0RwSlB4eFdvOU00TlpuTEVMWldIdEg3eDFBLUV1a0JWd0VxQzJibjdIVlVqamF4am9pT05zN1RqZkRHRXJIYXBSYlVwUW9zODYzNWdkYkVUYUhhRGRkTWh5S180U1k5WEYxUzI1d01jaXZNdk5temVMOHlPY0tHdnc?oc=5",\n+ "publishedUtc": "2026-07-25T00:08Z",\n+ "summary": "",\n+ "image": null\n+ },\n+ {\n+ "title": "空氣軟槍北區初賽落幕 冠軍隊伍分享訓練過程",\n+ "url": "https://news.google.com/rss/articles/CBMihwFBVV95cUxOdXpWeGpXZ0RLVWRJRUZqR1kxQXFwN2MzTFZiMEpQaTZjTU9Wbjl1NDFEZFBLeHNXQS1IWDU2dlAtNVpHMllLSUo3Tnp4cm55eXNfdTltX2lnbUNfdS13UHgzX0RZb1BFZnlzblltQ0FObGZZLWVrQUdieHFIbHV6ZkFTaVdDU00?oc=5",\n+ "publishedUtc": "2026-07-25T22:38Z",\n+ "summary": "",\n+ "image": null\n+ },\n+ {\n+ "title": "賴佳瑩",\n+ "url": "https://news.google.com/rss/articles/CBMimwFBVV95cUxNcjJwV3psa1ppU1cwcmZWR3BvaGVCeHNPUGhINGRSTjlFMHVTa1hDV1NGRHlYaWdEY3Utb25ucVRGa0lJQ192YVpEbGwzT2RJUEV4RW83S3dxNy1Yck9XRWhlVXVBaU1qLVZMVzZOUFRWQmVYQXA3QlRWc2ZMMjlXc0U1R2ZOR01Kb3pLc0NZTWNTbjExclVjdTFVTQ?oc=5",\n+ "publishedUtc": "2026-07-25T17:08Z",\n+ "summary": "",\n+ "image": null\n+ },\n+ {\n+ "title": "後測中心驗證564旅後勤保修能量",\n+ "url": "https://news.google.com/rss/articles/CBMihwFBVV95cUxQX0l0bW4wSWd4RVdFcG0xSGFqVktiTzZreWcyWms5Q1FVbnVWbERYUUNlUEhfcWZjVWpOUUhTeHlRc25NU3JpbHJ1QzQyYlFRUV9GMThaem1kb2xrOG1tdkcxd2JMYlJDWGx6My1OdjJadWZQUldCRmNzaXRfV3Y2VlNDRjZ0S1E?oc=5",\n+ "publishedUtc": "2026-07-26T11:05Z",\n+ "summary": "",\n+ "image": null\n+ },\n+ {\n+ "title": "中共機艦臺海周邊活動 國軍嚴密監控應處",\n+ "url": "https://news.google.com/rss/articles/CBMihwFBVV95cUxQNEcxSEVzVDgyWF80VTBXVnhjeTVSbG80aURtT3NIa2pIWUFDamJsa2RsVkdSM2FqdHFFdF90SmkxUEZEamVlVmlfaXpESVVsX0ExZlZ2TUYzU3NWZ1l0VTNrUXkzRktCZU9OUXBIc0otekhqNTM0elpWbWozN1p5WE8wcDZ5VzA?oc=5",\n+ "publishedUtc": "2026-07-25T05:56Z",\n+ "summary": "",\n+ "image": null\n+ },\n+ {\n+ "title": "全文檢索",\n+ "url": "https://news.google.com/rss/articles/CBMiigFBVV95cUxQUG8xeWNvVnlrM2ZjLWI4U2pVeUlqU0xBRzdFUGVqNEhYaDRuUFpnNUd0NkFqZmxfazg0R2dUVFZnRDJwNHFHN2xSeVBYbk5TQU13QnUySllRNTFfNUNxWXdwa20zVjQ4OHVPWkJGY19fMDhldFo5UFl6RFFrempXQjJNYlFjNzBzdWc?oc=5",\n+ "publishedUtc": "2026-07-25T00:08Z",\n+ "summary": "",\n+ "image": null\n+ },\n+ {\n+ "title": "搜尋",\n+ "url": "https://news.google.com/rss/articles/CBMiogFBVV95cUxNR1FWNEZKb0xvVFdnTGREMFJFTThUbVQ1S2pLaFJxOHdEWUFjc3hGY3RoTXc0SnlXb1JtNDJPX1hYamhWWjlxTzJ1Qkp1V3ZPMERaaktjMmdtXzhWNklXRnU2ckhSczJhaDcyb0tXU1B6SnBvMzZzdmJoaU16VVdPTXhaeDZiREdqTkJLeUgtNDM3LTBuNXNaN1BWaWlQNGNTS3c?oc=5",\n+ "publishedUtc": "2026-07-25T00:02Z",\n+ "summary": "",\n+ "image": null\n+ },\n+ {\n+ "title": "搜尋",\n+ "url": "https://news.google.com/rss/articles/CBMiogFBVV95cUxPeWpDM1BWVlFaUFhhTFJkVnVObmR6N21FcWx6cGpPSVhWTk5LbzJOR2QzMWpDdHM2LVFZNXB2bTliZ0JSMUk4Sk1mTUpJblNZczdIWVVLbEZhYTBMR0hqVG5kM0tBS0x0VlpFSmlyaXdoaDBXV05hZ0VTNFpfQi13UjFrZlZpNkQwMmpKV084dnV3dnp2Y0NZNFNaendocEZyckE?oc=5",\n+ "publishedUtc": "2026-07-26T00:37Z",\n+ "summary": "",\n+ "image": null\n+ },\n+ {\n+ "title": "善化區輔導中心對進駐官兵實施慰問",\n+ "url": "https://news.google.com/rss/articles/CBMiaEFVX3lxTE1EamFhUHZOVF9Ld2dDS2FyaTY5VXZBeUVrTGZqbTUzZ05vN2FoTnpSUUNFMVhuUWVKWnBVR29OMlI2dTIxSXlNRjBSOVAtY2FQbU9GMXY0c0hZeWpwa3FDSVJGZGtiODhp?oc=5",\n+ "publishedUtc": "2026-07-25T06:41Z",\n+ "summary": "",\n+ "image": null\n+ },\n+ {\n+ "title": "53工兵群挽袖獻熱血展現公益熱忱",\n+ "url": "https://news.google.com/rss/articles/CBMihwFBVV95cUxNb1RZbVFzMDVrbS1GUy1GVW5PMm05aDhwQjQxbGt1NURybVIzdzlkMUQwLWVyNVdwUUNrNFQtWFQ2cm5jTzA4REpxZmpFQVE1U202XzBkUHZqWFg1TlN5Tk1vU3hoZ05vTXpQOGtTZFFDMVczYXVNOFlfWmYxNk80UVVPUTBFNEE?oc=5",\n+ "publishedUtc": "2026-07-26T11:05Z",\n+ "summary": "",\n+ "image": null\n+ },\n+ {\n+ "title": "確認預約掛號",\n+ "url": "https://news.google.com/rss/articles/CBMipwFBVV95cUxQT2lUUVl3Y0FVTVZOZ1N6WWEwT2o1bXFIYVNxcktaajlDcXZlTXZGajVYbXY3N0xwaE52V1NONF85cjdXWlptQVdJaGNPRWR1Nlo1TDk3ZTJ1OVJzLXNYVE9mclE3OWRva3RuYlZEQmNiYXpYSkozdm15dkR6TVlKQkIzS2pZQWpPaUtjSmNBcGZ3Q2dBTGpwdHdIREdDRUlmUl9Eb25rTQ?oc=5",\n+ "publishedUtc": "2026-07-26T18:14Z",\n+ "summary": "",\n+ "image": null\n+ },\n+ {\n+ "title": "全球資訊網 - 標籤 - 第3任總司令 陳嘉尚上將(任期:民國46年7月1日起至民國52年7月1日止)",\n+ "url": "https://news.google.com/rss/articles/CBMiqwNBVV95cUxPZzE2b05EdWs5R2ZGNUViUWw4aUFvcDNELWIyQjNRVWJFWXEwNHM2Vi1INUN0U2JDY0NLSFp6Z2dZUkZNWW1YUVdZbFhxTXdiSXRCX2p1alpwaUlLOHJEV0dXbGJrNS1TTUVPYk85RmFJYW4yY0ZrV3ZnOFNBZVIyZmRMZEwxVk5QSmNDV1pJaU1oNW04RHpLZHhNU0VCNWZjZGtud0JMcnhjVWdnVVhva19nSlFqaFVpT1lxN1Z0ZDBadW4zVlQwQktSQmZaa2lhU25rcGZhNDRTRlY5Q0lyYklqaTRFYlhwYVlEYmNTb0M5ZFp2ZHFiUTE5TTltdldoYlk5R2xwLVNMNHMtZ0puVjE5WE1razk1R2VYNkIycnBCRWVpN0Q3TDFoQ01hdVBVMF9OT1kwTGlySjVfREkxT0J3Yy1obUUtdzhVMHJWQ2drRFNYMmI1RVVfb1NTN2Jobk81c096R1pDUHBnNWxmbDBsNlFmMjJVVGVmYklLZDUzMXpENUtfNDhrblFBTmtZUnVxeEZwd01RTzdwZEJCUnRoTnZONTM3ZkE0?oc=5",\n+ "publishedUtc": "2026-07-25T09:56Z",\n+ "summary": "",\n+ "image": null\n+ },\n+ {\n+ "title": "徐副部長主持空氣軟槍北區初賽 提升全社會防衛韌性",\n+ "url": "https://news.google.com/rss/articles/CBMihwFBVV95cUxNUXdjNzJOZmllelJrTEd2MHZCVGxEdGdNTDA4emYyMUR1VXZwaVZ4ek1MOW16U1FoNlI3aEJ4RDlPVXJ3ZkVFV1gwTWVVM1JFWS1GMEk1MWlncG5pYjBrTFY5Y3Z3NlNicksxWHU1emFGZkplVmpwZnNqaVVpcUxWNVhaT1VXTHc?oc=5",\n+ "publishedUtc": "2026-07-25T09:23Z",\n+ "summary": "",\n+ "image": null\n+ },\n+ {\n+ "title": "搜尋",\n+ "url": "https://news.google.com/rss/articles/CBMilgFBVV95cUxQMzJCclEwbE83eGJMby1fMWZGYzFzQk1yeXJkY3Z3WmRZS3VGYndYMDdYVzdmT3Q5cW5SeTk2OEJQSHhDV01WZ1lkOXRoLUU2TG84dXl1dGROMDAtM210LTNRbEpBbFhFWEhMMjF3NmZ3SEo5MWVvWEowVEtxSmVtNGVvTXZwR1JPZzlfN3h4VW9ZSS1JdWc?oc=5",\n+ "publishedUtc": "2026-07-25T12:09Z",\n+ "summary": "",\n+ "image": null\n+ },\n+ {\n+ "title": "全球資訊網- 標籤 - Defense Air Command issued press releases on \"anti-China launch of New route IDF for Taiwan\" for full year's arrival in Penghu",\n+ "url": "https://news.google.com/rss/articles/CBMisAJBVV95cUxQbVJsVTBFOVhjZHVSWFc0TWxtaWNURGlGR0hkMFZCT0xYM21kVU9nWkhNWFUxMFZFTnp5Tlhua3A4aDliMWMzUDdIbF9kVnlPbzdZcDlleFdQejBpcHhCXzh6VTZINWxFZi1oYTExWEotcHZrUnlld3FtQzdhTGJ0QU9fWFNRWHd5UmVXRi1UVm1WWGNQeDFJZEV6LWRkSVBwb3g3VC1HTV9aaXJPdnBLSkZuNHJsZFFscjVncFBxOTRlZ0g4ZTdEdmhIM09OQjJjYkdjdnpwdnk4VjZOU2V2RUhwZTJuMjlYS2ZHVzJuWnpRT1p3TmVCaEdsX0syOXQ2WkhMTGwxM05JS3p3SFNpdGNwU3dXcWVvUzk0aTNMTFpPOXd6ZEtKREhJeEo4TnM4?oc=5",\n+ "publishedUtc": "2026-07-25T20:05Z",\n+ "summary": "",\n+ "image": null\n+ },\n+ {\n+ "title": "賴佳瑩",\n+ "url": "https://news.google.com/rss/articles/CBMipwFBVV95cUxObVpaWk8xR200bGtZbUVnWUxaV09RdE1yNWJtYV9HR19GME5UNzRTaFNFREs5S2FLRm9yVkkzMDFXNjdMY0NXaHVGb2VxTkVBUGJudXlkUnpxamRGcG1aTGxudEQ0ZDZZZFdxSHNPNlRUTXQ3QWw3b3p1Rm5DNDVwVlNlbkNjVlZaelBIV3pEQ08yWlFaQmUxRXIwd0IxZnBZWHdaMXo4cw?oc=5",\n+ "publishedUtc": "2026-07-26T00:56Z",\n+ "summary": "",\n+ "image": null\n+ },\n+ {\n+ "title": "確認預約掛號",\n+ "url": "https://news.google.com/rss/articles/CBMipwFBVV95cUxOS0tvdkJOR3V3MUNvdHEtb0UycGFab3VvUGY2R1RvN3hUbXlGaWtsUm1iM01ONjN0UkNpcmtGVkRSa1VIbU1uRVBWTWxoY1p2VDVWTWtzaGFmWHY2d3BtMmlIUVF3bkQ0cGhjSEY5WE1nQVAwNDdoeHFzemhMcTVVd2Yycmh3Ri1tZVNwdGhVVXhjaTZqaFo0VDJ6Rjd4cUtsUGJjTzQzYw?oc=5",\n+ "publishedUtc": "2026-07-26T17:21Z",\n+ "summary": "",\n+ "image": null\n+ }\n+ ]\n+}\n@@ -1,6 +1,6 @@\n {\n "source": "ntsb",\n- "fetchedUtc": "2026-07-26T22:37Z",\n+ "fetchedUtc": "2026-07-26T22:43Z",\n "ok": true,\n "error": null,\n "items": [\n@@ -20,8 +20,8 @@\n },\n {\n "title": "CAROL Query - NTSB",\n- "url": "https://news.google.com/rss/articles/CBMieEFVX3lxTE5tZkh5QTVXTmwxTTNDVHRQeEc2X25IRHZjMHlkVXBBcVVEamstSlFJNm51S1VqOTJoU3M1N2NFV1NodEgzTjRsalBOaFlQOWNudjM3a3VMUVhuQTFnN1k1QmlwQjhEQ1RlZEZSY2NWZHJnVXlqaUdlRA?oc=5",\n- "publishedUtc": "2026-07-26T06:57Z",\n+ "url": "https://news.google.com/rss/articles/CBMieEFVX3lxTFBhY040T195VGxaWVNUZnNnTVJGS0ktcTVIcjdaUE5Cb2ZiSXZpR0s2V2xabzdTaWN4QzRwUWp6aG9iY1Q5dVdiSFB3Sjc1bkZJUy1yamJoaEYybkp1SmNlTjlRdjB0V25VM212UXQzX1N6alZRQlJsMA?oc=5",\n+ "publishedUtc": "2026-07-24T03:51Z",\n "summary": "",\n "image": null\n },\n@@ -1,6 +1,6 @@\n {\n "source": "reuters",\n- "fetchedUtc": "2026-07-26T22:37Z",\n+ "fetchedUtc": "2026-07-26T22:43Z",\n "ok": true,\n "error": null,\n "items": [\n@@ -0,0 +1,78 @@\n+{\n+ "source": "simpleflying",\n+ "fetchedUtc": "2026-07-26T22:43Z",\n+ "ok": true,\n+ "error": null,\n+ "items": [\n+ {\n+ "title": "United Airlines' Oldest Active Jet Is 35 Years Old: Here's Where It's Still Flying",\n+ "url": "https://simpleflying.com/united-airlines-oldest-aircraft-routes/",\n+ "publishedUtc": "2026-07-26T22:00Z",\n+ "summary": "The carrier's most vintage planes date back to the early 1990s.",\n+ "image": "https://static0.simpleflyingimages.com/wordpress/wp-content/uploads/2026/07/shutterstock_2466656525_cropped.jpg"\n+ },\n+ {\n+ "title": "Boeing's 737 MAX 7 Is Finally Nearing FAA Approval & Southwest Airlines' Entire Next Decade Depends On It",\n+ "url": "https://simpleflying.com/boeing-737-max-7-finally-nearing-faa-approval-southwest-airlines-entire-next-decade-depends/",\n+ "publishedUtc": "2026-07-26T22:00Z",\n+ "summary": "Southwest Airlines has been waiting longer than ever for the Boeing 737 MAX 7, as its entire business model revolves around a single aircraft fleet.",\n+ "image": "https://static0.simpleflyingimages.com/wordpress/wp-content/uploads/2026/07/boeing-s-737-max-7.jpg"\n+ },\n+ {\n+ "title": "5 Things Passengers Don’t Know About Premium Economy",\n+ "url": "https://simpleflying.com/5-things-passengers-dont-know-about-premium-economy/",\n+ "publishedUtc": "2026-07-26T21:30Z",\n+ "summary": "The cabin continues to become increasingly popular.",\n+ "image": "https://static0.simpleflyingimages.com/wordpress/wp-content/uploads/2026/03/passengers-premium-economy.jpg"\n+ },\n+ {\n+ "title": "United Airlines’ Scott Kirby Also Approached Delta In Hopes Of A Megadeal, New Report Unveils",\n+ "url": "https://simpleflying.com/united-airlines-scott-kirby-approach-delta-megadeal/",\n+ "publishedUtc": "2026-07-26T21:25Z",\n+ "summary": "A new report reveals United CEO Scott Kirby approached Delta about a merger, highlighting his bold ambitions despite major antitrust hurdles.",\n+ "image": "https://static0.simpleflyingimages.com/wordpress/wp-content/uploads/2026/01/vs-2.jpg"\n+ },\n+ {\n+ "title": "How Much A Delta Air Lines Flight Attendant Actually Earns During The 30 Minutes Before Door Close",\n+ "url": "https://simpleflying.com/how-much-delta-air-lines-flight-attendant-actually-earns-during-30-minutes-before-door-close/",\n+ "publishedUtc": "2026-07-26T21:00Z",\n+ "summary": "The first airline to solve a long term grievance.",\n+ "image": "https://static0.simpleflyingimages.com/wordpress/wp-content/uploads/2026/07/delta-air-lines-flight.jpg"\n+ },\n+ {\n+ "title": "How Rolls-Royce Quietly Used The Airbus A330neo's Engine To Fix The Boeing 787's Broken One",\n+ "url": "https://simpleflying.com/how-rolls-royce-quietly-used-airbus-a330neo-engine-fix-boeing-787-broken-one/",\n+ "publishedUtc": "2026-07-26T20:00Z",\n+ "summary": "A crisis behind the scenes of the 787 success story finally ends.",\n+ "image": "https://static0.simpleflyingimages.com/wordpress/wp-content/uploads/2026/07/a330neo-s-engine.jpg"\n+ },\n+ {\n+ "title": "9-Hour Flights: Breeze Airways' 11 Longest Airbus A220 Routes Revealed [Map]",\n+ "url": "https://simpleflying.com/breeze-airways-longest-airbus-a220-routes/",\n+ "publishedUtc": "2026-07-26T19:00Z",\n+ "summary": "Have you ever flown on one of these one-stop odysseys?",\n+ "image": "https://static0.simpleflyingimages.com/wordpress/wp-content/uploads/2026/07/airbus_a220-371_-n216bz-_cn_55172-_-3-11-2024.jpg"\n+ },\n+ {\n+ "title": "5 Engineering Decisions That Explain Why The Boeing 787 & Airbus A350 Feel Nothing Alike Inflight",\n+ "url": "https://simpleflying.com/5-engineering-decisions-explain-boeing-787-airbus-a350-feel-nothing-alike-inflight/",\n+ "publishedUtc": "2026-07-26T18:00Z",\n+ "summary": "The 787 and A350 are both composite widebodies. Here are the five engineering decisions that explain how they differ.",\n+ "image": "https://static0.simpleflyingimages.com/wordpress/wp-content/uploads/2026/07/5-engineering-decisions-that-explain-why-the-boeing-787-airbus-a350-feel-nothing-alike-inflight.jpg"\n+ },\n+ {\n+ "title": "The World’s Largest Air Forces By Number Of Pilots",\n+ "url": "https://simpleflying.com/worlds-largest-air-forces-by-number-pilots/",\n+ "publishedUtc": "2026-07-26T17:30Z",\n+ "summary": "Which air force has the deepest roster?",\n+ "image": "https://static0.simpleflyingimages.com/wordpress/wp-content/uploads/2025/09/largest.jpg"\n+ },\n+ {\n+ "title": "8-Hour Route: Air Arabia Launches 3rd Daily Nonstop Flight To London [Map]",\n+ "url": "https://simpleflying.com/air-arabia-8-hour-gatwick-route-grows-to-3-daily/",\n+ "publishedUtc": "2026-07-26T16:09Z",\n+ "summary": "Air Arabia will launch a third daily Airbus A321LR flight between Sharjah and London Gatwick from October, boosting UK-Asia connectivity.",\n+ "image": "https://static0.simpleflyingimages.com/wordpress/wp-content/uploads/2026/07/shutterstock_2445797177_cropped.jpg"\n+ }\n+ ]\n+}\n@@ -0,0 +1,183 @@\n+{\n+ "source": "twtransport",\n+ "fetchedUtc": "2026-07-26T22:44Z",\n+ "ok": true,\n+ "error": null,\n+ "items": [\n+ {\n+ "title": "快訊/台鐵深夜爆死傷事故!1人侵軌…遭區間迎面撞上",\n+ "url": "https://news.google.com/rss/articles/CBMi1AJBVV95cUxPQ2FQck9JTEI3YTJDRXcxVEhsWDhQNmRSNTYzU3V2WFZXcXdyQlF0QUZLX25jZTNvelZZMEZFbVVjMXpya281UEd6d3ZQcDFOUjBiYUpHLUNTVkNmOTlBWXlrTUJ5clhuMW5GcktJbkhnLWNJa2k2MnpXT1NaWUhGbGJmeHN2Q2N1Sk93MWk5M2JHMzhqb0J0QnduREVxQ0FDUzA4Sm1idmFROEFoZG9FZ3l2blkwOTZiMlAyQl9aNTUzR2ZMb2hvdXNJaFJNajNGNGtlcEpUZGt0Mnl4RE5nMjZTcTByNkhKTW1tR0gxQ3ZUWkMtWXNIRXF6Q2RIREdkTGgwekNMZ3lzN2puSEJtV1o2Q05JWUlkc3U0S2dpcmVfRm1oOTQ1SDJUczNTY2FkSlU3UEEyZWx3OGNndFVfcnF4RXp6Y216dlNVLUNYbjA2YXk2?oc=5",\n+ "publishedUtc": "2026-07-26T14:44Z",\n+ "summary": "",\n+ "image": null\n+ },\n+ {\n+ "title": "台鐵海線深夜重大事故…行人闖軌遭撞 路線中斷1.5小時恢復",\n+ "url": "https://news.google.com/rss/articles/CBMiUEFVX3lxTFBGcVEwcUtMMnlaX25QeUtIaWpQWEhFUU55dU1IbGpjVGlfMzgwVjZLazlfSlh2VjlYZlJCWXBRUEoxeVZoN3BZRTZkMGx5bno20gFWQVVfeXFMT0E3b3JFelJZR084VlN6M0ZpT0lxZWZBVnpIUlBWTXdKdmV6bXFsU3pqUExaVm5ZQUsxNmxydDM5c2JJdjBDLVF2U1ZYeW0zZ2YtUWtKRlE?oc=5",\n+ "publishedUtc": "2026-07-26T16:30Z",\n+ "summary": "",\n+ "image": null\n+ },\n+ {\n+ "title": "【台鐵死傷事故 民眾闖平交道遭輾斃「支離破碎」慘死...身分待查】 (#大表哥)",\n+ "url": "https://news.google.com/rss/articles/CBMiugNBVV95cUxNSWt4WlhaY0VIellLajlHTXRJOGJBNzhVWjNxX1ZobzhhZ1JXbUhxQkZRNVUtNlR6eVNjX1lYY1F1anR0TFoyU0xsbWlMR1A3d3ZVQzhjeUhyb2RhZUlpZ0MzUHBtZVlEY3R5d1NtOGRnRVQtcTZMSVhRRldtaEVBY2l4MEpCbTdQR3p4R3JudXhiNzk0c0laa2JIYkw5Z1FsS1N4OFNzTDJJdzZzbE1XNXNwOUdoNUFOa0pVZ2J6cmhuSVFGLUlmVkJNb1NjY3dxbk4xRFQ5bGQ4YVFyWnRYOU94UzVvRFhvcTRNM2VQcS14bU05WnlLU2dUWndtXzltWWNCUGhHRlFOSE0xeEd4NGx5VkFRRXdKVTQxT3dHSk9kUTFBck5UR096Z2UtVkpTeDBpanFMOHd3M28yOVJfbWwySjVJMVlMRWlfOGJmSkFfMWVfZGpYd3ZFaUVWN2dGcHN1V1ZmRm41SXg0QjNJV2hfa1I2cE5EblFPYUgzZDVoRW8zVjhzRktpMlRGOGVVNGdySEhuV3hTMENPSlVWSGxfYXpremtfMTJIak9FWV9LeHBjQ0lQOWtB?oc=5",\n+ "publishedUtc": "2026-07-26T22:28Z",\n+ "summary": "",\n+ "image": null\n+ },\n+ {\n+ "title": "台鐵沙鹿至龍井段突發死傷事故 行人被撞遺體四散 雙向路線受阻",\n+ "url": "https://news.google.com/rss/articles/CBMiaEFVX3lxTE5YSXhJX0IxOXdQZHJlaVVfWUxRVllId0hwbTdJRkw1c3lwelFfcFpQdTdNYkRXcGN0YUNRcHpuWjNscHY5UDRnc2Y2OTREZGFkSHhHOHJlUXAyX3RaQmd0S3c2eUZBYWkw0gFuQVVfeXFMTzFnai1ZV0R5Z2ZYdkdoUGoxRGZ0cFRPNENXOWJ4VzhWSG9VdVV0dDVTSVNxR25lSVFOUU5Pbkt4VWFPVTFYYjFNTjNwX1pENUVXNkhRR0ZJeDlwYkNXdHFsNGZPdGRja2NyM2lEeVE?oc=5",\n+ "publishedUtc": "2026-07-26T15:23Z",\n+ "summary": "",\n+ "image": null\n+ },\n+ {\n+ "title": "快訊/台鐵死傷事故!民眾入侵軌道遭撞 「沙鹿=龍井」暫時不通",\n+ "url": "https://news.google.com/rss/articles/CBMiT0FVX3lxTFB0MzlyNlpDOWdPY0NjTjVZTHFDT1NEM0dBem4xY2FHb0MtM1BRYlljQlpPMHdQTkhHcXQtNEZ3bllxTXJvN0FoWjlqbkRxSnM?oc=5",\n+ "publishedUtc": "2026-07-26T14:45Z",\n+ "summary": "",\n+ "image": null\n+ },\n+ {\n+ "title": "雙溪地震新北捷運一度停駛目前慢速行駛巡軌中| 生活",\n+ "url": "https://news.google.com/rss/articles/CBMiX0FVX3lxTE90OFlMQmFFNFoyUjNkTHpYZVQwTTFHdFVvaEJGMDVCNGVCRjZJTlRVV3BXSUY1SlJHZktyUFQ2bGZVeW1LRVpIdWpVcGVfRGZ0dkE3R2YyT0w2a095d2VV?oc=5",\n+ "publishedUtc": "2026-07-26T12:57Z",\n+ "summary": "",\n+ "image": null\n+ },\n+ {\n+ "title": "台鐵龍井平交道撞死人!民眾遭區間車輾斃「支離破碎」 身分待查",\n+ "url": "https://news.google.com/rss/articles/CBMiXkFVX3lxTE5pVXhUb0tNcVJXTTEzS1pzajFEd2c4ZHgtakMxU3hIb0kwck5sTU5FQlMwamh2ZVlqcVBRNlhEVEM0TE9PWUdwYVNXSjJyTVNDd3RyNEhMS3VnUHhvaEHSAUtBVV95cUxPM1Uycy1qbXZFeXVFWnlwblZoeDRsb1RTejdXcUJUMG05ZmF0Mnh1U0h6bFlPanJRUGFDSXRvWkNJU2FIdUFNcmFydnM?oc=5",\n+ "publishedUtc": "2026-07-26T15:15Z",\n+ "summary": "",\n+ "image": null\n+ },\n+ {\n+ "title": "雙溪規模5.6地震! 北捷全線恢復正常行駛 高鐵不影響列車運轉",\n+ "url": "https://news.google.com/rss/articles/CBMiV0FVX3lxTFBPcFh0ZFVHMHJKc0lveDZfZWZXU1pHbUEwNFQ3aGIyM3g0T2x4cUdHMmwwZDR1bkdfOFJGeWxfSG9ualE2ZXNsTWlxYWtwQjltUXc5WjBuWQ?oc=5",\n+ "publishedUtc": "2026-07-26T12:43Z",\n+ "summary": "",\n+ "image": null\n+ },\n+ {\n+ "title": "最新/台鐵深夜爆死傷事故!行人疑在沙鹿平交道被列車撞到 南北向列車全面延誤",\n+ "url": "https://news.google.com/rss/articles/CBMiYEFVX3lxTE1NZUJKYWNGZ1p1WktHZy1taV9LcE5zQXBRdnJ2Qndfb1ZlMnlQcmdCbEJjV293a01JeFhoMldPUjg1NEdlOFlsaEdrQ3pSNmJuZG10aEpPUHRRTzlPd3locA?oc=5",\n+ "publishedUtc": "2026-07-26T14:48Z",\n+ "summary": "",\n+ "image": null\n+ },\n+ {\n+ "title": "快訊/台鐵突發死傷事故!沙鹿至龍井雙向封閉",\n+ "url": "https://news.google.com/rss/articles/CBMiVkFVX3lxTFA3aldDRlFIUWQ2OWc3V1FwRWM3bG1fcXZoM3hmbG5xNm1aRjRaVGtXR05FbmRBcmcyckRLdkpwUHFWcGtqVmx4bUYtejBvNWJZZW5ZdHl3?oc=5",\n+ "publishedUtc": "2026-07-26T15:16Z",\n+ "summary": "",\n+ "image": null\n+ },\n+ {\n+ "title": "快訊/台鐵突發死傷事故!沙鹿至龍井雙向封閉",\n+ "url": "https://news.google.com/rss/articles/CBMiugJBVV95cUxPYkd1cUZCRHJhUFNvOEJ3RDdWWVUtNkN6RHh4VEpma2tGXzZzTlFOdkdSZnB2ODdLTmtsVUc2UERxM2ZQa25iR0trTVpTckhWcXVSRmdGM0s4TzBaMXNPM0Z5WVlPXzZjeWdoWHk2ZWZIZHVzWWhPZktkZGd0dk1Gdm5ZX3lPR1EzUENEUUJzOEJ1cjU2MWRpZlZ0Zm5MdVl1N1piVW93c1FOUk51OG1US1B6ZlNwaXlSSVh1VjdkaE1CREg1OGlPcW9BUGlPb1ktV1pERzZlWHhubzJBWDFYcGpmNmJMYVo0MUI3QWpsSmVWd2h0ZDZvbS03b1l5VXJqWExRNWI0QWhxOWlPWTFTS3I4eTY2bmtiR05tR3FfZEJUMzRkdW5fbkZRQnNfUTFiYXpubm0zZlpCUQ?oc=5",\n+ "publishedUtc": "2026-07-26T15:16Z",\n+ "summary": "",\n+ "image": null\n+ },\n+ {\n+ "title": "雙溪規模5.6地震 新北捷運慢速行駛後已恢復正常營運",\n+ "url": "https://news.google.com/rss/articles/CBMiZEFVX3lxTE9QalFtdklBbS1xeUN4VTZfeEJQclBDN0VYeFFvNWNtWk1kSThkckZnTXI4MzRhMkJZQ0F6Zm5BOFgyallzLVA1a2JVMzAySlpBeFQ2SGpNNldGSlQzb3JFV2YzZjLSAWpBVV95cUxPT0d4eEZEWm5tMW1HY3ZlNEh1QThTWkg1TmhGLUpOU1dCUDRJSjV4MDFXd1JCRlQwZmI3NEFfa3B4ekJZSzhSNWlZY0h1V2lBLXhzTGNRU3B4c1dpVDBpc0ZfVUFsSGxlNjR3?oc=5",\n+ "publishedUtc": "2026-07-26T13:23Z",\n+ "summary": "",\n+ "image": null\n+ },\n+ {\n+ "title": "北部有感地震 新北捷運恢復正常營運",\n+ "url": "https://news.google.com/rss/articles/CBMiUEFVX3lxTE1sSHl3YnJSa3hrbzlYUTJfQzZxdk04b2ZnSTRMVE1SUzRfUDhLOWJlQ3hrVGFUZEdYTmtqenhPREhKcG9oMmIySjBEOVpBTUxa0gFWQVVfeXFMTmt5Ym84MWxCZF9tSy13M0pnNkk1dnpJN2tEbDBuOW9QTGQ3SWtNN24yNDE0cVF0cnlXMG1ua3JlU2plbkhCNkRXLWpkTmxnQjlsUWNLX1E?oc=5",\n+ "publishedUtc": "2026-07-26T13:25Z",\n+ "summary": "",\n+ "image": null\n+ },\n+ {\n+ "title": "台鐵沙鹿=龍井深夜傳死傷事故!民眾闖平交道被區間車撞到",\n+ "url": "https://news.google.com/rss/articles/CBMiVkFVX3lxTE9qSWhydTN4S2kwUmRBXzN2akFYbEdOWm1jeXFHM1cxazRKMGhMeUlzWDJlSWVJM2lzaE9HSTJob1pmdDJxTnVyNnVaaFpVUW5IOFVMVVNR0gFWQVVfeXFMT2pJaHJ1M3hLaTBSZEFfM3ZqQVhsR05abWN5cUczVzFrNEowaEx5SXNYMmVJZUkzaXNoT0dJMmhvWmZ0MnFOdXI2dVpoWlVRbkg4VUxVU1E?oc=5",\n+ "publishedUtc": "2026-07-26T14:53Z",\n+ "summary": "",\n+ "image": null\n+ },\n+ {\n+ "title": "台鐵深夜發生死傷事故!沙鹿至龍井路段封閉 南北列車全面延誤",\n+ "url": "https://news.google.com/rss/articles/CBMiTEFVX3lxTE1XZllCTzhuZlNNVXhXNzZQUWJWR3RjbE9VcGc3THZ4SlRIcHJwNVFGN3hocGR4N2JacW1BbFNNMU5vS1NkLWNlNEVjTWnSAVJBVV95cUxPNmgxNGNMYXcyTlNSRFFCanZ3Y2tINWZSR0RSZE04SGJyQnBpRURCam0zbW00MmhVN1dwQVg2ZmpIMzNOZXd4QnQ1c0dPOXh3WHdB?oc=5",\n+ "publishedUtc": "2026-07-26T14:42Z",\n+ "summary": "",\n+ "image": null\n+ },\n+ {\n+ "title": "台鐵「告白平交道」區間車撞行人現場僅剩血跡、屍塊- 社會",\n+ "url": "https://news.google.com/rss/articles/CBMibkFVX3lxTFA3MU1SOHJhVzdIR1R0bGl5eGtCQ3o5ZDAyVlMtdXJ6LS1WbTBBbDFyR0dOMVZzY2RiV0FVcXpfU2k4Z0ZzM2VONXpEYURmbU54UDZXOG5KZTJqQ1VPek9VTzZha3lhdU9VN2p6blVn?oc=5",\n+ "publishedUtc": "2026-07-26T14:30Z",\n+ "summary": "",\n+ "image": null\n+ },\n+ {\n+ "title": "台風“紅霞”逐漸減弱 香港高鐵服務逐步恢復",\n+ "url": "https://news.google.com/rss/articles/CBMiZkFVX3lxTE04czdubFo4TDZweWw1Z2pEcGJhUm5YQUJZcm5XNFRsSnlvdWJiSTV0a192ZWpLM0dvMm1NOU5rRWNKSXRMR05pWU5ILVVHeFlnbFl2V01hRWlJeHU3WDlfRnZKMjdKUQ?oc=5",\n+ "publishedUtc": "2026-07-26T10:11Z",\n+ "summary": "",\n+ "image": null\n+ },\n+ {\n+ "title": "颱風紅霞| 廣東多條鐵路26日有序恢復通行廣深港高鐵部分班次下午起恢復運營- 神州",\n+ "url": "https://news.google.com/rss/articles/CBMid0FVX3lxTE1MOS1GSWNRdlN4NmpJa3lyX2VGdHNlUkhveGVsTWtUUG5VcURfdVhpSFY2Z2pRd1Jrc0NFYThnQmg5VEt3QUsxZzRZejI1N1QtX0RsTDFIUVRIX1A2WnNkaWR6Z3FQNDRZLWxjaEo1dGVVRW1nR3Uw?oc=5",\n+ "publishedUtc": "2026-07-26T08:30Z",\n+ "summary": "",\n+ "image": null\n+ },\n+ {\n+ "title": "紅霞影響趨緩 金廈小三通今上午10時5分起恢復雙向航駛",\n+ "url": "https://news.google.com/rss/articles/CBMiXkFVX3lxTE9UM1luU1V3Um1DLWFzY1NSNTVQbGloU0s2MXRublRqVTNmWWxqRm9IUzJuT2RMU1pWeHRrMzdJamZFRmNfWnhUdUNLb3E1SlItX0lPdWpReWc5Mzk3NVHSAUtBVV95cUxNMFlvTEYwZEdhVDYyWkxGc0c1d1k0QW5kYV9TVzluelg5RHpadEVCRy1oejdIckZZdVBtSGYwalFPSGo2endQalVXTHM?oc=5",\n+ "publishedUtc": "2026-07-26T00:57Z",\n+ "summary": "",\n+ "image": null\n+ },\n+ {\n+ "title": "打風.紅霞襲港|港鐵部分露天段列車恢復有限度服務高鐵今日下午4時前來往西九龍站列車班次取消",\n+ "url": "https://news.google.com/rss/articles/CBMi0ARBVV95cUxNakdWR1lNVnZ2S2ZSVDJpY2hmbkpvcmRNS2YyWjBKZmNzLS1VSUZQMDlQNmxHV1FSRmhuVzZTdGhNZE83OWpKcVZTRzU2MkNNUWViclBtZ2lqQU5YZ19XcFBsRDFGSDVCS0JZRnVKWHFiRHdhWFNkOWFuX05UY1pmVDJXVVBZT1ppN2ZUTnZKdldGMVdmNmN2cDlVSUhPTUJfM0U5dDFuUEMyaHpiREp6Ym5MeE9JZVZxYVhucGhEMjZEMXJKUjJyQW9BWGxDRUFPYmxGYWk5ME56OEFoU1dpRVB4UllGbmNLcmdkWmRrYTUxLThuOE13ZDFaT1VzaUZxdGtLN29XMGtrTW5uNDY4RXRacFFzOUpaVV9fSHFUWDVUYm5pQ29tNnNEcnFMM01teHZhX3BBbWJPOEtZZnM4TUgtWHVLWjVLZVJpbGI0RW5RNDNaeVZud05uV2FEeGtMZXhmQVRydFFXWWtGQjBaLUNTNi15eDVNNzRleU5FOFhoeVBpd0twZXVBdlY1YkpNLVZWMU1uNVU5bS1GZzItbzdlV2xRYlZPRjB6RkFENVFoOTRCaFg3NkttZWpqLUJvZEUyUWRyenFycXVsejBGeGdycnhESlQ1bGktcEJzdF9UU09wcTlxelpuX1dmUW5aM0FweXBGcVJLV3kya19YWXZ1SE41YkZWcFdMa0t0NklpWDJfSVVzLUxKYzVyaWMwWEJFRktvdUoxQlVUZTNscE1LY2ZNRGpXQVA2TFFacU4yWm9KVk8taW1rYVJ1djdu?oc=5",\n+ "publishedUtc": "2026-07-26T05:00Z",\n+ "summary": "",\n+ "image": null\n+ },\n+ {\n+ "title": "颱風紅霞.交通消息|機管局:全日處理約670航班 約360航班取消 目標明早回復正常運作",\n+ "url": "https://news.google.com/rss/articles/CBMi7ANBVV95cUxOdHloRDE0dEkzUDZNZzcydG5WclM5LURJdE9fVDFid2YzeUlsUEFiQlZTTlhjanNyUkYzZVo3eURoVUE3THUyME9hcVRzTUEtaHFiMkZrQnV0TmNEUzkzODZmekZ5QmljX0MtVjRoNnZNOG5RaUNVU1FXZWc4QV85Si1mdlZPUkc1Ql9SVlBPWE44OHpfZ1UxT1JackxyQUhKWFYta3RyLWM0RWVBcWttdTdPczVYRXE0RHNTQmdUYWw4bFdTMjV3X0xCVVpKVmZrbzNaUGoxZ1RYMEhQbVA1VWpKMXYyeXdzV2hOb0RhYnUwMUk0SjNGMm15VVRfdGM4OHNTLXVCeElZY01Kd0FORjVoNkhlVU8zTFh6Q09oZVJYcXEyNk04dHV6cWxuQThuV29WdU9uZm9GU1pkS1FOTThEN1RRN25yTjVBcS1abXQzSlQwdGFSOUt5cjAyZF8xVi14R2V2ZVc3ODlrb3ktQ2hveVVUY3A2bzZ6WnJvd3VCQUNmaTJBS1ljOF94d1JBWVhpRExKR2ZrWlAzT25VREhIYUNpWHRablFvTTBHTVRfZ1ZEWUMxOTFncUdBQkQ2TE40QnVtVlQtdlprY3hjV2tOZjkwRXpHa2pGWXdsUjJNQ21FUDdreThzSm0?oc=5",\n+ "publishedUtc": "2026-07-26T09:57Z",\n+ "summary": "",\n+ "image": null\n+ },\n+ {\n+ "title": "颱風紅霞|深圳地鐵:恢復運營!",\n+ "url": "https://news.google.com/rss/articles/CBMid0FVX3lxTE5nZ01HQUhqR1Jjdndfa1E1Q21LSVc2RnZGaUhvRUFrbkpQbU5zVnBsX3h3MVVTSlRELVFrdEZRMUotQjNtVnFIWUExTmNBUENaTjc0cmhUMWNIS1ZEQWozRnQ2Y3pVc2xlRWhFYVFMSU81ZDdPWHNN?oc=5",\n+ "publishedUtc": "2026-07-26T02:08Z",\n+ "summary": "",\n+ "image": null\n+ },\n+ {\n+ "title": "颱風紅霞|深圳地鐵所有車站恢復營運 下午2時前253航班取消",\n+ "url": "https://news.google.com/rss/articles/CBMingNBVV95cUxQXzIzbnhRRnlKeXh1TWdIcHE1bnJMNG1IQ1VWeE8tX0x1aWlDZVZmemUxUkQ0VUJTNjNmMU1vQkxEcWZWRUJBWDN4S0JBUTBmN01PamdKMVhNOThoZzFUUG11eVpvVVJKYUV2REE5VXF4NEJ3bzE5cjdQbTZ6SEdJdjZGM3hQTGU3VnRxSU9xSUN5RzhQM1R4V052OXNZbWxQVHh1WnM4UXQ3RmRrX19XLW55amVXQ2U5azhLaWVYM3VraGxXRWE0NngxdlNFSEl4c2E5WlQ0eEZLR3pWdHcyMXd0djBqeENVak90SnVWclBNOHVxamwtUDBfdHB2MXVPbDBRRHY3NjRQeExRQlg2eE5SeVowcFZIZ0dLc3Q3a2VpNlNrUm9CekxycDVPX3lKaHViMHZoRGZ0QURjTHFaOHZLcERuX01GaU9jWG5oWG9fN2h3dVpTV2ZHVW1iNm1HSW9WNHVLajRIOVNSSl9ncFllOVE3OXJDZ3o3UDNBZDVoTVRNekwzMFZHc2NLZVVKQVJyeFJMbmhSa0xJUnc?oc=5",\n+ "publishedUtc": "2026-07-26T03:28Z",\n+ "summary": "",\n+ "image": null\n+ },\n+ {\n+ "title": "八號風球生效 港鐵及巴士服務逐步恢復 高鐵多班次取消",\n+ "url": "https://news.google.com/rss/articles/CBMinAFBVV95cUxOd2xnVTVqWl9EUk93dkNYYVFieV9GZk02YXJDc3A3ZTdnSmh3NWR1T0FmUEdkNWtDTlMxUEp1UTJaNzgxb1BTRUFCeFFUNFA4R3Q5UHVTR3BXbS1jNnFjZHBpWXVWaHk0YmNWWjBwb2pHc3BGRVBEQnRYLVBfOTktZjFmblpBUzNTZUhneVBBbGRRTU5GWXBMWUtDYzg?oc=5",\n+ "publishedUtc": "2026-07-26T01:26Z",\n+ "summary": "",\n+ "image": null\n+ },\n+ {\n+ "title": "打風致全省高鐵停運 深中通道一度封閉",\n+ "url": "https://news.google.com/rss/articles/CBMiiwFBVV95cUxOeUJ1ZExrSFVHNFFDVU9DUThWbWF3QThiTEoxcUZteEdvOUk3R2hJc3JYdEN3RTlkOTVENDVxNHU2a2VTalk5T2ZZMGxmWkVCazJFT2NoTWhJWnJfQ0o1Ymp6eE5oLUxZa1NpQ2hPRkdTdFRxRWhDTVEyTTdmQmV2VmFheWFBVVMwTkxN?oc=5",\n+ "publishedUtc": "2026-07-26T03:26Z",\n+ "summary": "",\n+ "image": null\n+ }\n+ ]\n+}\n@@ -9,7 +9,7 @@\n "zh": "美國聯邦航空總署 — 新聞、AD、法規",\n "en": "US regulator — news, ADs, rules"\n },\n- "lastFetchUtc": "2026-07-26T22:37Z",\n+ "lastFetchUtc": "2026-07-26T22:43Z",\n "ok": true\n },\n {\n@@ -22,7 +22,7 @@\n "zh": "美國運輸安全委員會 — 事故調查",\n "en": "US accident investigator"\n },\n- "lastFetchUtc": "2026-07-26T22:37Z",\n+ "lastFetchUtc": "2026-07-26T22:43Z",\n "ok": true\n },\n {\n@@ -35,7 +35,7 @@\n "zh": "國際民航組織 — 標準與環境",\n "en": "UN body — standards & environment"\n },\n- "lastFetchUtc": "2026-07-26T22:37Z",\n+ "lastFetchUtc": "2026-07-26T22:43Z",\n "ok": true\n },\n {\n@@ -48,7 +48,7 @@\n "zh": "產業數據與政策",\n "en": "Industry data & policy"\n },\n- "lastFetchUtc": "2026-07-26T22:37Z",\n+ "lastFetchUtc": "2026-07-26T22:43Z",\n "ok": true\n },\n {\n@@ -61,7 +61,7 @@\n "zh": "歐盟航空安全局 — AD 與安全公告",\n "en": "EU safety agency — ADs & bulletins"\n },\n- "lastFetchUtc": "2026-07-26T22:37Z",\n+ "lastFetchUtc": "2026-07-26T22:43Z",\n "ok": true\n },\n {\n@@ -74,7 +74,7 @@\n "zh": "歐洲空管網路狀態",\n "en": "European network operations"\n },\n- "lastFetchUtc": "2026-07-26T22:37Z",\n+ "lastFetchUtc": "2026-07-26T22:43Z",\n "ok": true\n },\n {\n@@ -87,7 +87,7 @@\n "zh": "路透社航太與國防版",\n "en": "Reuters aerospace & defense"\n },\n- "lastFetchUtc": "2026-07-26T22:37Z",\n+ "lastFetchUtc": "2026-07-26T22:43Z",\n "ok": true\n },\n {\n@@ -100,7 +100,7 @@\n "zh": "全球事故事件專業追報",\n "en": "Global incident tracking"\n },\n- "lastFetchUtc": "2026-07-26T22:37Z",\n+ "lastFetchUtc": "2026-07-26T22:43Z",\n "ok": true\n },\n {\n@@ -126,7 +126,59 @@\n "zh": "交通部民航局 — 航班異動與公告",\n "en": "Taiwan CAA notices"\n },\n- "lastFetchUtc": "2026-07-26T22:37Z",\n+ "lastFetchUtc": "2026-07-26T22:43Z",\n+ "ok": true\n+ },\n+ {\n+ "key": "simpleflying",\n+ "name": "Simple Flying",\n+ "kind": "media",\n+ "fmt": "RSS",\n+ "url": "https://simpleflying.com",\n+ "cover": {\n+ "zh": "全球航空新聞與產業分析",\n+ "en": "Global aviation news & analysis"\n+ },\n+ "lastFetchUtc": "2026-07-26T22:43Z",\n+ "ok": true\n+ },\n+ {\n+ "key": "cnataiwan",\n+ "name": "中央社 CNA",\n+ "kind": "media",\n+ "fmt": "RSS",\n+ "url": "https://www.cna.com.tw",\n+ "cover": {\n+ "zh": "中央社 — 航空、軍航與交通相關報導",\n+ "en": "CNA Taiwan — aviation, military air & transport"\n+ },\n+ "lastFetchUtc": "2026-07-26T22:44Z",\n+ "ok": true\n+ },\n+ {\n+ "key": "mndnews",\n+ "name": "國防部・軍聞社",\n+ "kind": "official",\n+ "fmt": "RSS",\n+ "url": "https://www.mnd.gov.tw",\n+ "cover": {\n+ "zh": "國防部/軍聞社 — 共機動態與軍事新聞",\n+ "en": "Taiwan MND — PLA activity & military news"\n+ },\n+ "lastFetchUtc": "2026-07-26T22:44Z",\n+ "ok": true\n+ },\n+ {\n+ "key": "twtransport",\n+ "name": "臺灣交通要聞",\n+ "kind": "media",\n+ "fmt": "RSS",\n+ "url": "https://news.google.com",\n+ "cover": {\n+ "zh": "台鐵/高鐵/捷運/海運重大營運與事故報導",\n+ "en": "Taiwan rail / metro / maritime major events"\n+ },\n+ "lastFetchUtc": "2026-07-26T22:44Z",\n "ok": true\n }\n ]\n@@ -171,20 +171,21 @@ def get_briefing_window(edition: str, taipei_date: date) -> BriefingWindow:\n "澎湖", "金門", "馬祖", "中華航空", "華航", "長榮航空", "星宇航空",\n "台灣虎航", "臺灣虎航", "立榮航空", "華信航空", "taiwan", "taoyuan",\n "caa taiwan", "china airlines", "eva air", "starlux", "tigerair taiwan",\n- "uni air", "mandarin airlines",\n+ "uni air", "mandarin airlines", "國防部", "臺海", "台海", "國軍",\n )\n _GROUND_MARKERS = (\n "台鐵", "臺鐵", "高鐵", "捷運", "輕軌", "鐵路", "國道客運", "公路重大",\n- "railway", "high-speed rail", "metro line", "light rail", "train derail",\n+ "出軌", "railway", "high-speed rail", "metro line", "light rail",\n+ "train derail",\n )\n _MARITIME_MARKERS = (\n "港務", "航港", "海運", "商港", "貨輪", "客輪", "渡輪", "船舶",\n- "maritime", "ferry", "cargo ship", "container ship", "port authority",\n- "vessel",\n+ "小三通", "船班", "maritime", "ferry", "cargo ship", "container ship",\n+ "port authority", "vessel",\n )\n _MILITARY_MARKERS = (\n- "軍機", "國軍", "空軍", "軍用機", "military aircraft", "air force",\n- "fighter jet",\n+ "軍機", "國軍", "空軍", "軍用機", "共機", "中共軍機", "中共機艦",\n+ "解放軍", "戰機", "military aircraft", "air force", "fighter jet",\n )\n _FATAL_MARKERS = (\n "罹難", "死亡", "喪生", "身亡", "fatal", "killed", "fatalities", "died",\n@@ -93,10 +93,12 @@\n "brGenerated": "系統整理完成", "brTo": "至",\n "brEmpty": "截至本期資料截止時間,系統在本次查核的指定來源中,未發現符合收錄門檻的新事件。",\n "brPartial": "本期部分來源資料未能完整取得,內容可能不完整;來源擷取失敗不代表沒有新事件。",\n- "brChecked": "本期查核來源", "brWarnings": "資料覆蓋提示",\n- "brUpdate": "更新", "brItems": "則", "brNoItems": "本分類本期無收錄項目",\n+ "brChecked": "📡 本期查核來源", "brWarnings": "資料覆蓋提示",\n+ "brUpdate": "更新", "brItems": "則",\n+ "brNoItems": "本期查核來源中,此分類無新增符合收錄門檻的事件通報",\n "brModeDet": "程式化組裝(未使用模型)", "brModeLlm": "模型輔助導言",\n- "brSecs": ["航空事故與事件", "臺灣航空", "國際航空", "陸運與海運"],\n+ "brSecs": ["🚨 飛安事件與緊急狀況", "🇹🇼 台灣航空動態(民航+軍航)",\n+ "🌐 國際航空產業動態", "🚄 地面與海運交通"],\n "brSevs": {"fatal": "致命", "serious": "嚴重",\n "significant": "重要", "routine": "一般"},\n "sevs": ["全部", "事故", "嚴重事件", "事件"],\n@@ -148,13 +150,16 @@\n "brCutoff": "Data cutoff", "brGenerated": "Compiled", "brTo": "to",\n "brEmpty": "As of this edition's data cutoff, no new events meeting the inclusion bar were found in the sources checked for this edition.",\n "brPartial": "Some sources could not be fetched in full for this edition; coverage may be incomplete. A fetch failure does not mean no events occurred.",\n- "brChecked": "Sources checked", "brWarnings": "Coverage notes",\n+ "brChecked": "📡 Sources checked", "brWarnings": "Coverage notes",\n "brUpdate": "UPDATE", "brItems": "items",\n- "brNoItems": "No items in this section this edition",\n+ "brNoItems": "No new events met the inclusion bar in this section "\n+ "among the sources checked",\n "brModeDet": "Deterministic assembly (no model used)",\n "brModeLlm": "Model-assisted intro",\n- "brSecs": ["Aviation incidents", "Taiwan aviation",\n- "International aviation", "Ground & maritime"],\n+ "brSecs": ["🚨 Safety events & emergencies",\n+ "🇹🇼 Taiwan aviation (civil + military)",\n+ "🌐 International industry news",\n+ "🚄 Ground & maritime transport"],\n "brSevs": {"fatal": "Fatal", "serious": "Serious",\n "significant": "Significant", "routine": "Routine"},\n "sevs": ["All", "Accident", "Serious", "Incident"],\n@@ -1093,7 +1098,18 @@ def brief_item_view(item, lang: str, published_ids):\n art_id = item.get("article_id")\n url = (page_url(lang, f"news/{art_id}/")\n if art_id in published_ids else None)\n+ severity = str(item.get("severity") or "routine")\n+ marks = ""\n+ if severity == "fatal":\n+ marks += "⚠️🔴"\n+ elif severity in ("serious", "significant"):\n+ marks += "⚠️"\n+ if item.get("taiwan_priority"):\n+ marks += "🇹🇼"\n+ if item.get("military"):\n+ marks += "⚔️"\n return {\n+ "marks": marks,\n "headline": head, "summary": summary,\n "time": _fmt_tpe(item.get("source_published_at"), lang,\n time_only=True),\n@@ -264,6 +264,76 @@ def group_has_material(group: dict) -> bool:\n "en": "Taiwan CAA notices",\n },\n },\n+ "simpleflying": {\n+ "name": "Simple Flying",\n+ "kind": "media",\n+ "fmt": "RSS",\n+ "url": "https://simpleflying.com",\n+ "endpoint": "https://simpleflying.com/feed/",\n+ "type": "rss",\n+ "cover": {\n+ "zh": "全球航空新聞與產業分析",\n+ "en": "Global aviation news & analysis",\n+ },\n+ },\n+ "cnataiwan": {\n+ "name": "中央社 CNA",\n+ "kind": "media",\n+ "fmt": "RSS",\n+ "url": "https://www.cna.com.tw",\n+ # official CNA feed (broad politics wire); the keyword filter below\n+ # keeps only aviation / military-aviation / transport items so the\n+ # editorial stage never burns model calls on unrelated politics\n+ "endpoint": "https://feeds.feedburner.com/rsscna/politics",\n+ "type": "rss",\n+ "keywords": [\n+ "航空", "民航", "航班", "機場", "航線", "華航", "中華航空",\n+ "長榮航", "星宇", "台灣虎航", "臺灣虎航", "立榮", "華信",\n+ "空軍", "軍機", "共機", "中共機艦", "國軍", "國防部",\n+ "無人機", "直升機", "戰機", "台鐵", "臺鐵", "高鐵", "捷運",\n+ "航港", "港務", "小三通", "船班",\n+ ],\n+ "cover": {\n+ "zh": "中央社 — 航空、軍航與交通相關報導",\n+ "en": "CNA Taiwan — aviation, military air & transport",\n+ },\n+ },\n+ "mndnews": {\n+ "name": "國防部・軍聞社",\n+ "kind": "official",\n+ "fmt": "RSS",\n+ "url": "https://www.mnd.gov.tw",\n+ # MND blocks direct RSS pulls (403); Google News headlines proxy the\n+ # official releases (共機動態 etc.); CNA items usually join the same\n+ # story group and provide the quotable material\n+ "endpoint": (\n+ "https://news.google.com/rss/search?"\n+ "q=site:mna.mnd.gov.tw%20OR%20site:mnd.gov.tw%20when:2d"\n+ "&hl=zh-TW&gl=TW&ceid=TW:zh-Hant"\n+ ),\n+ "type": "rss",\n+ "cover": {\n+ "zh": "國防部/軍聞社 — 共機動態與軍事新聞",\n+ "en": "Taiwan MND — PLA activity & military news",\n+ },\n+ },\n+ "twtransport": {\n+ "name": "臺灣交通要聞",\n+ "kind": "media",\n+ "fmt": "RSS",\n+ "url": "https://news.google.com",\n+ "endpoint": (\n+ "https://news.google.com/rss/search?"\n+ "q=(台鐵%20OR%20高鐵%20OR%20捷運%20OR%20航港局%20OR%20小三通)"\n+ "%20(事故%20OR%20停駛%20OR%20停航%20OR%20出軌%20OR%20恢復)"\n+ "%20when:1d&hl=zh-TW&gl=TW&ceid=TW:zh-Hant"\n+ ),\n+ "type": "rss",\n+ "cover": {\n+ "zh": "台鐵/高鐵/捷運/海運重大營運與事故報導",\n+ "en": "Taiwan rail / metro / maritime major events",\n+ },\n+ },\n }\n \n CATEGORIES = ("safety", "reg", "biz", "ops")\n@@ -38,6 +38,13 @@\n )\n \n TIMEOUT = 20 # seconds per request\n+\n+\n+def _matches_keywords(item: dict, keywords) -> bool:\n+ """True when any source keyword appears in the item's title+summary."""\n+ blob = (f"{item.get('title') or ''} "\n+ f"{item.get('summary') or ''}").casefold()\n+ return any(str(k).casefold() in blob for k in keywords)\n RETRY_DELAY = 2 # seconds between the two attempts\n RESOLVE_TIMEOUT = 6 # seconds for google-news link resolution\n MAX_RESOLVE_FAILURES = 3 # stop resolving after this many misses in a row\n@@ -498,6 +505,16 @@ def _fetch_source(session: requests.Session, key: str, spec: dict,\n if not raw_items:\n raise FetchError("page parsed to 0 items (layout changed?)")\n \n+ keywords = spec.get("keywords")\n+ if keywords:\n+ # Broad feeds (e.g. the CNA politics wire) keep only on-topic items,\n+ # so unrelated stories never reach the paid editorial stage.\n+ before = len(raw_items)\n+ raw_items = [it for it in raw_items if _matches_keywords(it, keywords)]\n+ if before != len(raw_items):\n+ print(f"[fetch] {key}: keyword filter kept "\n+ f"{len(raw_items)}/{before} items")\n+\n items = _finalize(raw_items, fetched_iso, load_json(raw_path, None))\n save_json(raw_path, {"source": key, "fetchedUtc": fetched_iso,\n "ok": True, "error": None, "items": items})\n@@ -58,6 +58,11 @@\n "www.icao.int", "icao.int",\n "www.iata.org", "iata.org",\n "www.eurocontrol.int", "eurocontrol.int",\n+ # official Taiwan defense releases (共機動態 etc.)\n+ "www.mnd.gov.tw", "mnd.gov.tw", "mna.mnd.gov.tw",\n+ # CNA articles arrive via CNA's own official feed with direct links;\n+ # robots.txt is still honored per fetch\n+ "www.cna.com.tw", "cna.com.tw",\n }\n \n # Text shown to the model AND used for quote verification is capped at\n@@ -3,7 +3,7 @@\n <div style="max-width:860px;margin:0 auto;padding:28px 20px 64px;">\n <a href="{{ base }}/{% if lang == 'en' %}en/{% endif %}briefings/" class="btn btn-ghost" style="margin-bottom:18px;">← {{ t.brIndexTitle }}</a>\n <span class="card-kicker">{{ t.brKicker }}</span>\n- <h1 style="font-size:32px;line-height:1.2;margin:10px 0 6px;">{{ b.title }}</h1>\n+ <h1 style="font-size:32px;line-height:1.2;margin:10px 0 6px;">✈️ {{ b.title }}</h1>\n <div style="font-size:17px;font-weight:700;margin-bottom:14px;">{{ b.date_label }}</div>\n <div class="text-muted" style="font-size:13px;line-height:2;border-top:2px solid var(--color-divider);border-bottom:2px solid var(--color-divider);padding:10px 0;margin-bottom:6px;">\n <div><span style="font-weight:800;">{{ t.brWindow }}</span>:{{ b.window_start }} {{ t.brTo }} {{ b.window_end }}(UTC+8)</div>\n@@ -26,12 +26,12 @@ <h1 style="font-size:32px;line-height:1.2;margin:10px 0 6px;">{{ b.title }}</h1>\n <p class="text-muted" style="font-size:14.5px;line-height:1.9;margin:0;">{{ t.brEmpty }}</p>\n </div>\n {% endif %}\n- {% for sec in b.sections %}\n- {% if sec['items'] %}\n+ {% for sec in (b.sections if b.total > 0 else []) %}\n <h4 style="margin:26px 0 4px;">{{ sec.label }}</h4>\n {% for it in sec['items'] %}\n <div style="padding:14px 0;border-bottom:1px solid var(--color-divider);">\n <div style="display:flex;gap:10px;align-items:baseline;flex-wrap:wrap;">\n+ {% if it.marks %}<span style="font-size:14px;">{{ it.marks }}</span>{% endif %}\n <span class="tag {{ it.sev_cls }}">{{ t.brSevs[it.severity] }}</span>\n {% if it.update %}<span class="tag tag-outline">{{ t.brUpdate }}</span>{% endif %}\n <span class="text-muted" style="font-size:12px;font-weight:800;">{{ it.time }}</span>\n@@ -48,8 +48,9 @@ <h4 style="margin:26px 0 4px;">{{ sec.label }}</h4>\n {% endfor %}\n </div>\n </div>\n+ {% else %}\n+ <p class="text-muted" style="font-size:13px;line-height:1.8;margin:6px 0 0;">{{ t.brNoItems }}</p>\n {% endfor %}\n- {% endif %}\n {% endfor %}\n <div style="border:2px solid var(--color-divider);padding:16px 20px 12px;margin-top:32px;">\n <h6 style="margin:0 0 10px;">{{ t.brChecked }}</h6>\n@@ -492,6 +492,44 @@ def install_fake_providers(providers):\n all(m not in _req for m in ("newsapi", "bing", "serpapi", "tavily",\n "exa", "perplexity")))\n \n+# ── section classification for the expanded source mix ──────────────────────\n+\n+def _art_text(text):\n+ a = make_article("a-cls", text, tpe(2026, 7, 27, 6))\n+ a["entities"]["locations"] = []\n+ a["zh"]["summary"] = text\n+ return a\n+\n+\n+check("小三通/船班 stories classify as ground_and_maritime",\n+ briefing.classify_section(_art_text("小三通航線多航次停航")) ==\n+ "ground_and_maritime")\n+check("台鐵 stories classify as ground_and_maritime",\n+ briefing.classify_section(_art_text("台鐵區間車出軌無人受傷")) ==\n+ "ground_and_maritime")\n+check("共機動態 stories are taiwan_aviation with the military flag",\n+ briefing.classify_section(_art_text("國防部公布中共軍機臺海周邊動態"))\n+ == "taiwan_aviation"\n+ and briefing._has_marker(\n+ briefing._text_blob(_art_text("中共軍機臺海周邊動態")),\n+ briefing._MILITARY_MARKERS))\n+\n+import build as _b # noqa: E402\n+\n+_mil_item = {"headline": "共機動態", "summary": "s", "severity": "routine",\n+ "taiwan_priority": True, "military": True, "item_type": "new",\n+ "sources": [], "article_id": None,\n+ "source_published_at": "2026-07-27T00:00:00+08:00"}\n+_marks_mil = _b.brief_item_view(_mil_item, "zh", set())["marks"]\n+check("briefing item view renders taiwan+military marks",\n+ "⚔" in _marks_mil and "\U0001f1f9\U0001f1fc" in _marks_mil\n+ and "⚠" not in _marks_mil)\n+_fatal_item = dict(_mil_item, severity="fatal", taiwan_priority=False,\n+ military=False)\n+_marks_fatal = _b.brief_item_view(_fatal_item, "zh", set())["marks"]\n+check("fatal items render warning+red marks",\n+ "⚠" in _marks_fatal and "\U0001f534" in _marks_fatal)\n+\n # ── caps ─────────────────────────────────────────────────────────────────────\n \n reset()