feat(feeds): add IRNA, Mehr, Jerusalem Post, Ynetnews to middleeast (#3236)

* feat(feeds): add IRNA, Mehr, Jerusalem Post, Ynetnews to middleeast

Four direct-RSS sources verified from a clean IP and absent everywhere
in the repo (src/config/feeds.ts, scripts/seed-*, ais-relay.cjs, RSS
allowlist). Closes the highest-ROI Iran / Israel domestic-press gap
from the ME source audit (PR #3226) with zero infra changes.

- IRNA        https://en.irna.ir/rss
- Mehr News   https://en.mehrnews.com/rss
- Jerusalem Post https://www.jpost.com/rss/rssfeedsheadlines.aspx
- Ynetnews    https://www.ynetnews.com/Integration/StoryRss3089.xml

Propaganda-risk metadata:
- IRNA + Mehr tagged high / Iran state-affiliated (join Press TV).
- JPost + Ynetnews tagged low with knownBiases for transparency.

RSS allowlist updated in all three mirrors (shared/, scripts/shared/,
api/_rss-allowed-domains.js) per the byte-identical mirror contract
enforced by tests/edge-functions.test.mjs.

Deferred (separate PRs):
- Times of Israel: already in allowlist; was removed from feeds for
  cloud-IP 403. Needs Decodo routing.
- IDF Spokesperson: idf.il has no direct RSS endpoint; needs scraper.
- Tasnim / Press TV RSS / Israel Hayom: known cloud-IP blocks.
- WAM / SPA / KUNA / QNA / BNA: public RSS endpoints are dead; sites
  migrated to SPAs or gate with 403.

Plan doc (PR #3226) overstated the gap: it audited only feeds.ts and
missed that travel advisories + US Embassy alerts are already covered
by scripts/seed-security-advisories.mjs. NOTAM claim in that doc is
also wrong: we use ICAO's global NOTAM API, not FAA.

* fix(feeds): enable IRNA, Mehr, Jerusalem Post, Ynetnews by default

Reviewer on #3236 flagged that adding the four new ME feeds to
FULL_FEEDS.middleeast alone leaves them disabled on first run, because
App.ts:661 persists computeDefaultDisabledSources() output derived from
DEFAULT_ENABLED_SOURCES. Users would have to manually re-enable via
Settings > Sources, defeating the purpose of broadening the default
ME mix.

Add the four new sources to DEFAULT_ENABLED_SOURCES.middleeast so they
ship on by default. Placement keeps them adjacent to their peers
(IRNA / Mehr with the other Iran sources, JPost / Ynetnews after
Haaretz). Risk/slant tags already in SOURCE_PROPAGANDA_RISK ensure
downstream digest dedup + summarization weights them correctly.

* style(feeds): move JPost + Ynetnews under Low-risk section header

Greptile on #3236 flagged that both entries are risk: 'low' but were
inserted above the `// Low risk - Independent with editorial standards`
comment header, making the section boundary misleading for future
contributors. Shift them under the header where they belong.

No runtime change; cosmetic ordering only.
This commit is contained in:
Elie Habib
2026-04-20 19:07:09 +04:00
committed by GitHub
parent 661bbe8f09
commit ecd56d4212
4 changed files with 21 additions and 1 deletions

View File

@@ -113,6 +113,10 @@ export default [
"www.omanobserver.om",
"english.alarabiya.net",
"www.timesofisrael.com",
"www.jpost.com",
"www.ynetnews.com",
"en.irna.ir",
"en.mehrnews.com",
"www.haaretz.com",
"www.scmp.com",
"kyivindependent.com",

View File

@@ -110,6 +110,10 @@
"www.omanobserver.om",
"english.alarabiya.net",
"www.timesofisrael.com",
"www.jpost.com",
"www.ynetnews.com",
"en.irna.ir",
"en.mehrnews.com",
"www.haaretz.com",
"www.scmp.com",
"kyivindependent.com",

View File

@@ -110,6 +110,10 @@
"www.omanobserver.om",
"english.alarabiya.net",
"www.timesofisrael.com",
"www.jpost.com",
"www.ynetnews.com",
"en.irna.ir",
"en.mehrnews.com",
"www.haaretz.com",
"www.scmp.com",
"kyivindependent.com",

View File

@@ -118,6 +118,8 @@ export const SOURCE_PROPAGANDA_RISK: Record<string, SourceRiskProfile> = {
'Sputnik': { risk: 'high', stateAffiliated: 'Russia', note: 'Russian state media' },
'CGTN': { risk: 'high', stateAffiliated: 'China', note: 'Chinese state broadcaster' },
'Press TV': { risk: 'high', stateAffiliated: 'Iran', note: 'Iranian state media' },
'IRNA': { risk: 'high', stateAffiliated: 'Iran', note: 'Iranian state news agency (Islamic Republic News Agency)' },
'Mehr News': { risk: 'high', stateAffiliated: 'Iran', note: 'Iranian state-affiliated, Basij-linked' },
'KCNA': { risk: 'high', stateAffiliated: 'North Korea', note: 'North Korean state media' },
// Medium risk - State-affiliated or known bias
@@ -133,6 +135,8 @@ export const SOURCE_PROPAGANDA_RISK: Record<string, SourceRiskProfile> = {
'Moscow Times': { risk: 'medium', knownBiases: ['Anti-Kremlin'], note: 'Independent, critical of Russian government' },
// Low risk - Independent with editorial standards (explicit)
'Jerusalem Post': { risk: 'low', knownBiases: ['Israeli centre-right'], note: 'English-language Israeli daily of record' },
'Ynetnews': { risk: 'low', knownBiases: ['Israeli mainstream'], note: 'Yedioth Ahronoth English edition' },
'Reuters': { risk: 'low', note: 'Wire service, strict editorial standards' },
'AP News': { risk: 'low', note: 'Wire service, nonprofit cooperative' },
'AFP': { risk: 'low', note: 'Wire service, editorially independent' },
@@ -272,7 +276,11 @@ const FULL_FEEDS: Record<string, Feed[]> = {
{ name: 'BBC Persian', url: rss('http://feeds.bbci.co.uk/persian/tv-and-radio-37434376/rss.xml') },
{ name: 'Iran International', url: rss('https://news.google.com/rss/search?q=site:iranintl.com+when:2d&hl=en-US&gl=US&ceid=US:en') },
{ name: 'Fars News', url: rss('https://news.google.com/rss/search?q=site:farsnews.ir+when:2d&hl=en-US&gl=US&ceid=US:en') },
{ name: 'IRNA', url: rss('https://en.irna.ir/rss') },
{ name: 'Mehr News', url: rss('https://en.mehrnews.com/rss') },
{ name: 'Haaretz', url: rss('https://news.google.com/rss/search?q=site:haaretz.com+when:7d&hl=en-US&gl=US&ceid=US:en') },
{ name: 'Jerusalem Post', url: rss('https://www.jpost.com/rss/rssfeedsheadlines.aspx') },
{ name: 'Ynetnews', url: rss('https://www.ynetnews.com/Integration/StoryRss3089.xml') },
{ name: 'Arab News', url: rss('https://news.google.com/rss/search?q=site:arabnews.com+when:7d&hl=en-US&gl=US&ceid=US:en') },
{ name: 'The National', url: rss('https://news.google.com/rss/search?q=site:thenationalnews.com+when:2d&hl=en-US&gl=US&ceid=US:en') },
{ name: 'Oman Observer', url: rss('https://www.omanobserver.om/rssFeed/1') },
@@ -981,7 +989,7 @@ export const DEFAULT_ENABLED_SOURCES: Record<string, string[]> = {
politics: ['BBC World', 'Guardian World', 'AP News', 'Reuters World', 'CNN World'],
us: ['Reuters US', 'NPR News', 'PBS NewsHour', 'ABC News', 'CBS News', 'NBC News', 'Wall Street Journal', 'Politico', 'The Hill'],
europe: ['France 24', 'EuroNews', 'Le Monde', 'DW News', 'Tagesschau', 'ANSA', 'NOS Nieuws', 'SVT Nyheter'],
middleeast: ['BBC Middle East', 'Al Jazeera', 'Al Arabiya', 'Guardian ME', 'BBC Persian', 'Iran International', 'Haaretz', 'Asharq News', 'The National'],
middleeast: ['BBC Middle East', 'Al Jazeera', 'Al Arabiya', 'Guardian ME', 'BBC Persian', 'Iran International', 'IRNA', 'Mehr News', 'Haaretz', 'Jerusalem Post', 'Ynetnews', 'Asharq News', 'The National'],
africa: ['BBC Africa', 'News24', 'Africanews', 'Jeune Afrique', 'Africa News', 'Premium Times', 'Channels TV', 'Sahel Crisis'],
latam: ['BBC Latin America', 'Reuters LatAm', 'InSight Crime', 'Mexico News Daily', 'Clarín', 'Primicias', 'Infobae Americas', 'El Universo'],
asia: ['BBC Asia', 'The Diplomat', 'South China Morning Post', 'Reuters Asia', 'Nikkei Asia', 'CNA', 'Asia News', 'The Hindu'],