Skip to content

Commit 63ca729

Browse files
authored
Merge pull request #2530 from Hack23/copilot/improve-news-titles-and-descriptions
Harden analysis-gate + renderer against BLUF-leak and duplicate-card title regressions
2 parents 7be28fd + e2f1ac4 commit 63ca729

2,415 files changed

Lines changed: 28919 additions & 26368 deletions

File tree

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

.github/prompts/05-analysis-gate.md

Lines changed: 66 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -206,6 +206,72 @@ if [ -s "$ANALYSIS_DIR/executive-brief.md" ]; then
206206
echo "❌ executive-brief.md: H1 is bare boilerplate ('Executive Brief') — write a publishable story-oriented title (actor + active verb + instrument or number)"
207207
FAIL=1
208208
fi
209+
# Date-in-H1 guard (seo-metadata-contract.md §2.1) — title must not
210+
# contain a literal publication date. Catches ISO YYYY-MM-DD,
211+
# English day-first ("15 May 2026") + US-order ("May 15, 2026") +
212+
# Swedish long-form months. Mirrors scripts/agentic/analysis-gate.ts
213+
# checkExecutiveBrief — keep regex parity TS ↔ bash.
214+
EB_H1_TEXT="$(printf '%s' "$EB_H1" \
215+
| sed -E 's/^#[[:space:]]+//' \
216+
| sed -E 's/<[^>]+>//g')"
217+
if printf '%s' "$EB_H1_TEXT" | grep -qE '[0-9]{4}[-/][0-9]{1,2}[-/][0-9]{1,2}'; then
218+
echo "❌ executive-brief.md: H1 contains a literal ISO date (YYYY-MM-DD) — dates belong in article:published_time, not the SERP <title>"
219+
FAIL=1
220+
elif printf '%s' "$EB_H1_LOWER" | grep -qE '[0-9]{1,2}[[:space:]]+(january|february|march|april|may|june|july|august|september|october|november|december)[[:space:]]+[0-9]{4}'; then
221+
echo "❌ executive-brief.md: H1 contains a literal English long-form date — dates belong in article:published_time, not the SERP <title>"
222+
FAIL=1
223+
elif printf '%s' "$EB_H1_LOWER" | grep -qE '(january|february|march|april|may|june|july|august|september|october|november|december)[[:space:]]+[0-9]{1,2}(,[[:space:]]*[0-9]{4})?'; then
224+
echo "❌ executive-brief.md: H1 contains a literal English long-form date (US order: 'May 15, 2026') — dates belong in article:published_time, not the SERP <title>"
225+
FAIL=1
226+
elif printf '%s' "$EB_H1_LOWER" | grep -qE '[0-9]{1,2}[[:space:]]+(januari|februari|mars|april|maj|juni|juli|augusti|september|oktober|november|december)[[:space:]]+[0-9]{4}'; then
227+
echo "❌ executive-brief.md: H1 contains a literal Swedish long-form date — dates belong in article:published_time, not the SERP <title>"
228+
FAIL=1
229+
fi
230+
# Trailing-punctuation / dangling-connector guard — H1 must be a
231+
# complete grammatical phrase. Catches `Sweden Evening Analysis,`,
232+
# `Week Ahead: Aid Accountability,`, `… opposition for`, etc.
233+
EB_H1_TRIM="$(printf '%s' "$EB_H1_TEXT" | sed -E 's/[[:space:]]+$//')"
234+
case "$EB_H1_TRIM" in
235+
*,|*\;|*:|*—|*–|*-)
236+
echo "❌ executive-brief.md: H1 ends with dangling punctuation (',' / ';' / ':' / '—' / '–' / '-') — complete the headline or remove the trailing marker"
237+
FAIL=1 ;;
238+
esac
239+
EB_H1_TRIM_LOWER="$(printf '%s' "$EB_H1_TRIM" | tr '[:upper:]' '[:lower:]')"
240+
if printf '%s' "$EB_H1_TRIM_LOWER" | grep -qE '[[:space:]](and|or|but|with|as|for|to|in|of|on|at|by|the|a|an|from|that)$'; then
241+
echo "❌ executive-brief.md: H1 ends with a coordinating connector or article ('and', 'or', 'with', 'the', …) — complete the headline"
242+
FAIL=1
243+
fi
244+
# Across-days uniqueness check (Phase 2 — period-aggregation duplicate-card
245+
# guard). The full normalised comparison lives in
246+
# scripts/agentic/analysis-gate.ts checkExecutiveBrief; this bash
247+
# check is a fast pre-flight that compares the raw H1 line against
248+
# the prior 7 sibling daily folders for the same subfolder.
249+
EB_DAILY_DIR="$(dirname "$ANALYSIS_DIR")"
250+
EB_DAILY_ROOT="$(dirname "$EB_DAILY_DIR")"
251+
EB_CURR_DATE="$(basename "$EB_DAILY_DIR")"
252+
EB_SUBFOLDER="$(basename "$ANALYSIS_DIR")"
253+
if printf '%s' "$EB_CURR_DATE" | grep -qE '^[0-9]{4}-[0-9]{2}-[0-9]{2}$' && [ -d "$EB_DAILY_ROOT" ]; then
254+
EB_CURR_NORM="$(printf '%s' "$EB_H1_TRIM_LOWER" | sed -E 's/[0-9]{4}-[0-9]{2}-[0-9]{2}//g' | tr -s '[:space:][:punct:]' ' ' | sed -E 's/^[[:space:]]+|[[:space:]]+$//g')"
255+
if [ "${#EB_CURR_NORM}" -ge 10 ]; then
256+
for EB_SIBLING in $(ls -1 "$EB_DAILY_ROOT" 2>/dev/null | grep -E '^[0-9]{4}-[0-9]{2}-[0-9]{2}$' | awk -v c="$EB_CURR_DATE" '$0 < c' | sort | tail -7); do
257+
EB_SIB_BRIEF="$EB_DAILY_ROOT/$EB_SIBLING/$EB_SUBFOLDER/executive-brief.md"
258+
[ -s "$EB_SIB_BRIEF" ] || continue
259+
EB_SIB_H1="$(grep -E '^#[[:space:]]+' "$EB_SIB_BRIEF" | head -n1 | sed -E 's/^#[[:space:]]+//' | sed -E 's/<[^>]+>//g')"
260+
[ -n "$EB_SIB_H1" ] || continue
261+
EB_SIB_NORM="$(printf '%s' "$EB_SIB_H1" | tr '[:upper:]' '[:lower:]' | sed -E 's/[0-9]{4}-[0-9]{2}-[0-9]{2}//g' | tr -s '[:space:][:punct:]' ' ' | sed -E 's/^[[:space:]]+|[[:space:]]+$//g')"
262+
if [ "$EB_SIB_NORM" = "$EB_CURR_NORM" ]; then
263+
echo "❌ executive-brief.md: H1 is normalised-identical (case/punctuation/date stripped) to analysis/daily/$EB_SIBLING/$EB_SUBFOLDER/executive-brief.md — reword to surface the day-specific angle (period-aggregation briefs must not ship duplicate cards on the news index)"
264+
FAIL=1
265+
break
266+
fi
267+
done
268+
fi
269+
fi
270+
else
271+
# No H1 at all — the renderer has nothing to seed the SERP <title>
272+
# from and will silently fall back to a BLUF-sentence fragment.
273+
echo "❌ executive-brief.md: no '# H1' heading found — the H1 is the SERP <title> source across all 14 languages; add a publishable story-oriented title"
274+
FAIL=1
209275
fi
210276
fi
211277
if [ -s "$ANALYSIS_DIR/intelligence-assessment.md" ]; then

