131 promisiuni de campanie urmărite în discursul de mandat
131 promisiuni de campanie urmărite prin clasificator LLM + fact-check manual individual. Rezultat: 46% ținute în realitate vs 20% raportate de clasificator.
Cum a fost făcută analiza
Extras din 319 discursuri de campanie (≤ 25 mai 2025) toate angajamentele explicite la acțiune viitoare specifică, cu Gemini 2.5 Flash
Verificare clasificator în corpusul de mandat (≥ 26 mai 2025, ~540 docs): pentru fiecare promisiune, top-8 paragrafe relevante + clasificare LLM
Audit dublu clasificator pe 32 sample-uri (75% spot-on)
Audit random pe 15 promisiuni (seed=42) — confirmă pattern systematic: 4/4 NO_MENTION sunt KEPT real
Fact-check manual individual pe toate 131 promisiuni — verdict + raționament + surse media pentru fiecare, salvate în manual_factcheck_status
Distribuția globală de mai jos folosește fact-check-ul real (pasul 6), nu clasificarea LLM.
Distribuția globală (fact-check pe toate 131)
Aceasta este distribuția reală (fact-check pe fiecare promisiune individual), nu cea raportată de clasificatorul ND-centric. Pentru comparație cu distribuția clasificatorului, vezi tabelul de mai jos.
Layer de fact-check manual pe TOATE 131 promisiuni
Clasificatorul ND-centric vede doar ce anunță ND. Pentru a măsura realitatea, am făcut fact-check individual (verdict + raționament + surse media) pentru fiecare din cele 131 promisiuni — bazat pe web search + cunoștințe acumulate.
Comparație clasificator vs fact-check real (toate 131)
Verdict
Classifier
Fact-check real
Δ
✅ KEPT (ținută)
20%
46%
↑2.3×
🔄 IN_PROGRESS
59%
38%
↓
❓ NO_MENTION
21%
8%
↓2.6×
⚠️ CONTRADICTED
0.8%
2%
↑
🔀 REFRAMED
—
1%
nou
ⓘ UNVERIFIABLE
—
5%
promisiuni prea vagi
Pattern confirmat empiric pe întregul corpus
Clasificatorul subestimează KEPT cu factor 2.3× (46% real vs 20% raportat)
Clasificatorul supra-marchează NO_MENTION cu factor 2.6× (8% real vs 21% raportat)
Multe promisiuni clasificate NO_MENTION/IN_PROGRESS sunt de fapt KEPT executate prin acțiuni concrete (decrete, contracte, numiri, evenimente)
Metodă
Pentru fiecare promisiune individual: 1. Citit textul + clasificarea LLM 2. Web search pe topic + cunoștințe acumulate (fact-check anterior + audit dublu + audit random) 3. Verdict + sursă/raționament 1-2 propoziții
Toate verdictele individuale (cu raționament + surse) sunt în scripts/04g_full_factcheck.py — script transparent, reproducible. Câmpurile nou adăugate în promise_status.jsonl: manual_factcheck_status, factcheck_confidence, factcheck_reasoning, factcheck_sources.
Audit random anterior (15 promisiuni, seed=42)
A confirmat pattern-ul independent: 100% NO_MENTION clasificator sample (4/4) erau de fapt KEPT real. Vezi AUDIT_RANDOM_15.md.
Pe domenii (cele mai relevante)
Rata reală KEPT pe domeniu — clasificator vs fact-check
Observații concrete pe domenii:
Diplomație: 100% KEPT real (vs 60% classifier) — toate 10 promisiunile diplomatice confirmate executate
Anti-corupție: 67% real (vs 0% classifier) — numiri DNA/DIICOT
Diaspora: 100% real (vs 0% classifier) — consilieri prezidențiali pentru diaspora numiți
București/local: 44% real (vs 4% classifier) — proiecte PMB executate sub Bujduveanu/Ciucu
Sănătate / Educație: 0% KEPT atât classifier cât și real — domenii unde livrarea concretă este realmente limitată
Cum s-au calculat aceste cifre
Bar chart de mai sus folosește date computate direct din promise_status.jsonl (câmpurile status_status pentru clasificator, manual_factcheck_status pentru fact-check). Recalculate la fiecare render — sincronizate cu datele.
ND execută concret pe aceste domenii — dar nu vorbește despre realizările sale post-execuție.
Caz emblematic — “Dau în scris că TVA nu va crește”
Pe 14 mai 2025, cu 4 zile înainte de turul 2, în campanie, Nicușor Dan a făcut o promisiune memorabilă, ferm exprimată — fixată în titlul publicării video oficiale:
«Da, dau în scris.»
“Satul român trebuie să fie suficient de ferm pentru a încasa taxele care i se cuvin la cuantumul care sunt azi… TVA de 19%, […] putem să redresăm. Da, dau în scris.”
— Nicușor Dan, video oficial 14 mai 2025, titlu video: “Nicușor Dan: Dau în scris că TVA nu va crește”
6 săptămâni mai târziu — TVA crescut.
⚠️ Limitare metodologică detectată
Această promisiune NU apare în top 131 promisiuni canonice clasificate de pipeline. Extractorul LLM a căutat formulări de tip “Voi face X” și a ratat formularea negativă “X nu se va întâmpla”. Promisiunea e bine documentată media (titlul video oficial) și e prima pe rezultate Google pentru “Nicușor Dan TVA promisiune”.
Asta e un blind spot al Promise Tracker-ului — formularea în negativ scapă extracției. Adăugată manual ca CONTRADICTED.
Cronologia reală (fact-check media)
Data
Eveniment
Sursă
14 mai 2025
ND, în campanie: “Dau în scris că TVA nu va crește”
Realitate (după 6 săptămâni): TVA general 19% → 21%, TVA reduse aproape dublate (5% → 11%, 9% → 11-21%)
ND a pierdut negocierea internă cu Bolojan — premierul a pus condiția majorării
ND a comentat ulterior: măsura “putea să nu fie luată”
Cazul demonstrează 3 lucruri:
ND nu domină mereu executivul — pe deciziile fiscale dure, Bolojan a impus poziția.
Promisiunea de campanie a fost încălcată direct — nu reframuită, ci contrazisă într-o lună de la învestire.
Pipeline-ul are blind spot — promisiuni formulate negativ (“X nu se va întâmpla”) scapă extractorului.
Caz secundar — “viceprimar = primar interimar”
Există și un alt caz interesant, dar mai nuanțat: promisiunea din 20 mai 2025 că Adrian Vigheciu (PSD) va fi primar interimar al Capitalei. ND a împins ulterior pentru Stelian Bujduveanu (PNL) — spiritul promisiunii (viceprimar = primar interimar) a fost respectat, persoana s-a schimbat conștient și anunțat. Asta e REFRAMED, nu CONTRADICTED. Vezi cronologia detaliată în results/04_promises/.
Toate cele 131 promisiuni — explorabil
Loading ITables v2.8.0 from the internet...
(need help?)
---title: "Promisiunile"subtitle: "131 promisiuni de campanie urmărite în discursul de mandat"description: "131 promisiuni de campanie urmărite prin clasificator LLM + fact-check manual individual. Rezultat: 46% ținute în realitate vs 20% raportate de clasificator."---```{python}#| include: falseimport sys, jsonfrom pathlib import PathROOT = Path("..").resolve()sys.path.insert(0, str(ROOT))import pandas as pdimport plotly.graph_objects as goimport plotly.express as pxdef load_promises(): rows = []with (ROOT /"results"/"04_promises"/"promise_status.jsonl").open() as f:for line in f: rows.append(json.loads(line))return pd.DataFrame(rows)promises = load_promises()```## Cum a fost făcută analiza1. **Extras** din 319 discursuri de campanie (≤ 25 mai 2025) toate angajamentele explicite la acțiune viitoare specifică, cu Gemini 2.5 Flash2. **Deduplicare** cu embedding cosinus (prag 0,85) → 150 → 131 promisiuni unice3. **Verificare clasificator** în corpusul de mandat (≥ 26 mai 2025, ~540 docs): pentru fiecare promisiune, top-8 paragrafe relevante + clasificare LLM4. **Audit dublu** clasificator pe 32 sample-uri (75% spot-on)5. **Audit random** pe 15 promisiuni (seed=42) — confirmă pattern systematic: 4/4 NO_MENTION sunt KEPT real6. **Fact-check manual individual pe toate 131 promisiuni** — verdict + raționament + surse media pentru fiecare, salvate în `manual_factcheck_status`Distribuția globală de mai jos folosește **fact-check-ul real** (pasul 6), nu clasificarea LLM.## Distribuția globală (fact-check pe toate 131)```{python}#| echo: falselabels_ro = {"KEPT_real": "Ținută","IN_PROGRESS_real": "În curs","NO_MENTION_real": "Nemenționată / fără acțiune vizibilă","CONTRADICTED_real": "Contrazisă","REFRAMED_real": "Redefinită","UNVERIFIABLE": "Prea vagă (neverificabilă)",# Original classifier labels (kept for backwards compatibility)"KEPT": "Ținută (clasificator)","IN_PROGRESS": "În curs (clasificator)","NO_MENTION": "Nemenționată (clasificator)","CONTRADICTED": "Contrazisă (clasificator)","REFRAMED": "Redefinită (clasificator)","ABANDONED": "Abandonată",}colors = {"KEPT_real": "#2a9d8f","IN_PROGRESS_real": "#f4a261","NO_MENTION_real": "#cccccc","CONTRADICTED_real": "#e63946","REFRAMED_real": "#9b5de5","UNVERIFIABLE": "#888888","KEPT": "#2a9d8f","IN_PROGRESS": "#f4a261","NO_MENTION": "#cccccc","CONTRADICTED": "#e63946","REFRAMED": "#9b5de5",}# Use fact-check distribution as primarycounts = promises["manual_factcheck_status"].value_counts()# Sort for consistent orderingorder = ["KEPT_real", "IN_PROGRESS_real", "NO_MENTION_real","CONTRADICTED_real", "REFRAMED_real", "UNVERIFIABLE"]counts = counts.reindex([k for k in order if k in counts.index])fig = go.Figure(go.Pie( labels=[labels_ro.get(s, s) for s in counts.index], values=counts.values, marker=dict(colors=[colors.get(s, "#888") for s in counts.index]), textinfo="label+percent+value", hole=0.4,))fig.update_layout( title="Status promisiuni — fact-check independent pe toate 131", height=500, annotations=[dict(text=f"{len(promises)}<br>total", x=0.5, y=0.5, font_size=18, showarrow=False)],)fig.show()```Aceasta este distribuția **reală** (fact-check pe fiecare promisiune individual), nu cea raportată de clasificatorul ND-centric. Pentru comparație cu distribuția clasificatorului, vezi tabelul de mai jos.::: {.callout-warning}## Layer de fact-check manual pe TOATE 131 promisiuniClasificatorul ND-centric vede doar ce **anunță** ND. Pentru a măsura realitatea, am făcut fact-check individual (verdict + raționament + surse media) pentru **fiecare din cele 131 promisiuni** — bazat pe web search + cunoștințe acumulate.### Comparație clasificator vs fact-check real (toate 131)| Verdict | Classifier | Fact-check real | Δ ||---|---:|---:|---:|| ✅ KEPT (ținută) | 20% | **46%** | **↑2.3×** || 🔄 IN_PROGRESS | 59% | 38% | ↓ || ❓ NO_MENTION | 21% | **8%** | **↓2.6×** || ⚠️ CONTRADICTED | 0.8% | 2% | ↑ || 🔀 REFRAMED | — | 1% | nou || ⓘ UNVERIFIABLE | — | 5% | promisiuni prea vagi |### Pattern confirmat empiric pe întregul corpus- **Clasificatorul subestimează KEPT cu factor 2.3×** (46% real vs 20% raportat)- **Clasificatorul supra-marchează NO_MENTION cu factor 2.6×** (8% real vs 21% raportat)- Multe promisiuni clasificate NO_MENTION/IN_PROGRESS sunt de fapt **KEPT executate** prin acțiuni concrete (decrete, contracte, numiri, evenimente)### MetodăPentru fiecare promisiune individual:1. Citit textul + clasificarea LLM2. Web search pe topic + cunoștințe acumulate (fact-check anterior + audit dublu + audit random)3. Verdict + sursă/raționament 1-2 propozițiiToate verdictele individuale (cu raționament + surse) sunt în [`scripts/04g_full_factcheck.py`](https://github.com/radusqrt/evolutie-discurs-nicusor-dan/blob/main/scripts/04g_full_factcheck.py) — script transparent, reproducible. Câmpurile nou adăugate în `promise_status.jsonl`: `manual_factcheck_status`, `factcheck_confidence`, `factcheck_reasoning`, `factcheck_sources`.::: {.callout-note}## Audit random anterior (15 promisiuni, seed=42)A confirmat pattern-ul independent: 100% NO_MENTION clasificator sample (4/4) erau de fapt KEPT real. Vezi [`AUDIT_RANDOM_15.md`](https://github.com/radusqrt/evolutie-discurs-nicusor-dan/blob/main/results/04_promises/AUDIT_RANDOM_15.md).::::::## Pe domenii (cele mai relevante)```{python}#| echo: falseper_topic = promises.groupby(["topic", "manual_factcheck_status"]).size().unstack(fill_value=0)per_topic["total"] = per_topic.sum(axis=1)per_topic["KEPT_pct"] = (per_topic.get("KEPT_real", 0) / per_topic["total"] *100).round(0)per_topic = per_topic.sort_values("total", ascending=False).head(10)fig = go.Figure()for status in ["KEPT_real", "IN_PROGRESS_real", "NO_MENTION_real","CONTRADICTED_real", "REFRAMED_real", "UNVERIFIABLE"]:if status in per_topic.columns: fig.add_bar( name=labels_ro.get(status, status), x=per_topic.index, y=per_topic[status], marker_color=colors.get(status, "#888"), )fig.update_layout( barmode="stack", title="Status promisiuni pe top 10 teme (fact-check pe 131)", yaxis_title="Număr promisiuni", xaxis_title="", height=500, plot_bgcolor="white", legend_title="",)fig.update_xaxes(tickangle=-30)fig.show()```## Rata reală KEPT pe domeniu — clasificator vs fact-check```{python}#| echo: false# Calculate real KEPT% and classifier KEPT% per topic from fact-check datatopic_stats = []for topic in promises["topic"].unique(): sub = promises[promises["topic"] == topic] total =len(sub)if total <3:continue kept_real = (sub["manual_factcheck_status"] =="KEPT_real").sum() kept_clf = (sub["status_status"] =="KEPT").sum() topic_stats.append({"topic": topic,"total": total,"kept_real_pct": round(100* kept_real / total),"kept_clf_pct": round(100* kept_clf / total), })# Sort by total desc, then take top 12topic_stats =sorted(topic_stats, key=lambda x: -x["total"])domains = [t["topic"] for t in topic_stats]real_vals = [t["kept_real_pct"] for t in topic_stats]clf_vals = [t["kept_clf_pct"] for t in topic_stats]fig = go.Figure()fig.add_bar(name="Clasificator LLM (discurs)", x=domains, y=clf_vals, marker_color="#cccccc", text=[f"{v}%"for v in clf_vals], textposition="outside")fig.add_bar(name="Fact-check real (verificat)", x=domains, y=real_vals, marker_color="#2a9d8f", text=[f"{v}%"for v in real_vals], textposition="outside")fig.update_layout( barmode="group", title="Rata KEPT pe domeniu: clasificator vs realitate fact-checked", yaxis_title="% promisiuni ținute", yaxis_range=[0, 110], height=500, plot_bgcolor="white", legend=dict(yanchor="top", y=0.99, xanchor="left", x=0.01),)fig.update_xaxes(tickangle=-30)fig.show()```**Observații concrete pe domenii**:- **Diplomație**: 100% KEPT real (vs 60% classifier) — toate 10 promisiunile diplomatice confirmate executate- **NATO/apărare**: 86% KEPT real (vs 29% classifier) — acțiuni concrete (B9 summit, 5% PIB angajament)- **Justiție electorală**: 82% KEPT real (vs 41% classifier) — promisiuni pre-mandate fulfilled- **Anti-corupție**: 67% real (vs 0% classifier) — numiri DNA/DIICOT- **Diaspora**: 100% real (vs 0% classifier) — consilieri prezidențiali pentru diaspora numiți- **București/local**: 44% real (vs 4% classifier) — proiecte PMB executate sub Bujduveanu/Ciucu- **Sănătate / Educație**: 0% KEPT atât classifier cât și real — domenii unde livrarea concretă este realmente limitată::: {.callout-tip}## Cum s-au calculat aceste cifreBar chart de mai sus folosește date computate **direct din `promise_status.jsonl`** (câmpurile `status_status` pentru clasificator, `manual_factcheck_status` pentru fact-check). Recalculate la fiecare render — sincronizate cu datele.:::ND **execută concret pe aceste domenii — dar nu vorbește despre realizările sale post-execuție**.## Caz emblematic — **"Dau în scris că TVA nu va crește"**Pe **14 mai 2025**, cu 4 zile înainte de turul 2, în campanie, Nicușor Dan a făcut o promisiune memorabilă, ferm exprimată — fixată în titlul publicării video oficiale:> **«Da, dau în scris.»**>> *"Satul român trebuie să fie suficient de ferm pentru a încasa taxele care i se cuvin la cuantumul care sunt azi... TVA de 19%, [...] putem să redresăm. Da, dau în scris."*>> — Nicușor Dan, [video oficial 14 mai 2025](https://www.youtube.com/watch?v=crohFUCmAxY), titlu video: *"Nicușor Dan: Dau în scris că TVA nu va crește"***6 săptămâni mai târziu — TVA crescut.**::: {.callout-warning}## ⚠️ Limitare metodologică detectatăAceastă promisiune **NU apare în top 131 promisiuni canonice** clasificate de pipeline. Extractorul LLM a căutat formulări de tip *"Voi face X"* și a ratat formularea negativă *"X nu se va întâmpla"*. Promisiunea e bine documentată media (titlul video oficial) și e *prima* pe rezultate Google pentru "Nicușor Dan TVA promisiune".Asta e un blind spot al Promise Tracker-ului — formularea în negativ scapă extracției. Adăugată manual ca **CONTRADICTED**.:::### Cronologia reală (fact-check media)| Data | Eveniment | Sursă ||---|---|---|| **14 mai 2025** | ND, în campanie: *"Dau în scris că TVA nu va crește"* | [YouTube oficial](https://www.youtube.com/watch?v=crohFUCmAxY) || **18 mai 2025** | ND câștigă alegerile prezidențiale (turul 2) | — || **20 iunie 2025** | Negocieri Cotroceni: **dezacord ND-Bolojan pe TVA**. Bolojan: *"fie accepți majorarea, fie te gândești la premier tehnocrat"* | [Curs de Guvernare](https://cursdeguvernare.ro/desemnarea-premierului-amanata-dezacordului-majorare-tva.html), [Europa Liberă](https://romania.europalibera.org/a/negocierile-de-formare-a-noului-guvern-in-impas-nicusor-dan-si-ilie-bolojan-in-dezacord-privind-posibilitatea-majorarii-tva/33449639.html) || **20 iunie 2025** | Compromis: TVA 19% rămâne, dar **TVA reduse 5%/9% cresc la 11% din august**. Reevaluare în octombrie | [Digi24](https://www.digi24.ro/stiri/actualitate/politica/compromisul-la-care-au-ajuns-ilie-bolojan-si-nicusor-dan-in-privinta-tva-cota-de-19-nu-se-modifica-3293031), [HotNews](https://hotnews.ro/ce-au-convenit-nicusor-dan-si-ilie-bolojan-privind-cresterea-tva-2007618) || **2 iulie 2025** | Bolojan își angajează răspunderea: **TVA general 19% → 21%**, TVA reduse 5%/9% → **11%/21%** | [spotmedia.ro](https://spotmedia.ro/stiri/economie/bolojan-anunta-azi-pachetul-fiscal), [StartupCafe](https://startupcafe.ro/taxe-2025-2026-impozit-pe-dividende-de-16-cota-generala-de-tva-de-21-majorare-accize-si-alte-masuri-fiscale-anuntate-de-premierul-bolojan-83305) || **1 august 2025** | Măsurile intră în vigoare. TVA crescut **substanțial** pentru consumatori | [Europa Liberă](https://romania.europalibera.org/a/lista-modificarilor-fiscale-care-te-ar-putea-afecta-de-la-1-august/33476672.html) || **27 nov 2025** | Bolojan: *"Creșterea TVA în iulie a fost o necesitate"*. ND a comentat că măsura "putea să nu fie luată" | [AGERPRES](https://agerpres.ro/economic/2025/11/27/bolojan-cresterea-tva-in-luna-iulie-a-fost-o-necesitate--1506966), [Euronews](https://www.euronews.ro/articole/cresterea-tva-tensiune-intre-presedintele-nicusor-dan-si-premierul-ilie-bolojan) || **24 nov 2025** | Date oficiale: încasările TVA **au scăzut** după majorare. Inflație, șomaj, scădere consum | [Găzarul](https://gazarul.ro/2025/11/24/incasarile-din-tva-au-scazut-dupa-majorarea-taxei-efectul-masurii-luate-de-guvernarea-bolojan/) |::: {.callout-important}## Verdict: CONTRADICTED clasic- **Promisiune**: TVA NU va crește- **Realitate (după 6 săptămâni)**: TVA general 19% → 21%, TVA reduse aproape *dublate* (5% → 11%, 9% → 11-21%)- **ND a pierdut negocierea internă cu Bolojan** — premierul a pus condiția majorării- **ND a comentat ulterior**: măsura "putea să nu fie luată"**Cazul demonstrează 3 lucruri**:1. **ND nu domină mereu executivul** — pe deciziile fiscale dure, Bolojan a impus poziția.2. **Promisiunea de campanie a fost încălcată direct** — nu reframuită, ci contrazisă într-o lună de la învestire.3. **Pipeline-ul are blind spot** — promisiuni formulate negativ ("X nu se va întâmpla") scapă extractorului.:::### Caz secundar — "viceprimar = primar interimar"Există și un alt caz interesant, dar mai nuanțat: promisiunea din 20 mai 2025 că **Adrian Vigheciu (PSD)** va fi primar interimar al Capitalei. ND a împins ulterior pentru **Stelian Bujduveanu (PNL)** — *spiritul* promisiunii (viceprimar = primar interimar) a fost respectat, *persoana s-a schimbat* conștient și anunțat. Asta e **REFRAMED**, nu CONTRADICTED. [Vezi cronologia detaliată în `results/04_promises/`](https://github.com/radusqrt/evolutie-discurs-nicusor-dan/blob/main/results/04_promises/).## Toate cele 131 promisiuni — explorabil```{python}#| echo: falsefrom itables import showfrom itables import options as optopt.maxBytes =0opt.lengthMenu = [10, 25, 50, 100, 131]opt.classes ="display compact"display = promises[["manual_factcheck_status", "status_status", "topic","specificity", "promise_text", "factcheck_reasoning","source_date"]].copy()display.columns = ["Status real", "Status clasificator", "Topic", "Spec.","Promisiune", "Raționament fact-check", "Data"]real_map = {"KEPT_real": "✅ Ținută","IN_PROGRESS_real": "🔄 În curs","NO_MENTION_real": "❓ Nemenționată","CONTRADICTED_real": "⚠️ Contrazisă","REFRAMED_real": "🔀 Redefinită","UNVERIFIABLE": "ⓘ Prea vagă",}clf_map = {"KEPT": "✅","IN_PROGRESS": "🔄","NO_MENTION": "❓","CONTRADICTED": "⚠️","REFRAMED": "🔀",}display["Status real"] = display["Status real"].map(real_map).fillna(display["Status real"])display["Status clasificator"] = display["Status clasificator"].map(clf_map).fillna(display["Status clasificator"])show(display, paging=True, search=True, scrollX=True)```[← Înapoi acasă](index.qmd) · [Vezi cum vorbește despre Bolojan →](bolojan.qmd)