livrare lot 2

This commit is contained in:
EVOTECH IT SRL 2026-07-10 03:39:53 -07:00
commit 8ecc78e729
763 changed files with 164593 additions and 0 deletions

View file

@ -0,0 +1,546 @@
# VERDICT ALIGNMENT PLAN
Plan complet de aliniere PG ↔ Redis ↔ Cod pentru tot sistemul de verdict.
**Regula de aur**: PG = source of truth. Redis = cache rapid. Cod = zero hardcodari (doar defaults de fallback).
**Flow**: Admin Dashboard → CRUD PG (didiFramework) → Sync Redis → agent-v3 citeste din Redis.
---
## 1. INVENTAR ACTUAL — UNDE E FIECARE PARAMETRU
### VERDE — Aliniat PG ↔ Redis ↔ UI (functioneaza corect)
| # | Parametru | PG tabel | Redis cheie | UI | agent-v3 citeste din |
|---|---|---|---|---|---|
| 1 | Verdict categories (ranges, culori) | `verdict_category` | `didi:framework:verdicts` | FrameworkDashboard | Redis |
| 2 | Risk mappings (ranges) | `risk_mapping` | `didi:framework:verdicts` | FrameworkDashboard | Redis |
| 3 | Severity (ranges + actiuni) | `severity_assessment` | `didi:framework:verdicts` | FrameworkDashboard | Redis |
| 4 | Component weights (35/25/20/10/10) | `component_weight` | `didi:framework:weights` | FrameworkDashboard | Redis |
| 5 | Weight scenarios | `weight_scenario` | `didi:framework:weights` | FrameworkDashboard | Redis |
| 6 | Topic multipliers | `multiplier` | `didi:framework:weights` | FrameworkDashboard | Redis |
| 7 | Claim statuses (VT, LT, UV...) | `claim` | `didi:framework:claims` | FrameworkDashboard | Redis |
| 8 | Claim types (VF, SC, QA...) | `claim_type` | `didi:framework:claims` | FrameworkDashboard | Redis |
| 9 | Claim confidence levels | `confidence` | `didi:framework:claims` | FrameworkDashboard | Redis |
| 10 | Claim interpretations | `interpretation` | `didi:framework:claims` | FrameworkDashboard | Redis |
| 11 | LLM stage assignments | `component_stage_assignment` | `didi:config:*:stage_assignments` | LLMComponentsConfig | Redis |
| 12 | LLM prompts | `component_prompt` | `didi:config:*:prompts:*` | LLMComponentsConfig | Redis |
| 13 | LLM available models | derivat din assignments | `didi:config:*:available_models` | LLMComponentsConfig | Redis |
| 14 | Platforms (social media) | `platform` | `didi:framework:sources` | FrameworkDashboard | Redis |
| 15 | Source credibility params | `source_credibility` + altele | `didi:framework:sources` | FrameworkDashboard | Redis |
| 16 | Techniques hierarchy | `dimension/subdimension/technique/indicator` | `didi:framework:techniques` | FrameworkDashboard | Redis |
**Total: 16 parametri complet aliniati.** Functionale, cu UI, cu sync.
---
### GALBEN — Exista in Redis dar NU in PG (puse manual, fara persistenta)
Mecanismul `component_config` (tabel PG) → `didi:config:*` (Redis) exista in sync-redis.ts (linia 576-583).
Dar nimeni nu a inserat randurile in PG. Cheile au fost puse direct in Redis manual.
| # | Redis cheie | Continut (rezumat) | In PG? | In UI? | Risc |
|---|---|---|---|---|---|
| 17 | `didi:config:techniques:v3:scoring_config` | countBonus, dimensionBonus, intensityBonus, manipulation_levels, warning_flags | **NU** | **NU** | Se pierde daca Redis se sterge |
| 18 | `didi:config:techniques:v3:coupling_registry` | Coupling config | **NU** | **NU** | |
| 19 | `didi:config:techniques:v3:schemas:*` (3 chei) | Zod schemas export | **NU** | **NU** | |
| 20 | `didi:config:techniques:v3:dimensions_compact` | Dimensiuni compacte pt screening | **NU** | **NU** | Derivabil din techniques hierarchy |
| 21 | `didi:config:ai-tampered:v1:scoring_config` | thresholds (70/50/30), disclosure_impact (0.3/0.5/0.7/1.0), category_weights, confidence_levels | **NU** | **NU** | Se pierde |
| 22 | `didi:config:ai-tampered:v1:categories_compact` | Categorii AI compacte pt screening | **NU** | **NU** | |
| 23 | `didi:config:ai-tampered:v1:indicators_hierarchy` | Categorii + indicatori AI | **NU** | **NU** | |
| 24 | `didi:config:ai-tampered:v1:quick_patterns` | Hedging patterns (regex) | **NU** | **NU** | |
| 25 | `didi:config:ai-tampered:v1:coupling_registry` | Coupling config AI | **NU** | **NU** | |
| 26 | `didi:config:ai-tampered:v1:schemas:*` (3 chei) | Zod schemas AI | **NU** | **NU** | |
| 27 | `didi:config:ai-tampered:v1:vision_models` | Cascade viziune (Qwen→Gemini→GPT-4o) | **NU** | **NU** | |
| 28 | `didi:config:claims:v1:scoring_config` | status_thresholds, claim_type_weights, source_reliability_weights | **NU** | **NU** | Se pierde |
| 29 | `didi:config:pipeline:v1:verdict_config` | synergy, overrides, confidence, confidence_levels | **NU** | **NU** | Se pierde — CRITIC |
| 30 | `didi:config:pipeline:v1:component_config` | Components enabled/disabled, applies_to, timeouts | **NU** | **NU** | Se pierde |
| 31 | `didi:config:pipeline:v1:session_config` | Session config | **NU** | **NU** | |
| 32 | `didi:config:pipeline:v1:external_apis` | API URLs externe | **NU** | **NU** | |
| 33 | `didi:config:pipeline:v1:prompts:verdict_explanation` | Prompt verdict reviewer | **NU** | **NU** | |
| 34 | `didi:config:vision:v1:prompts:extraction` | Prompt Vision OCR | **NU** | **NU** | |
| 35 | `didi:config:vision:v1:prompts:video_frames` | Prompt Vision video frames | **NU** | **NU** | |
| 36 | `didi:config:vision:v1:prompts:ai_detection` | Prompt Vision AI detection | **NU** | **NU** | |
| 37 | `didi:config:verdict:v1:available_models` | Modele LLM verdict reviewer | **NU** | **NU** | |
| 38 | `didi:config:source-assessment:v1:available_models` | Modele LLM source assessment | **NU** | **NU** | |
**Total: 22 parametri (unele cu sub-chei) in Redis fara PG. RISC: se pierd la orice Redis flush/restart fara persistenta.**
---
### ROSU — Hardcodat DOAR in cod (nici PG, nici Redis)
| # | Parametru | Fisier | Valoare actuala | Ar trebui in |
|---|---|---|---|---|
| 39 | Count scaler divisor | `techniques/executor.ts:614` | `3` (1 tech=33%) | `techniques.scoring_config` |
| 40 | Severe technique threshold | `techniques/executor.ts:686` | `severity >= 8` | `techniques.scoring_config` |
| 41 | Intensity bonus formula | `techniques/executor.ts:635` | `min(0.15, sqrt(x-1)*0.05)` | `techniques.scoring_config` (codul sa citeasca parametrii, nu formula string) |
| 42 | AI blend screening/deep | `ai-tampered/executor.ts:705` | `0.6 / 0.4` | `ai-tampered.scoring_config` |
| 43 | AI undisclosed threshold | `ai-tampered/executor.ts:725` | `>= 50` | `ai-tampered.scoring_config` |
| 44 | AI disclosure rating vals | `ai-tampered/executor.ts:792-798` | `80/40/25/+15/+5` | Inlocuit de `disclosure_impact` din Redis #21 |
| 45 | AI quick analyze scores | `ai-tampered/executor.ts:378-410` | `+10/+30/+15/+40/+25` | `ai-tampered.scoring_config.quick_scores` |
| 46 | Source axis weights | `source-assessment/executor.ts:110-113` | `0.35/0.25/0.25/0.15` | `source-assessment.scoring_config` (NOU) |
| 47 | Source verdict thresholds | `source-assessment/executor.ts:296-299` | `70/50/30` | `source-assessment.scoring_config` (NOU) |
| 48 | Video track weights | `component-worker.ts` | `0.40/0.60` | `pipeline.component_config` |
| 49 | Video min text chars | `component-worker.ts` | `200` | `pipeline.component_config` |
| 50 | Claims status weights | `claims/executor.ts:681-688` | `VT=1.0,LT=0.75,UV=0.5,...` | `claims.scoring_config.status_weights` (exista partial in Redis dar codul NU citeste) |
| 51 | Claims "all UV = 75%" | `claims/executor.ts:673` | `0.75` | `claims.scoring_config.all_unverified_credibility` |
| 52 | Input profiles per type | NICAIERI | nu exista | `pipeline.input_profiles` (NOU) |
| 53 | INCONCLUSIVE rules | `verdict-calculator.ts:321-337` | 3 if-uri | `pipeline.input_profiles` (NOU) |
| 54 | Context = -1 always | `verdict-calculator.ts:448` | `-1` | ELIMINAT din formula |
**Total: 16 parametri hardcodati in cod.**
---
### DIVERGENTE — Acelasi parametru cu valori diferite in Redis vs Cod
| # | Parametru | In Redis | In Cod | Codul citeste din |
|---|---|---|---|---|
| D1 | Claims status weights | Redis: `claim_type_weights: {EF:0.95, VF:0.85...}` (tip → weight) | Cod: `{VT:1.0, LT:0.75, UV:0.5...}` (status → weight) | **COD** — sunt concepte DIFERITE, nu duplicate |
| D2 | Intensity bonus | Redis: `formula: "(avg_intensity - 1) * 0.05"` (string, neexecutat) | Cod: `min(0.15, sqrt(x-1)*0.05)` (formula diferita!) | **COD** — Redis are formula veche, codul are noua |
| D3 | Override false_claims | Redis: `per_claim:5, max:20, threshold:3` | Cod DEFAULT: `per_claim:15, max:40, threshold:1` | **REDIS** (codul citeste din Redis, defaults doar fallback) |
| D4 | Disclosure impact | Redis: `explicit:0.3, partial:0.5, implied:0.7` | Cod: doar `undisclosed_ai: +15` override | **REDIS** pt disclosure_impact, **COD** pt override bonus |
**D3 e important**: Redis are `false_claims.per_claim=5` si `max=20`, dar codul DEFAULT are `per_claim=15` si `max=40`. Daca Redis e disponibil → se folosesc valorile mici din Redis. Daca Redis e indisponibil → fallback la valorile mari din cod. Comportament inconsistent.
---
## 2. PLAN DE ALINIERE — FAZE DE IMPLEMENTARE
### FAZA 0: Backup + Inventar (1 ora)
```
0.1 Export TOATE cheile Redis didi:config:* si didi:framework:* in JSON local
→ redis-cli --scan --pattern 'didi:*' | while read key; do echo "$key"; redis-cli -a redis123 GET "$key"; done > redis_backup.json
0.2 Verifica ca PG e accesibil si tabelele bos_parammgmt exista
→ psql → \dt bos_parammgmt.*
0.3 Lista randuri existente in component_config
→ SELECT * FROM bos_parammgmt.component_config ORDER BY component_code;
```
---
### FAZA 1: Redis → PG (persistenta, fara schimbari de comportament)
**Scop**: Tot ce e in Redis dar nu in PG → inserat in `component_config`.
**Impact**: Zero — agent-v3 citeste tot din Redis, sync-redis le va rescrie identic.
**Risc**: Zero — doar adaugam randuri in PG.
```
1.1 Script SQL: INSERT INTO component_config pentru fiecare cheie Redis din sectiunea GALBEN
- Citeste din Redis, formateaza ca INSERT
- 22 INSERT-uri (unele cu JSONB mare)
1.2 Testeaza: POST /api/sync-redis → verifica ca Redis e identic dupa sync
- Compara output sync cu backup-ul de la 0.1
1.3 Randuri noi in component_config:
| component_code | config_key | sursa |
|---|---|---|
| techniques | scoring_config | din Redis didi:config:techniques:v3:scoring_config |
| techniques | coupling_registry | din Redis |
| techniques | schemas_screening | din Redis |
| techniques | schemas_deep_per_dimension | din Redis |
| techniques | schemas_complete | din Redis |
| ai-tampered | scoring_config | din Redis |
| ai-tampered | categories_compact | din Redis |
| ai-tampered | indicators_hierarchy | din Redis |
| ai-tampered | quick_patterns | din Redis |
| ai-tampered | coupling_registry | din Redis |
| ai-tampered | schemas_screening | din Redis |
| ai-tampered | schemas_deep_per_category | din Redis |
| ai-tampered | schemas_complete | din Redis |
| ai-tampered | vision_models | din Redis |
| claims | scoring_config | din Redis |
| pipeline | verdict_config | din Redis |
| pipeline | component_config | din Redis |
| pipeline | session_config | din Redis |
| pipeline | external_apis | din Redis |
| vision | prompts_extraction | din Redis (sau in component_prompt) |
| vision | prompts_video_frames | din Redis |
| vision | prompts_ai_detection | din Redis |
Nota: Prompturile vision pot merge in component_prompt (component_code='vision', stage_code='extraction/video_frames/ai_detection')
Nota: verdict_explanation prompt merge in component_prompt (component_code='verdict', stage_code='explanation')
Nota: source-assessment available_models si verdict available_models merg in component_stage_assignment
```
---
### FAZA 2: Cod → Redis+PG (externalizare hardcodari)
**Scop**: Toate hardcodarile din sectiunea ROSU → adaugate in scoring_config (PG+Redis).
**Impact**: Zero daca valorile sunt identice cu ce era hardcodat.
**Risc**: Minim — codul citeste din Redis cu fallback la exact aceleasi valori.
```
2.1 Extinde techniques scoring_config in PG cu:
{
"count_scaler_divisor": 3,
"severe_threshold": 8,
"intensity_bonus_cap": 0.15,
"intensity_bonus_coefficient": 0.05,
"intensity_bonus_type": "sqrt" // sqrt | linear
}
Modifica techniques/executor.ts:
- Citeste count_scaler_divisor din scoringConfig (linia 614)
- Citeste severe_threshold din scoringConfig (linia 686)
- Citeste intensity params din scoringConfig (linia 635)
- Fallback la valorile actuale daca Redis e gol
2.2 Extinde ai-tampered scoring_config in PG cu:
{
"blend_weights": { "screening": 0.6, "deep": 0.4 },
"undisclosed_threshold": 50,
"quick_scores": { "hedging": 10, "self_reference": 30, "tool_mention": 15, "explicit_disclosure": 40, "partial_disclosure": 25 }
}
Modifica ai-tampered/executor.ts:
- Citeste blend_weights din scoringConfig (linia 705)
- Citeste undisclosed_threshold din scoringConfig (linia 725)
- Citeste quick_scores din scoringConfig (liniile 378-410)
2.3 Extinde claims scoring_config in PG cu:
{
"status_weights": { "VT": 1.0, "LT": 0.75, "UV": 0.5, "OP": 0.3, "LF": 0.25, "VF": 0.0 },
"all_unverified_credibility": 0.75,
"all_unverified_behavior": "fixed" // fixed | calculate_per_type
}
Modifica claims/executor.ts:
- Citeste status_weights din scoringConfig (linia 681)
- Citeste all_unverified din scoringConfig (linia 670-676)
2.4 Adauga source-assessment scoring_config (NOU) in PG:
{
"axis_weights": { "publication": 0.35, "domain": 0.25, "author": 0.25, "platform": 0.15 },
"verdict_thresholds": { "TRUSTED": 70, "NEUTRAL": 50, "SUSPICIOUS": 30 },
"domain_unavailable_default": 50
}
Modifica source-assessment/executor.ts:
- Citeste axis_weights din Redis (liniile 110-113)
- Citeste verdict_thresholds din Redis (liniile 296-299)
2.5 Extinde pipeline component_config in PG cu:
{
"video_track_weights": { "text": 0.40, "visual": 0.60 },
"video_min_text_chars": 200
}
Modifica component-worker.ts:
- Citeste video_track_weights din Redis
- Citeste video_min_text_chars din Redis
2.6 POST /api/sync-redis → toate valorile noi apar in Redis
2.7 Testeaza: ruleaza aceeasi analiza, scoruri identice (valorile sunt identice)
```
---
### FAZA 3: Fix divergente + aliniere defaults
**Scop**: Rezolva cele 4 divergente (D1-D4). Defaults in cod = identice cu Redis.
**Impact**: Mic — doar aliniaza valorile.
```
3.1 D2 (intensity formula): Actualizeaza Redis scoring_config cu formula noua:
"intensity_bonus_type": "sqrt",
"intensity_bonus_cap": 0.15,
"intensity_bonus_coefficient": 0.05
(sterge string-ul vechi "formula": "(avg_intensity - 1) * 0.05")
3.2 D3 (override false_claims): Decide valori canonice:
Propunere: per_claim=15, max=40, threshold=1 (valorile din cod, nu din Redis)
→ Actualizeaza Redis verdict_config.overrides.false_claims
→ Actualizeaza DEFAULT_VERDICT_CONFIG in verdict-calculator.ts sa fie identic
3.3 D4 (disclosure): disclosure_impact RAMINE in Redis (codul deja citeste de acolo)
Override undisclosed_ai RAMINE in verdict_config
Nu e divergenta — sunt mecanisme complementare
3.4 Actualizeaza TOATE DEFAULT_* in verdict-calculator.ts sa fie identice cu Redis:
- DEFAULT_VERDICTS ← sync cu PG verdict_category
- DEFAULT_WEIGHTS ← sync cu PG component_weight
- DEFAULT_VERDICT_CONFIG ← sync cu Redis verdict_config
```
---
### FAZA 4: Tabele PG noi + migratie
**Scop**: Adauga structuri PG noi pentru input profiles si claims weights.
```
4.1 Migration SQL:
-- Input type profiles
CREATE TABLE bos_parammgmt.input_type_profile (
profile_id SERIAL PRIMARY KEY,
profile_code VARCHAR(30) UNIQUE NOT NULL,
profile_name VARCHAR(100) NOT NULL,
description TEXT,
weight_techniques INTEGER NOT NULL DEFAULT 25,
weight_claims INTEGER NOT NULL DEFAULT 25,
weight_ai_tampered INTEGER NOT NULL DEFAULT 25,
weight_source INTEGER NOT NULL DEFAULT 25,
role_techniques VARCHAR(20) DEFAULT 'secondary',
role_claims VARCHAR(20) DEFAULT 'secondary',
role_ai_tampered VARCHAR(20) DEFAULT 'secondary',
role_source VARCHAR(20) DEFAULT 'secondary',
min_components INTEGER DEFAULT 2,
primary_components TEXT[] DEFAULT '{}',
required_any TEXT[] DEFAULT '{}',
missing_techniques VARCHAR(30) DEFAULT 'redistribute',
missing_claims VARCHAR(30) DEFAULT 'redistribute',
missing_ai_tampered VARCHAR(30) DEFAULT 'redistribute',
missing_source VARCHAR(30) DEFAULT 'redistribute',
confidence_config JSONB DEFAULT '{}',
ai_disclosure_multipliers JSONB DEFAULT '{"explicit":0.15,"partial":0.4,"implied":0.6,"none":1.0}',
is_active BOOLEAN DEFAULT true,
parameter_id INTEGER REFERENCES bos_parammgmt.parameter(parameter_id)
);
-- Override rules per profile
CREATE TABLE bos_parammgmt.profile_override_config (
override_id SERIAL PRIMARY KEY,
profile_code VARCHAR(30) REFERENCES bos_parammgmt.input_type_profile(profile_code),
override_code VARCHAR(40) NOT NULL,
enabled BOOLEAN DEFAULT true,
threshold INTEGER,
bonus_per_unit INTEGER,
bonus_fixed INTEGER,
max_bonus INTEGER,
description TEXT,
UNIQUE(profile_code, override_code)
);
-- Override cap per profile (in input_type_profile)
ALTER TABLE bos_parammgmt.input_type_profile ADD COLUMN override_cap INTEGER DEFAULT 50;
-- Unverified weight per claim type
ALTER TABLE bos_parammgmt.claim_type ADD COLUMN unverified_weight NUMERIC(3,2) DEFAULT 0.50;
-- Credibility weight per claim status
ALTER TABLE bos_parammgmt.claim ADD COLUMN credibility_weight NUMERIC(3,2) DEFAULT 0.50;
4.2 Seed data — 6 profiluri:
INSERT INTO input_type_profile (profile_code, profile_name, weight_techniques, weight_claims, weight_ai_tampered, weight_source, role_techniques, role_claims, role_ai_tampered, role_source, primary_components, required_any, min_components) VALUES
('text_no_url', 'Text simplu', 35, 35, 15, 15, 'primary', 'primary', 'secondary', 'secondary', '{techniques,claims}', '{techniques,claims}', 2),
('text_with_url', 'Text cu URL', 25, 25, 15, 35, 'secondary', 'secondary', 'secondary', 'primary', '{source}', '{techniques,claims,source}', 2),
('image', 'Imagine', 20, 15, 50, 15, 'secondary', 'secondary', 'primary', 'secondary', '{ai_tampered}', '{ai_tampered}', 1),
('audio', 'Audio', 35, 30, 20, 15, 'primary', 'secondary', 'secondary', 'secondary', '{techniques}', '{techniques}', 1),
('video', 'Video', 25, 20, 40, 15, 'secondary', 'secondary', 'primary', 'secondary', '{ai_tampered}', '{ai_tampered}', 1),
('url', 'URL articol', 25, 25, 15, 35, 'secondary', 'secondary', 'secondary', 'primary', '{source}', '{techniques,claims,source}', 2);
4.3 Seed data — 48 override rules (8 × 6 profiluri):
(vezi VERDICT_UI_SPEC.md Tab 2 pentru valorile per profil)
4.4 Seed data — claim_type unverified_weight:
UPDATE claim_type SET unverified_weight = 0.25 WHERE claim_code IN ('VF', 'SC');
UPDATE claim_type SET unverified_weight = 0.30 WHERE claim_code = 'QA';
UPDATE claim_type SET unverified_weight = 0.35 WHERE claim_code = 'EF';
UPDATE claim_type SET unverified_weight = 0.40 WHERE claim_code IN ('CC', 'RE');
-- PC, OP, VC raman 0.50 (default)
4.5 Seed data — claim status credibility_weight:
UPDATE claim SET credibility_weight = 1.00 WHERE claim_code = 'VT';
UPDATE claim SET credibility_weight = 0.75 WHERE claim_code = 'LT';
UPDATE claim SET credibility_weight = 0.50 WHERE claim_code = 'UV';
UPDATE claim SET credibility_weight = 0.30 WHERE claim_code = 'OP';
UPDATE claim SET credibility_weight = 0.25 WHERE claim_code = 'LF';
UPDATE claim SET credibility_weight = 0.00 WHERE claim_code = 'VF';
-- NV exclus din calcul (ramane NULL sau 0)
```
---
### FAZA 5: CRUD didiFramework (backend endpoints)
**Scop**: API-uri CRUD pentru noile tabele + extindere sync-redis.
```
5.1 Fisier nou: routes/input-profiles.ts
GET /api/input-profiles → lista toate profilurile
GET /api/input-profiles/:code → un profil cu override-uri
PUT /api/input-profiles/:code → update profil (ponderi, reguli)
GET /api/input-profiles/:code/overrides → override-uri per profil
PUT /api/input-profiles/:code/overrides → update override-uri
Nota: NU avem POST/DELETE — cele 6 profiluri sunt fixe, nu se adauga/sterg.
5.2 Fisier nou: routes/scoring-configs.ts (sau extinde providers.ts)
GET /api/scoring-configs → lista toate scoring_config per component
GET /api/scoring-configs/:component → scoring_config pentru o componenta
PUT /api/scoring-configs/:component → update scoring_config
GET /api/scoring-configs/disclosure-multipliers → multiplicatori disclosure
PUT /api/scoring-configs/disclosure-multipliers → update multiplicatori
Nota: Astea sunt wrapper-e peste component_config CRUD existent.
5.3 Extinde routes/claims.ts (deja exista):
- GET /api/claims/types → include unverified_weight in raspuns
- PUT /api/claims/types/:id → accepta unverified_weight
- GET /api/claims/status → include credibility_weight in raspuns
- PUT /api/claims/status/:id → accepta credibility_weight
5.4 Extinde routes/sync-redis.ts:
- fetchInputProfiles() → citeste din input_type_profile + profile_override_config
- Scrie la didi:config:pipeline:v1:input_profiles
- fetchClaimsExtended() → include unverified_weight si credibility_weight
- Include in didi:framework:claims sync
5.5 Extinde routes/sync-redis.ts:
- fetchScoringConfigs() → citeste din component_config pentru source-assessment
- Scrie la didi:config:source-assessment:v1:scoring_config (NOU)
```
---
### FAZA 6: Agent-v3 — verdict-calculator citeste profiles
**Scop**: verdict-calculator foloseste input profiles din Redis.
```
6.1 VerdictCalculator.loadFramework() extins:
- Citeste didi:config:pipeline:v1:input_profiles din Redis
- Fallback la DEFAULT_PROFILES (identice cu seed data din Faza 4)
6.2 VerdictCalculator.calculate() primeste input_type:
- Selecteaza profil pe baza input_type + has_url
- Foloseste ponderi din profil (nu din didi:framework:weights global)
- Aplica override-uri din profil (nu DEFAULT_VERDICT_CONFIG global)
- Aplica INCONCLUSIVE rules din profil
6.3 Component weights globale (didi:framework:weights.components) devin FALLBACK:
- Daca input_profiles nu exista in Redis → foloseste weights globale (backward compat)
- Daca input_profiles exista → ignora weights globale
6.4 Source Assessment override-uri:
- applyOverrides() primeste source_assessment in loc de domain
- Citeste verdict, is_blacklisted, red_flags din source_assessment
6.5 Claims scoring:
- claims/executor.ts citeste status_weights din Redis (in loc de hardcodat)
- claims/executor.ts citeste unverified_weight per tip din Redis (via claims framework data)
```
---
### FAZA 7: Admin Dashboard — UI verdict config
**Scop**: Interfata pentru editarea tuturor parametrilor.
```
7.1 Pagina noua: /admin/verdict-config
- Sau sub-pagina in LLM Components Config (depinde de layout)
7.2 Tab 1: Input Profiles (vezi VERDICT_UI_SPEC.md)
- Consuma: GET /api/input-profiles
- Editeaza: PUT /api/input-profiles/:code
- Slidere ponderi cu validare total=100
7.3 Tab 2: Override Rules (vezi VERDICT_UI_SPEC.md)
- Consuma: GET /api/input-profiles/:code/overrides
- Editeaza: PUT /api/input-profiles/:code/overrides
7.4 Tab 3: AI Disclosure
- Consuma: GET /api/scoring-configs/disclosure-multipliers
- Editeaza: PUT /api/scoring-configs/disclosure-multipliers
7.5 Tab 4: Claims Weights
- Consuma: GET /api/claims/types (cu unverified_weight) + GET /api/claims/status (cu credibility_weight)
- Editeaza: PUT existente
7.6 Tab 5-6: Verdict Categories + Risk/Severity
- Muta componentele existente din FrameworkDashboard (sau link catre)
7.7 Tab 7: Confidence Config
- Consuma: din input profile confidence_config JSONB
- Editeaza: ca parte din PUT /api/input-profiles/:code
7.8 Tab 8: Topic Multipliers — link/embed din FrameworkDashboard
7.9 Tab 9: LLM Reviewer
- Consuma: GET /api/scoring-configs/pipeline (verdict_config JSONB)
- Editeaza: PUT /api/scoring-configs/pipeline
7.10 Tab 10: Score Simulator
- Frontend JS pur — incarca configuratia din /api/input-profiles + /api/verdicts/all
- Calculeaza local, zero API calls per calcul
- Optiune "Compare with production" → POST la agent-v3 cu scoruri mock
```
---
### FAZA 8: Cleanup + Documentare
```
8.1 Elimina context (10%) din component_weight PG + formula
8.2 Elimina domain legacy din verdict-calculator (inlocuit de source_assessment)
8.3 Actualizeaza DEFAULT_* constants sa fie identice cu PG seed data
8.4 Actualizeaza INDEX.md agent-v3 cu noul flow
8.5 Actualizeaza VERDICT_BUSINESS_ANALYSIS.md ca "implementat"
```
---
## 3. VERIFICARE FINALA — DUPA TOATE FAZELE
### Fiecare parametru → exact un loc in PG, exact o cheie Redis, exact un UI element
| # | Parametru | PG | Redis | UI | Cod |
|---|---|---|---|---|---|
| 1 | Ponderi per input type | `input_type_profile.weight_*` | `input_profiles[code].weights` | Tab 1 slidere | citeste Redis, fallback defaults |
| 2 | INCONCLUSIVE rules | `input_type_profile.primary_components` etc | `input_profiles[code].inconclusive` | Tab 1 checkboxes | citeste Redis |
| 3 | Missing component handling | `input_type_profile.missing_*` | `input_profiles[code].missing` | Tab 1 dropdowns | citeste Redis |
| 4 | Override per profil | `profile_override_config` | `input_profiles[code].overrides` | Tab 2 toggles + inputs | citeste Redis |
| 5 | Override cap | `input_type_profile.override_cap` | `input_profiles[code].override_cap` | Tab 2 input | citeste Redis |
| 6 | Disclosure multipliers | `input_type_profile.ai_disclosure_multipliers` | `input_profiles[code].disclosure` | Tab 3 slidere | citeste Redis |
| 7 | Claims UV weight per tip | `claim_type.unverified_weight` | `didi:framework:claims.types[].unverified_weight` | Tab 4 inputs | citeste Redis |
| 8 | Claims status credibility weight | `claim.credibility_weight` | `didi:framework:claims.status[].credibility_weight` | Tab 4 inputs | citeste Redis |
| 9 | Verdict categories | `verdict_category` | `didi:framework:verdicts.categories` | Tab 5 table | citeste Redis |
| 10 | Risk mappings | `risk_mapping` | `didi:framework:verdicts.risk_mappings` | Tab 6 table | citeste Redis |
| 11 | Severity | `severity_assessment` | `didi:framework:verdicts.severity` | Tab 6 table | citeste Redis |
| 12 | Confidence config | `input_type_profile.confidence_config` | `input_profiles[code].confidence` | Tab 7 inputs | citeste Redis |
| 13 | Topic multipliers | `multiplier` | `didi:framework:weights.multipliers` | Tab 8 table | citeste Redis |
| 14 | LLM max adjustment | `component_config(pipeline, verdict_config)` | `verdict_config.llm_review.max_adjustment` | Tab 9 input | citeste Redis |
| 15 | LLM models + prompts | `component_stage_assignment + component_prompt` | `didi:config:verdict:*` | Tab 9 selects | citeste Redis |
| 16 | Techniques scoring params | `component_config(techniques, scoring_config)` | `didi:config:techniques:v3:scoring_config` | Tab 9 sau sectiune dedicata | citeste Redis |
| 17 | AI scoring params | `component_config(ai-tampered, scoring_config)` | `didi:config:ai-tampered:v1:scoring_config` | Tab 9 sau sectiune dedicata | citeste Redis |
| 18 | Claims scoring params | `component_config(claims, scoring_config)` | `didi:config:claims:v1:scoring_config` | Tab 9 sau sectiune dedicata | citeste Redis |
| 19 | Source scoring params | `component_config(source-assessment, scoring_config)` | `didi:config:source-assessment:v1:scoring_config` | Tab 9 sau sectiune dedicata | citeste Redis |
| 20 | Video track weights | `component_config(pipeline, component_config)` | `didi:config:pipeline:v1:component_config` | Tab 1 sub-sectiune sau Tab 9 | citeste Redis |
**20 parametri × 3 locuri (PG + Redis + UI) = complet aliniat. Zero hardcodari in cod.**
---
## 4. EFORT ESTIMAT PER FAZA
| Faza | Ce | Fisiere afectate | Complexitate |
|---|---|---|---|
| 0 | Backup + inventar | 0 (doar comenzi) | Mica |
| 1 | Redis → PG (22 INSERT-uri) | 1 SQL migration | Mica |
| 2 | Cod → Redis+PG (citire din Redis) | 5 executori + 1 worker | Medie |
| 3 | Fix divergente | 2 fisiere (verdict-calculator + Redis data) | Mica |
| 4 | Tabele PG noi + seed | 1 SQL migration | Medie |
| 5 | CRUD didiFramework | 2 fisiere noi + 2 extinse + sync-redis | Medie-mare |
| 6 | Agent-v3 verdict-calculator | 1 fisier (verdict-calculator.ts) + 1 (executor.ts pipeline) | Medie |
| 7 | Admin Dashboard UI | 1 pagina noua cu 10 tab-uri | Mare |
| 8 | Cleanup + docs | 3-4 fisiere | Mica |
**Dependente**:
- Faza 1 → independent
- Faza 2 → dupa Faza 1
- Faza 3 → dupa Faza 2
- Faza 4 → independent (poate in paralel cu 2-3)
- Faza 5 → dupa Faza 4
- Faza 6 → dupa Faza 5 (sau 3)
- Faza 7 → dupa Faza 5
- Faza 8 → dupa toate