# VERDICT UI SPECIFICATION Design UI admin dashboard — tot ce se editeaza pentru a controla verdictul. Pagina: `/admin/verdict-config` (tab nou in sidebar, sau sub-pagina in LLM Components Config) --- ## LAYOUT GENERAL ``` ┌─────────────────────────────────────────────────────────────────────┐ │ SIDEBAR │ CONTENT │ │ │ │ │ [1] Input Profiles ◄────│ ┌─────────────────────────────────┐ │ │ [2] Override Rules │ │ Tab content here │ │ │ [3] AI Disclosure │ │ │ │ │ [4] Claims Weights │ │ │ │ │ [5] Verdict Categories │ │ │ │ │ [6] Risk & Severity │ │ │ │ │ [7] Confidence │ │ │ │ │ [8] Topic Multipliers │ │ │ │ │ [9] LLM Reviewer │ │ │ │ │ [10] Score Simulator ★ │ │ │ │ │ │ └─────────────────────────────────┘ │ │ ────────────────── │ │ │ [Sync to Redis] │ [Save] [Reset to defaults] │ └─────────────────────────────────────────────────────────────────────┘ ``` --- ## TAB 1: INPUT PROFILES — Ponderi per tip input **Ce controleaza**: Cat conteaza fiecare componenta in scorul final, per tip de input. **Formula afectata**: `risk_score = sum(component_risk × weight) / sum(weights)` ### UI Layout ``` ┌─────────────────────────────────────────────────────────────────────┐ │ Input Profiles │ │ │ │ ┌──────────────────────────────────────────────────────────┐ │ │ │ [Text] [Text+URL] [Image] [Audio] [Video] [URL] │ │ │ └──────────────────────────────────────────────────────────┘ │ │ ▲ tab selectat: Image │ │ │ │ Profile: Image │ │ Description: "Analiza imagine — AI detection e componenta primara" │ │ │ │ ┌─ COMPONENT WEIGHTS ─────────────────────────────────────────┐ │ │ │ │ │ │ │ Techniques ████████░░░░░░░░░░░░ 20% [role: secondary]│ │ │ │ Claims ██████░░░░░░░░░░░░░ 15% [role: secondary]│ │ │ │ AI Tampered █████████████████████░░ 50% [role: PRIMARY ]│ │ │ │ Source ██████░░░░░░░░░░░░ 15% [role: secondary]│ │ │ │ ──── │ │ │ │ Total: 100% ✓ │ │ │ │ │ │ │ │ ⚠ Total must equal 100%. Drag sliders to adjust. │ │ │ └──────────────────────────────────────────────────────────────┘ │ │ │ │ ┌─ INCONCLUSIVE RULES ────────────────────────────────────────┐ │ │ │ │ │ │ │ Minimum components to produce verdict: [ 1 ] ▼ │ │ │ │ │ │ │ │ Primary component(s) — INCONCLUSIVE if ALL crash: │ │ │ │ [✓] AI Tampered │ │ │ │ [ ] Techniques │ │ │ │ [ ] Claims │ │ │ │ [ ] Source │ │ │ │ │ │ │ │ Required ANY (at least one must run): │ │ │ │ [✓] AI Tampered │ │ │ │ [ ] Techniques │ │ │ │ [ ] Claims │ │ │ │ [ ] Source │ │ │ └──────────────────────────────────────────────────────────────┘ │ │ │ │ ┌─ MISSING COMPONENT HANDLING ────────────────────────────────┐ │ │ │ │ │ │ │ When Techniques is missing: [Redistribute ] ▼ │ │ │ │ When Claims is missing: [Redistribute + penalty] ▼ │ │ │ │ When AI Tampered is missing: [→ INCONCLUSIVE ] ▼ │ │ │ │ When Source is missing: [Redistribute ] ▼ │ │ │ │ │ │ │ │ Options: Redistribute | Redistribute + confidence penalty │ │ │ │ | → INCONCLUSIVE | Ignore (weight=0) │ │ │ └──────────────────────────────────────────────────────────────┘ │ │ │ │ [Save Profile] [Reset to Default] [Copy from: [Text ▼] ] │ └─────────────────────────────────────────────────────────────────────┘ ``` ### Tabel CRUD in PG | Coloana | Tip | Exemplu | UI element | |---|---|---|---| | `profile_code` | VARCHAR PK | "image" | Tab selector | | `profile_name` | VARCHAR | "Analiza imagine" | Text input | | `description` | TEXT | "AI detection e componenta primara" | Textarea | | `weight_techniques` | INTEGER | 20 | Slider 0-100 | | `weight_claims` | INTEGER | 15 | Slider 0-100 | | `weight_ai_tampered` | INTEGER | 50 | Slider 0-100 | | `weight_source` | INTEGER | 15 | Slider 0-100 | | `role_techniques` | VARCHAR | "secondary" | Dropdown | | `role_claims` | VARCHAR | "secondary" | Dropdown | | `role_ai_tampered` | VARCHAR | "primary" | Dropdown | | `role_source` | VARCHAR | "secondary" | Dropdown | | `min_components` | INTEGER | 1 | Number input | | `primary_components` | TEXT[] | {"ai_tampered"} | Checkboxes | | `required_any` | TEXT[] | {"ai_tampered"} | Checkboxes | | `missing_techniques` | VARCHAR | "redistribute" | Dropdown | | `missing_claims` | VARCHAR | "redistribute_penalty" | Dropdown | | `missing_ai_tampered` | VARCHAR | "inconclusive" | Dropdown | | `missing_source` | VARCHAR | "redistribute" | Dropdown | | `is_active` | BOOLEAN | true | Toggle | **6 profiluri default**: text_no_url, text_with_url, image, audio, video, url --- ## TAB 2: OVERRIDE RULES — Bonusuri de risc per profil **Ce controleaza**: Ce override-uri se aplica si cu ce valori, per tip de input. **Formula afectata**: `risk_score += sum(override_bonuses)` (dupa media ponderata, cap configurat) ### UI Layout ``` ┌─────────────────────────────────────────────────────────────────────┐ │ Override Rules │ │ │ │ Profile: [Image ▼] Override Cap Total: [ 50 ] puncte │ │ │ │ ┌─────────────────────────────────────────────────────────────┐ │ │ │ Override │ Activ │ Parametri │ Impact │ │ │ ├───────────────────────┼───────┼────────────────────┼─────────┤ │ │ │ False Claims │ [ON] │ +[15]/claim max[40]│ MARE │ │ │ │ Unverified Verifiable │ [ON] │ prag[3] bonus[10] │ MEDIU │ │ │ │ Severe Techniques │ [ON] │ prag[2] bonus[10] │ MEDIU │ │ │ │ Undisclosed AI │ [ON] │ bonus [10] │ MEDIU │ │ │ │ Untrusted Source │ [OFF] │ bonus [20] │ — │ │ │ │ Blacklisted Source │ [OFF] │ bonus [25] │ — │ │ │ │ Source Red Flags │ [OFF] │ prag[2] +[5] mx[15]│ — │ │ │ │ Synergy (multi high) │ [ON] │ prag[70] +[5] mx[15│ MEDIU │ │ │ └─────────────────────────────────────────────────────────────┘ │ │ │ │ Nota: Override-uri dezactivate (OFF) nu contribuie la scor │ │ indiferent de datele componentelor. │ │ │ │ ┌─ EXEMPLU LIVE ──────────────────────────────────────────────┐ │ │ │ Cu setarile curente, daca 2 claims false + undisclosed AI: │ │ │ │ Override total: 2×15 + 10 = +40 puncte (sub cap 50) ✓ │ │ │ └──────────────────────────────────────────────────────────────┘ │ │ │ │ [Save] [Copy overrides from: [Text ▼] ] │ └─────────────────────────────────────────────────────────────────────┘ ``` ### Tabel CRUD in PG | Coloana | Tip | Exemplu | |---|---|---| | `profile_code` | VARCHAR FK | "image" | | `override_code` | VARCHAR | "false_claims" | | `enabled` | BOOLEAN | true | | `threshold` | INTEGER NULL | 1 (min claims false pt activare) | | `bonus_per_unit` | INTEGER NULL | 15 (per claim fals) | | `bonus_fixed` | INTEGER NULL | NULL (foloseste per_unit) | | `max_bonus` | INTEGER NULL | 40 | | `override_cap` | INTEGER | 50 (pe intregul profil) | **8 override-uri × 6 profiluri = 48 randuri** (pre-populate la creare profil) --- ## TAB 3: AI DISCLOSURE — Multiplicatori disclosure **Ce controleaza**: Cat de mult conteaza AI detection cand AI-ul e declarat vs nedeclarat. **Formula afectata**: `ai_risk = ai_probability × disclosure_multiplier` ### UI Layout ``` ┌─────────────────────────────────────────────────────────────────────┐ │ AI Disclosure Impact │ │ │ │ Cand continutul AI e declarat, riscul scade proportional. │ │ Misinformarea prin AI vine din DECEPTIE, nu din AI in sine. │ │ │ │ ┌─────────────────────────────────────────────────────────────┐ │ │ │ │ │ │ │ Explicit disclosure ██░░░░░░░░░░░░░░░░ 0.15 (15%) │ │ │ │ ("Scris cu ChatGPT") │ │ │ │ Exemplu: AI prob=80 → risk = 80 × 0.15 = 12 │ │ │ │ │ │ │ │ Partial disclosure ████████░░░░░░░░░░ 0.40 (40%) │ │ │ │ ("Cu ajutorul AI") │ │ │ │ Exemplu: AI prob=80 → risk = 80 × 0.40 = 32 │ │ │ │ │ │ │ │ Implied disclosure ████████████░░░░░░ 0.60 (60%) │ │ │ │ (Mentionat ChatGPT) │ │ │ │ Exemplu: AI prob=80 → risk = 80 × 0.60 = 48 │ │ │ │ │ │ │ │ No disclosure ████████████████████ 1.00 (100%) │ │ │ │ (Nedeclarat) │ │ │ │ Exemplu: AI prob=80 → risk = 80 × 1.00 = 80 │ │ │ │ │ │ │ └─────────────────────────────────────────────────────────────┘ │ │ │ │ Acesti multiplicatori se aplica pe TOATE profilurile. │ │ Override-ul "Undisclosed AI" (tab Override Rules) se aplica │ │ suplimentar DOAR cand disclosure = none. │ │ │ │ [Save] [Reset to defaults] │ └─────────────────────────────────────────────────────────────────────┘ ``` ### CRUD Se poate stoca in `component_config` existent (JSONB) sau tabel dedicat. | Coloana | Tip | Exemplu | |---|---|---| | `disclosure_type` | VARCHAR PK | "explicit" | | `multiplier` | NUMERIC | 0.15 | | `description` | TEXT | "AI declarat clar — aproape zero risc" | | `example` | TEXT | "Acest articol a fost scris cu ChatGPT" | **4 randuri fixe** (explicit, partial, implied, none). Nu se adauga/sterg, doar se editeaza multiplicatorii. --- ## TAB 4: CLAIMS WEIGHTS — Ponderi credibilitate per status si tip **Ce controleaza**: Cum contribuie fiecare claim la scorul de credibilitate. **Formula afectata**: `credibility_score = sum(status_weight × type_weight) / sum(type_weight)` ### UI Layout ``` ┌─────────────────────────────────────────────────────────────────────┐ │ Claims Scoring Configuration │ │ │ │ ┌─ STATUS WEIGHTS (cat valoreaza fiecare status) ─────────────┐ │ │ │ │ │ │ │ VT Verified True ████████████████████ [ 1.00 ] │ │ │ │ LT Likely True ███████████████░░░░░ [ 0.75 ] │ │ │ │ UV Unverified (per tip — vezi mai jos) │ │ │ │ OP Opinion as Fact ██████░░░░░░░░░░░░░ [ 0.30 ] │ │ │ │ LF Likely False █████░░░░░░░░░░░░░░ [ 0.25 ] │ │ │ │ VF Verified False ░░░░░░░░░░░░░░░░░░░ [ 0.00 ] │ │ │ │ NV Not Verifiable (exclus din calcul) │ │ │ │ │ │ │ └──────────────────────────────────────────────────────────────┘ │ │ │ │ ┌─ UNVERIFIED WEIGHTS PER CLAIM TYPE ─────────────────────────┐ │ │ │ │ │ │ │ Tip claim │ Cod │ UV Weight │ Logica │ │ │ │ ──────────────────┼─────┼───────────┼─────────────────── │ │ │ │ Factual verificab.│ VF │ [0.25] ██ │ Suspect — faptele │ │ │ │ │ │ │ reale au surse web │ │ │ │ Stiintific │ SC │ [0.25] ██ │ Studiile sunt publice │ │ │ │ Cantitativ │ QA │ [0.30] ██ │ Statisticile au sursa │ │ │ │ Factual general │ EF │ [0.35] ██ │ Moderat suspect │ │ │ │ Cauzal │ CC │ [0.40] ██ │ Greu de verificat │ │ │ │ Reglementare │ RE │ [0.40] ██ │ Moderat │ │ │ │ Predictiv │ PC │ [0.50] ██ │ Viitorul nu se verif. │ │ │ │ Opinie/Valoare │ OP │ [0.50] ██ │ Opiniile nu se verif. │ │ │ │ │ │ │ │ ⚠ Valori mici (0.25) = "neverificat e suspect" │ │ │ │ Valori mari (0.50) = "neverificat e neutru" │ │ │ └──────────────────────────────────────────────────────────────┘ │ │ │ │ ┌─ CAZUL SPECIAL: TOATE NEVERIFICATE ─────────────────────────┐ │ │ │ │ │ │ │ Cand TOATE claims sunt UV si fara surse web: │ │ │ │ Comportament: [Calculeaza normal per tip ▼] │ │ │ │ │ │ │ │ Optiuni: │ │ │ │ • Calculeaza normal per tip (propus) │ │ │ │ • Forteaza credibility 75% (actual) │ │ │ │ • Forteaza credibility 50% (neutru strict) │ │ │ └──────────────────────────────────────────────────────────────┘ │ │ │ │ [Save] [Reset to defaults] │ └─────────────────────────────────────────────────────────────────────┘ ``` ### CRUD — camp NOU in tabel existent Tabelul `claim_type` din `bos_parammgmt` primeste coloana: | Coloana noua | Tip | Default | |---|---|---| | `unverified_weight` | NUMERIC(3,2) | 0.50 | Tabelul `claim` (statuses) primeste coloana: | Coloana noua | Tip | Default | |---|---|---| | `credibility_weight` | NUMERIC(3,2) | 0.50 | **Deja exista UI** in FrameworkDashboard → Claims → Types/Status. Se adauga doar coloana noua in tabelul CRUD existent. --- ## TAB 5: VERDICT CATEGORIES — Range-uri scor → categorie **Ce controleaza**: Ce eticheta primeste scorul final (RELIABLE, MIXED, DISINFORMATION etc.) **DEJA EXISTA** in FrameworkDashboard → Verdicts → Categories. Doar se regrupeaza aici. ### UI Layout (mutata din FrameworkDashboard) ``` ┌─────────────────────────────────────────────────────────────────────┐ │ Verdict Categories │ │ │ │ Scor │ 0────15│16───30│31───55│56───75│76───90│91──100│ │ │ │ RELIAB │MOSTLY │ MIXED │QUESTI │UNRELI │DISINF│ │ │ │ verde │l.green│galben │portoc.│ rosu │bordo │ │ │ │ │ ┌─────────────────────────────────────────────────────────────┐ │ │ │ Cod │ Range │ Culoare │ Descriere │ │ │ ├──────────────────┼──────────┼─────────┼─────────────────────┤ │ │ │ RELIABLE │ [0]-[15] │ [green] │ [Continut de incr.] │ │ │ │ MOSTLY_RELIABLE │ [16]-[30]│ [l.grn] │ [Preponderent cred] │ │ │ │ MIXED │ [31]-[55]│ [yellw] │ [Informatie mixta ] │ │ │ │ QUESTIONABLE │ [56]-[75]│ [ornge] │ [Indoielnic ] │ │ │ │ UNRELIABLE │ [76]-[90]│ [red ] │ [Putin credibil ] │ │ │ │ DISINFORMATION │ [91]-[100│ [dkred] │ [Probabil dezinf. ] │ │ │ │ INCONCLUSIVE │ special │ [gray ] │ [Date insuficiente] │ │ │ └─────────────────────────────────────────────────────────────┘ │ │ │ │ ⚠ Range-urile trebuie sa acopere 0-100 fara gap-uri. │ │ INCONCLUSIVE e setat algoritmic din profil, nu din range. │ │ │ │ [Save] [Add Category] [Reset to defaults] │ └─────────────────────────────────────────────────────────────────────┘ ``` ### CRUD — tabel existent `verdict_category` Deja exista. Zero schimbari PG. --- ## TAB 6: RISK & SEVERITY — Nivele de risc + actiuni recomandate **DEJA EXISTA** in FrameworkDashboard → Verdicts → Risk / Severity. Se regrupeaza. ### UI Layout ``` ┌─────────────────────────────────────────────────────────────────────┐ │ Risk Levels & Severity │ │ │ │ ┌─ RISK LEVELS ───────────────────────────────────────────────┐ │ │ │ Nivel │ Range │ Culoare │ │ │ │ │ VERY_LOW │ [0]-[10] │ [green] │ │ │ │ │ LOW │ [11]-[25]│ [l.grn] │ │ │ │ │ MEDIUM │ [26]-[50]│ [yellw] │ │ │ │ │ HIGH │ [51]-[75]│ [ornge] │ │ │ │ │ VERY_HIGH │ [76]-[90]│ [red ] │ │ │ │ │ CRITICAL │ [91]-[100│ [dkred] │ │ │ │ └──────────────────────────────────────────────────────────────┘ │ │ │ │ ┌─ SEVERITY + ACTIUNI ────────────────────────────────────────┐ │ │ │ Severity │ Range │ Actiune recomandata │ │ │ │ LOW │ [0]-[29] │ [MONITOR ] │ │ │ │ MEDIUM │ [30]-[59]│ [REVIEW ] │ │ │ │ HIGH │ [60]-[79]│ [ESCALATE ] │ │ │ │ CRITICAL │ [80]-[100│ [URGENT ] │ │ │ └──────────────────────────────────────────────────────────────┘ │ │ │ │ [Save] [Reset to defaults] │ └─────────────────────────────────────────────────────────────────────┘ ``` ### CRUD — tabele existente `risk_mapping`, `severity_assessment` Deja exista. Zero schimbari PG. --- ## TAB 7: CONFIDENCE — Cum se calculeaza increderea **Ce controleaza**: Cat de siguri suntem pe verdictul dat. **Formula afectata**: `confidence = base × components_ok - penalties + bonuses` ### UI Layout ``` ┌─────────────────────────────────────────────────────────────────────┐ │ Confidence Configuration │ │ │ │ Profile: [Image ▼] (confidence se configureaza PER profil) │ │ │ │ ┌─ BASE ──────────────────────────────────────────────────────┐ │ │ │ Base per component available: [15] puncte │ │ │ │ (4 componente × 15 = 60 baza maxima) │ │ │ └──────────────────────────────────────────────────────────────┘ │ │ │ │ ┌─ PENALTIES (cand o componenta CRAPAT — nu lipsa, ci eroare) ┐ │ │ │ │ │ │ │ Claims crash: -[25] puncte (cel mai sever) │ │ │ │ Techniques crash: -[15] puncte │ │ │ │ AI Tampered crash: -[10] puncte │ │ │ │ Source crash: -[5] puncte │ │ │ └──────────────────────────────────────────────────────────────┘ │ │ │ │ ┌─ BONUSES (semnale puternice cresc increderea) ──────────────┐ │ │ │ │ │ │ │ Source verdict TRUSTED/UNTRUSTED (semnal clar): +[15] │ │ │ │ Source verdict NEUTRAL/SUSPICIOUS (semnal slab): +[8] │ │ │ │ Techniques: avg(confidence) / 100 × [12] max │ │ │ │ AI confidence HIGH: +[12] MEDIUM: +[8] LOW: +[4] │ │ │ │ Claims verified ratio × [11] max │ │ │ └──────────────────────────────────────────────────────────────┘ │ │ │ │ ┌─ LEVELS ────────────────────────────────────────────────────┐ │ │ │ HIGH: >= [75] │ │ │ │ MEDIUM: >= [50] │ │ │ │ LOW: < [50] │ │ │ └──────────────────────────────────────────────────────────────┘ │ │ │ │ [Save] [Copy from: [Text ▼] ] [Reset to defaults] │ └─────────────────────────────────────────────────────────────────────┘ ``` ### CRUD Stocat in `input_type_profile.confidence_config` (JSONB) sau tabel separat `profile_confidence_config`. --- ## TAB 8: TOPIC MULTIPLIERS — Amplificatori de context **Ce controleaza**: Anumite topicuri (alegeri, sanatate) amplifica riscul. **Formula afectata**: `risk_score = weighted_average × topic_multiplier` (INAINTE de override) **DEJA EXISTA** in FrameworkDashboard → Weights → Multipliers. Se regrupeaza. ### UI Layout ``` ┌─────────────────────────────────────────────────────────────────────┐ │ Topic Multipliers │ │ │ │ Acesti multiplicatori se aplica INAINTE de override-uri. │ │ Valoare > 100% = amplifica riscul. < 100% = reduce riscul. │ │ │ │ ┌─────────────────────────────────────────────────────────────┐ │ │ │ Topic │ Multiplicator │ Efect pe scor 50 │ │ │ ├───────────────┼───────────────┼─────────────────────────────┤ │ │ │ elections │ [150]% ████ │ 50 → 75 (+50%) │ │ │ │ health │ [130]% ███ │ 50 → 65 (+30%) │ │ │ │ climate │ [120]% ██ │ 50 → 60 (+20%) │ │ │ │ finance │ [110]% ██ │ 50 → 55 (+10%) │ │ │ │ entertainment │ [ 80]% █ │ 50 → 40 (-20%) │ │ │ └─────────────────────────────────────────────────────────────┘ │ │ │ │ [Add Topic] [Save] [Reset to defaults] │ └─────────────────────────────────────────────────────────────────────┘ ``` ### CRUD — tabel existent `multiplier` Deja exista. Zero schimbari PG. --- ## TAB 9: LLM REVIEWER — Configurare reviewer final **Ce controleaza**: Cata putere are LLM-ul sa ajusteze verdictul matematic. ### UI Layout ``` ┌─────────────────────────────────────────────────────────────────────┐ │ LLM Verdict Reviewer │ │ │ │ ┌─ GENERAL ───────────────────────────────────────────────────┐ │ │ │ Enabled: [ON] │ │ │ │ Max adjustment: ±[20] puncte │ │ │ │ Confidence penalty -[10] puncte (daca LLM pica) │ │ │ │ on LLM failure: │ │ │ └──────────────────────────────────────────────────────────────┘ │ │ │ │ ┌─ MODEL CHAIN (ordinea de fallback) ─────────────────────────┐ │ │ │ 1. Primary: [local:qwen3-235b ▼] timeout [45]s │ │ │ │ 2. Fallback 1: [openrouter:gemini-flash ▼] timeout [30]s │ │ │ │ 3. Fallback 2: [openrouter:gpt-4o-mini ▼] timeout [30]s │ │ │ │ │ │ │ │ [Add fallback] [Test primary model] │ │ │ └──────────────────────────────────────────────────────────────┘ │ │ │ │ ┌─ CE PRIMESTE LLM-UL ───────────────────────────────────────┐ │ │ │ [✓] Scoruri componente │ │ │ │ [✓] Profilul input_type folosit │ │ │ │ [✓] Claims false cu text (max [3]) │ │ │ │ [✓] Claims neverificate verificabile │ │ │ │ [✓] Disclosure AI detalii │ │ │ │ [✓] Source Assessment complet │ │ │ │ [✓] Tehnici top cu dimensiuni │ │ │ │ [✓] Red flags din toate componentele │ │ │ │ [✓] Metadata media (transcript, frames) │ │ │ │ [✓] Limitari componente │ │ │ └──────────────────────────────────────────────────────────────┘ │ │ │ │ ┌─ CE PRODUCE LLM-UL ────────────────────────────────────────┐ │ │ │ [✓] Explicatie RO + EN (3-5 propozitii) │ │ │ │ [✓] Risk score ajustat (±max_adjustment) │ │ │ │ [✓] Key findings (bullet points) │ │ │ │ [✓] Warnings (avertismente pt utilizator) │ │ │ │ [✓] Reasoning (pentru audit intern) │ │ │ └──────────────────────────────────────────────────────────────┘ │ │ │ │ [Save] [Edit System Prompt] [Edit User Prompt Template] │ └─────────────────────────────────────────────────────────────────────┘ ``` ### CRUD Stocat in `component_config` existent (config_key = "verdict_config", config_value = JSONB). Prompturile in `component_prompt` existent (component_code = "verdict", stage_code = "explanation"). Modelele in `component_stage_assignment` existent. **Zero tabele noi** — totul in infrastructura existenta. --- ## TAB 10: SCORE SIMULATOR — Cel mai important tool **Ce face**: Adminul introduce scoruri mock si vede instant ce verdict ar produce. ### UI Layout ``` ┌─────────────────────────────────────────────────────────────────────┐ │ Score Simulator ★ │ │ │ │ ┌─ INPUT ─────────────────────────────────────────────────────┐ │ │ │ │ │ │ │ Input Type: [Image ▼] Topic: [none ▼] │ │ │ │ │ │ │ │ ── Component Scores ── │ │ │ │ Techniques: [ 60 ] ████████████░░░░░░░░ │ │ │ │ Claims: [ N/A ] (dezactivat — nu a rulat) │ │ │ │ AI Tampered: [ 85 ] █████████████████░░░ │ │ │ │ Source: [ 40 ] ████████░░░░░░░░░░░░ │ │ │ │ │ │ │ │ ── Claims Details (optional) ── │ │ │ │ Total claims: [ 0 ] False: [ 0 ] Unverified: [ 0 ] │ │ │ │ │ │ │ │ ── AI Details ── │ │ │ │ AI Probability: [ 85 ] Disclosure: [none ▼] │ │ │ │ │ │ │ │ ── Source Details ── │ │ │ │ Verdict: [NEUTRAL ▼] Blacklisted: [ ] Red flags: [ 0 ] │ │ │ │ │ │ │ │ ── Failed Components ── │ │ │ │ [ ] Techniques [ ] Claims [ ] AI [ ] Source │ │ │ │ │ │ │ │ [CALCULATE] │ │ │ └──────────────────────────────────────────────────────────────┘ │ │ │ │ ┌─ RESULT ────────────────────────────────────────────────────┐ │ │ │ │ │ │ │ ┌─────────────────────────────────────────────────────┐ │ │ │ │ │ RISK SCORE: 78 UNRELIABLE │ │ │ │ │ │ ████████████████░░░░ │ │ │ │ │ │ Risk Level: VERY_HIGH Severity: CRITICAL │ │ │ │ │ │ Confidence: 42 (LOW) Action: URGENT │ │ │ │ │ └─────────────────────────────────────────────────────┘ │ │ │ │ │ │ │ │ ── Breakdown ── │ │ │ │ │ │ │ │ Profil folosit: image │ │ │ │ Ponderi: AI=50% Tech=20% Claims=15%(→0) Source=15% │ │ │ │ Redistribuire: AI=58.8% Tech=23.5% Source=17.6% │ │ │ │ │ │ │ │ Step 1 - Scoruri risc: │ │ │ │ manipulation=60, ai_risk=85×1.0(none)=85, source=60 │ │ │ │ │ │ │ │ Step 2 - Media ponderata: │ │ │ │ 60×23.5% + 85×58.8% + 60×17.6% = 14.1 + 50.0 + 10.6 │ │ │ │ = 74.7 │ │ │ │ │ │ │ │ Step 3 - Multiplicator topic: (none) → × 1.0 = 74.7 │ │ │ │ │ │ │ │ Step 4 - Override-uri: │ │ │ │ ✓ Undisclosed AI: +10 │ │ │ │ ✗ False claims: 0 false (inactive) │ │ │ │ ✗ Severe techniques: coupling data not available │ │ │ │ Total override: +10 │ │ │ │ │ │ │ │ Step 5 - Final: round(74.7 + 10) = 85 │ │ │ │ Step 6 - Remap: 85 → UNRELIABLE (76-90) │ │ │ │ Step 7 - INCONCLUSIVE check: NU (AI=primary, AI ok) │ │ │ │ │ │ │ │ ── Comparatie cu formula actuala ── │ │ │ │ Formula actuala: 72 (QUESTIONABLE) + INCONCLUSIVE fortat │ │ │ │ Formula noua: 85 (UNRELIABLE) ← +13 puncte, fara INCONCL│ │ │ │ │ │ │ └──────────────────────────────────────────────────────────────┘ │ │ │ └─────────────────────────────────────────────────────────────────────┘ ``` ### Logica Score Simulator **NU apeleaza backend**. Ruleza formula in browser (JavaScript pur) folosind configuratia din Redis (incarcata la deschiderea paginii). Rezultat instant la fiecare schimbare de slider. Optiune bonus: **"Compare with production"** — apeleaza backend-ul cu aceleasi scoruri si formula actuala, afiseaza diferenta. --- ## REZUMAT — CE E NOU VS CE EXISTA DEJA ### Exista deja in UI (se regrupeaza) | Ce | Unde e acum | Unde va fi | |---|---|---| | Verdict Categories (ranges) | FrameworkDashboard → Verdicts | Tab 5 | | Risk Mappings (ranges) | FrameworkDashboard → Verdicts | Tab 6 | | Severity (ranges + actions) | FrameworkDashboard → Verdicts | Tab 6 | | Topic Multipliers | FrameworkDashboard → Weights | Tab 8 | | Component Weights (global) | FrameworkDashboard → Weights | Inlocuit de Tab 1 (per profil) | | Claim Types (CRUD) | FrameworkDashboard → Claims | Tab 4 (camp nou) | | Claim Statuses (CRUD) | FrameworkDashboard → Claims | Tab 4 (camp nou) | | LLM Models + Prompts | LLM Components Config | Tab 9 | ### Nou (trebuie implementat) | Ce | Tab | Effort | |---|---|---| | Input Type Profiles (ponderi per input) | Tab 1 | Tabel PG + CRUD + UI | | Override Rules per profil | Tab 2 | Tabel PG + CRUD + UI | | AI Disclosure Multipliers | Tab 3 | 4 randuri in config + UI | | UV Weight per claim type | Tab 4 | 1 coloana noua + UI | | Credibility weight per status | Tab 4 | 1 coloana noua + UI | | Confidence config per profil | Tab 7 | JSONB in profil + UI | | Score Simulator | Tab 10 | Frontend JS pur | ### Tabele PG noi | Tabel | Coloane | Randuri default | |---|---|---| | `input_type_profile` | ~20 coloane (vezi Tab 1) | 6 (text, text+url, image, audio, video, url) | | `profile_override_config` | 7 coloane | 48 (8 override × 6 profiluri) | ### Coloane noi in tabele existente | Tabel | Coloana noua | Tip | |---|---|---| | `claim_type` | `unverified_weight` | NUMERIC(3,2) DEFAULT 0.50 | | `claim` (statuses) | `credibility_weight` | NUMERIC(3,2) DEFAULT 0.50 | ### Chei Redis noi | Cheie | Continut | |---|---| | `didi:config:pipeline:v1:input_profiles` | JSON cu toate profilurile + override-uri + confidence | | `didi:config:pipeline:v1:disclosure_multipliers` | JSON cu 4 multiplicatori | --- ## FLOW COMPLET: ADMIN EDITEAZA → VERDICT SE SCHIMBA ``` 1. Admin deschide /admin/verdict-config 2. Selecteaza Tab 1 → Profil "video" 3. Muta slider AI Tampered de la 40% la 50% 4. Ajusteaza Techniques de la 25% la 20% (total ramane 100%) 5. Click [Save Profile] └→ PUT /api/profiles/video → PG update → response 200 6. Admin deschide Tab 10 → Score Simulator 7. Selecteaza Input: video, AI=90, Techniques=30, Claims=N/A 8. Vede instant: Risk=78 UNRELIABLE (in loc de INCONCLUSIVE) 9. Satisfacut cu rezultatul 10. Click [Sync to Redis] (sidebar) └→ POST /api/sync-redis → citeste din PG → scrie in Redis └→ `didi:config:pipeline:v1:input_profiles` actualizat 11. Urmatoarea analiza video in agent-v3: └→ verdict-calculator citeste profil "video" din Redis └→ aplica ponderi noi: AI=50%, Tech=20% └→ verdict nou reflecta schimbarea ``` **Timp de la editare la efect**: ~5 secunde (save + sync + prima analiza). **Rollback**: Admin poate [Reset to defaults] oricand. **Audit**: Fiecare save in PG e versionat prin tabelul `parameter` existent.