news/2026-04-17-realtime-1434-ar.html

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -68,11 +68,11 @@
6868
<meta property="og:image:width" content="1200">
6969
<meta property="og:image:height" content="630">
7070
<meta property="og:image:alt" content="Riksdagsmonitor Sweden&#039;s Konstitutionsutskottet advanced two grundlag amendments">
71-
<meta property="og:updated_time" content="2026-05-16T14:12:39.040Z">
71+
<meta property="og:updated_time" content="2026-05-16T19:31:08.685Z">
7272

7373
<meta property="article:publisher" content="https://www.hack23.com">
7474
<meta property="article:section" content="Political Intelligence">
75-
<meta property="article:modified_time" content="2026-05-16T14:12:39.040Z">
75+
<meta property="article:modified_time" content="2026-05-16T19:31:08.685Z">
7676
<meta property="article:published_time" content="2026-04-17T00:00:00Z">
7777

7878
<meta name="twitter:card" content="summary_large_image">
@@ -88,7 +88,7 @@
8888
<link rel="icon" href="/favicon.ico" sizes="48x48">
8989
<link rel="manifest" href="/site.webmanifest">
9090

91-
<script type="application/ld+json">{"@context":"https://schema.org","@type":"NewsArticle","headline":"Sweden's Konstitutionsutskottet advanced two grundlag amendments","description":"Sweden's Konstitutionsutskottet advanced two grundlag amendments (HD01KU32 + HD01KU33) on 2026-04-17 — the first substantive narrowing of Tryckfrihetsförordningen (1766) in the digital-evidence…","datePublished":"2026-04-17T00:00:00Z","dateModified":"2026-05-16T14:12:39.040Z","inLanguage":"ar","url":"https://riksdagsmonitor.com/news/2026-04-17-realtime-1434-ar.html","mainEntityOfPage":"https://riksdagsmonitor.com/news/2026-04-17-realtime-1434-ar.html","author":{"@type":"Organization","name":"Riksdagsmonitor (Hack23 AB)","url":"https://www.hack23.com"},"publisher":{"@type":"Organization","name":"Hack23 AB","url":"https://www.hack23.com","logo":{"@type":"ImageObject","url":"https://riksdagsmonitor.com/images/logo.png"}},"isAccessibleForFree":true,"isPartOf":{"@type":"WebSite","@id":"https://riksdagsmonitor.com/#website","name":"Riksdagsmonitor","url":"https://riksdagsmonitor.com"},"isBasedOn":[{"@type":"CreativeWork","url":"https://github.com/Hack23/riksdagsmonitor/blob/main/analysis/daily/2026-04-17/realtime-1434/classification-results.md","name":"classification-results.md"},{"@type":"CreativeWork","url":"https://github.com/Hack23/riksdagsmonitor/blob/main/analysis/daily/2026-04-17/realtime-1434/comparative-international.md","name":"comparative-international.md"},{"@type":"CreativeWork","url":"https://github.com/Hack23/riksdagsmonitor/blob/main/analysis/daily/2026-04-17/realtime-1434/cross-reference-map.md","name":"cross-reference-map.md"},{"@type":"CreativeWork","url":"https://github.com/Hack23/riksdagsmonitor/blob/main/analysis/daily/2026-04-17/realtime-1434/data-download-manifest.md","name":"data-download-manifest.md"},{"@type":"CreativeWork","url":"https://github.com/Hack23/riksdagsmonitor/blob/main/analysis/daily/2026-04-17/realtime-1434/documents/HD01CU27-CU28-analysis.md","name":"documents/HD01CU27-CU28-analysis.md"},{"@type":"CreativeWork","url":"https://github.com/Hack23/riksdagsmonitor/blob/main/analysis/daily/2026-04-17/realtime-1434/documents/HD01KU32-KU33-analysis.md","name":"documents/HD01KU32-KU33-analysis.md"},{"@type":"CreativeWork","url":"https://github.com/Hack23/riksdagsmonitor/blob/main/analysis/daily/2026-04-17/realtime-1434/documents/HD03231-analysis.md","name":"documents/HD03231-analysis.md"},{"@type":"CreativeWork","url":"https://github.com/Hack23/riksdagsmonitor/blob/main/analysis/daily/2026-04-17/realtime-1434/documents/HD03232-analysis.md","name":"documents/HD03232-analysis.md"},{"@type":"CreativeWork","url":"https://github.com/Hack23/riksdagsmonitor/blob/main/analysis/daily/2026-04-17/realtime-1434/economic-data.json","name":"economic-data.json"},{"@type":"CreativeWork","url":"https://github.com/Hack23/riksdagsmonitor/blob/main/analysis/daily/2026-04-17/realtime-1434/executive-brief.md","name":"executive-brief.md"},{"@type":"CreativeWork","url":"https://github.com/Hack23/riksdagsmonitor/blob/main/analysis/daily/2026-04-17/realtime-1434/methodology-reflection.md","name":"methodology-reflection.md"},{"@type":"CreativeWork","url":"https://github.com/Hack23/riksdagsmonitor/blob/main/analysis/daily/2026-04-17/realtime-1434/README.md","name":"README.md"},{"@type":"CreativeWork","url":"https://github.com/Hack23/riksdagsmonitor/blob/main/analysis/daily/2026-04-17/realtime-1434/risk-assessment.md","name":"risk-assessment.md"},{"@type":"CreativeWork","url":"https://github.com/Hack23/riksdagsmonitor/blob/main/analysis/daily/2026-04-17/realtime-1434/scenario-analysis.md","name":"scenario-analysis.md"},{"@type":"CreativeWork","url":"https://github.com/Hack23/riksdagsmonitor/blob/main/analysis/daily/2026-04-17/realtime-1434/significance-scoring.md","name":"significance-scoring.md"},{"@type":"CreativeWork","url":"https://github.com/Hack23/riksdagsmonitor/blob/main/analysis/daily/2026-04-17/realtime-1434/stakeholder-perspectives.md","name":"stakeholder-perspectives.md"},{"@type":"CreativeWork","url":"https://github.com/Hack23/riksdagsmonitor/blob/main/analysis/daily/2026-04-17/realtime-1434/swot-analysis.md","name":"swot-analysis.md"},{"@type":"CreativeWork","url":"https://github.com/Hack23/riksdagsmonitor/blob/main/analysis/daily/2026-04-17/realtime-1434/synthesis-summary.md","name":"synthesis-summary.md"},{"@type":"CreativeWork","url":"https://github.com/Hack23/riksdagsmonitor/blob/main/analysis/daily/2026-04-17/realtime-1434/threat-analysis.md","name":"threat-analysis.md"}]}</script>
91+
<script type="application/ld+json">{"@context":"https://schema.org","@type":"NewsArticle","headline":"Sweden's Konstitutionsutskottet advanced two grundlag amendments","description":"Sweden's Konstitutionsutskottet advanced two grundlag amendments (HD01KU32 + HD01KU33) on 2026-04-17 — the first substantive narrowing of Tryckfrihetsförordningen (1766) in the digital-evidence…","datePublished":"2026-04-17T00:00:00Z","dateModified":"2026-05-16T19:31:08.685Z","inLanguage":"ar","url":"https://riksdagsmonitor.com/news/2026-04-17-realtime-1434-ar.html","mainEntityOfPage":"https://riksdagsmonitor.com/news/2026-04-17-realtime-1434-ar.html","author":{"@type":"Organization","name":"Riksdagsmonitor (Hack23 AB)","url":"https://www.hack23.com"},"publisher":{"@type":"Organization","name":"Hack23 AB","url":"https://www.hack23.com","logo":{"@type":"ImageObject","url":"https://riksdagsmonitor.com/images/logo.png"}},"isAccessibleForFree":true,"isPartOf":{"@type":"WebSite","@id":"https://riksdagsmonitor.com/#website","name":"Riksdagsmonitor","url":"https://riksdagsmonitor.com"},"isBasedOn":[{"@type":"CreativeWork","url":"https://github.com/Hack23/riksdagsmonitor/blob/main/analysis/daily/2026-04-17/realtime-1434/classification-results.md","name":"classification-results.md"},{"@type":"CreativeWork","url":"https://github.com/Hack23/riksdagsmonitor/blob/main/analysis/daily/2026-04-17/realtime-1434/comparative-international.md","name":"comparative-international.md"},{"@type":"CreativeWork","url":"https://github.com/Hack23/riksdagsmonitor/blob/main/analysis/daily/2026-04-17/realtime-1434/cross-reference-map.md","name":"cross-reference-map.md"},{"@type":"CreativeWork","url":"https://github.com/Hack23/riksdagsmonitor/blob/main/analysis/daily/2026-04-17/realtime-1434/data-download-manifest.md","name":"data-download-manifest.md"},{"@type":"CreativeWork","url":"https://github.com/Hack23/riksdagsmonitor/blob/main/analysis/daily/2026-04-17/realtime-1434/documents/HD01CU27-CU28-analysis.md","name":"documents/HD01CU27-CU28-analysis.md"},{"@type":"CreativeWork","url":"https://github.com/Hack23/riksdagsmonitor/blob/main/analysis/daily/2026-04-17/realtime-1434/documents/HD01KU32-KU33-analysis.md","name":"documents/HD01KU32-KU33-analysis.md"},{"@type":"CreativeWork","url":"https://github.com/Hack23/riksdagsmonitor/blob/main/analysis/daily/2026-04-17/realtime-1434/documents/HD03231-analysis.md","name":"documents/HD03231-analysis.md"},{"@type":"CreativeWork","url":"https://github.com/Hack23/riksdagsmonitor/blob/main/analysis/daily/2026-04-17/realtime-1434/documents/HD03232-analysis.md","name":"documents/HD03232-analysis.md"},{"@type":"CreativeWork","url":"https://github.com/Hack23/riksdagsmonitor/blob/main/analysis/daily/2026-04-17/realtime-1434/economic-data.json","name":"economic-data.json"},{"@type":"CreativeWork","url":"https://github.com/Hack23/riksdagsmonitor/blob/main/analysis/daily/2026-04-17/realtime-1434/executive-brief.md","name":"executive-brief.md"},{"@type":"CreativeWork","url":"https://github.com/Hack23/riksdagsmonitor/blob/main/analysis/daily/2026-04-17/realtime-1434/methodology-reflection.md","name":"methodology-reflection.md"},{"@type":"CreativeWork","url":"https://github.com/Hack23/riksdagsmonitor/blob/main/analysis/daily/2026-04-17/realtime-1434/README.md","name":"README.md"},{"@type":"CreativeWork","url":"https://github.com/Hack23/riksdagsmonitor/blob/main/analysis/daily/2026-04-17/realtime-1434/risk-assessment.md","name":"risk-assessment.md"},{"@type":"CreativeWork","url":"https://github.com/Hack23/riksdagsmonitor/blob/main/analysis/daily/2026-04-17/realtime-1434/scenario-analysis.md","name":"scenario-analysis.md"},{"@type":"CreativeWork","url":"https://github.com/Hack23/riksdagsmonitor/blob/main/analysis/daily/2026-04-17/realtime-1434/significance-scoring.md","name":"significance-scoring.md"},{"@type":"CreativeWork","url":"https://github.com/Hack23/riksdagsmonitor/blob/main/analysis/daily/2026-04-17/realtime-1434/stakeholder-perspectives.md","name":"stakeholder-perspectives.md"},{"@type":"CreativeWork","url":"https://github.com/Hack23/riksdagsmonitor/blob/main/analysis/daily/2026-04-17/realtime-1434/swot-analysis.md","name":"swot-analysis.md"},{"@type":"CreativeWork","url":"https://github.com/Hack23/riksdagsmonitor/blob/main/analysis/daily/2026-04-17/realtime-1434/synthesis-summary.md","name":"synthesis-summary.md"},{"@type":"CreativeWork","url":"https://github.com/Hack23/riksdagsmonitor/blob/main/analysis/daily/2026-04-17/realtime-1434/threat-analysis.md","name":"threat-analysis.md"}]}</script>
9292
<script type="application/ld+json">{"@context":"https://schema.org","@type":"BreadcrumbList","itemListElement":[{"@type":"ListItem","position":1,"name":"الرئيسية","item":"https://riksdagsmonitor.com/"},{"@type":"ListItem","position":2,"name":"الأخبار والتحليل","item":"https://riksdagsmonitor.com/news/"},{"@type":"ListItem","position":3,"name":"Sweden's Konstitutionsutskottet advanced two gr…"}]}</script>
9393
<script type="application/ld+json">{"@context":"https://schema.org","@type":"WebPage","url":"https://riksdagsmonitor.com/news/2026-04-17-realtime-1434-ar.html","inLanguage":"ar","speakable":{"@type":"SpeakableSpecification","cssSelector":[".rm-article-header h1",".rm-article-dek",".rm-article-body"]},"isPartOf":{"@type":"WebSite","@id":"https://riksdagsmonitor.com/#website"}}</script>
9494

@@ -8848,7 +8848,7 @@ <h2 id="rm-ft-about" class="rm-footer-heading">Riksdagsmonitor</h2>
88488848
· بُني بواسطة
88498849
<a href="https://www.hack23.com" target="_blank" rel="noopener noreferrer">Hack23 AB</a>
88508850
</p>
8851-
<p class="rm-footer-updated"><small>آخر تحديث: <time datetime="2026-05-16T14:12:39.040Z">2026-05-16 14:12 UTC</time></small></p>
8851+
<p class="rm-footer-updated"><small>آخر تحديث: <time datetime="2026-05-16T19:31:08.685Z">2026-05-16 19:31 UTC</time></small></p>
88528852
</section>
88538853
<section class="rm-footer-col rm-footer-navigate" aria-labelledby="rm-ft-nav">
88548854
<h2 id="rm-ft-nav" class="rm-footer-heading">روابط سريعة</h2>

0 commit comments

Comments
 (0)