fix(maria): codul de eroare decide acoperirea, nu cosinusul

O captura cu ORA-06550 / PLS-00906 primea raspunsul despre ORA-12541 (TNS no
listener) si nu pleca la suport. Cauza: doua erori Oracle diferite se scriu
aproape la fel ("[Oracle][ODBC][Ora]ORA-..."), asa ca chunk-ul gresit a iesit la
cosinus 0,736 — peste RANK_STRONG_COSINE, care scurtcircuita orice alta dovada.
Chunk-ul corect din dictionar exista, dar statea pe pozitia 4, in afara TOP_K:
OCR-ul unei ferestre intregi aduce zeci de tokeni de zgomot, iar BM25 ineca tocmai
codul.

- `rank.codes()` scoate codurile de oriunde din text, nu doar ca token intreg —
  OCR-ul le lipeste de ce e langa ("OraJORA-06550").
- `rank.by_codes()` e un al treilea clasament in fuziune: chunk-ul care poarta
  codul cerut urca peste cele care doar seamana. Acum iese primul.
- `rank.assess()`: cand intrebarea are coduri, decid doar ele. Niciun cod gasit =
  escaladare la suport, oricat de mare ar fi cosinusul.
- `consumer.search()` judeca acoperirea pe cosinusul chunk-urilor date chiar
  modelului, nu pe cel mai bun din tot indexul.

Calibrare 21/21 (cele 19 cazuri + captura reala + ORA-00600, cod care nu e in
documente si trebuie sa plece la suport). Teste: 79 pass.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01Q4uzvgm7AyJch5WH8QHRhY
This commit is contained in:
Claude Agent
2026-08-31 22:25:45 +00:00
parent 44763869ce
commit b7d75f05ee
5 changed files with 143 additions and 10 deletions

View File

@@ -351,6 +351,8 @@ lexicala e singura care le tine in joc.
Fuziunea da mereu un clasament, si la o intrebare complet straina. De aceea decizia
**„avem sau nu acoperire"** se ia separat, pe dovezi:
0. **intrebarea contine un cod de eroare** (`ORA-…`, `PLS-…`, `D406`) → decide
doar prezenta lui in chunk-uri, indiferent de cosinus;
1. cosinus ≥ `RANK_STRONG_COSINE` → raspundem;
2. cosinus < `RANK_WEAK_COSINE` → escaladam direct;
3. intre ele → raspundem doar daca cel putin `RANK_MIN_RARE_RATIO` din termenii
@@ -360,6 +362,18 @@ Fuziunea da mereu un clasament, si la o intrebare complet straina. De aceea deci
Fractiunea din pasul 3 nu e cosmetica: cu un singur termen gasit, „cum imi resetez
parola de la Windows" trecea drept acoperita fiindca „parola" apare in documente.
Pasul 0 e mai tare decat cosinusul pentru ca **doua erori Oracle diferite se scriu
aproape la fel**. O captura cu `ORA-06550 / PLS-00906` a primit cosinus 0,736 pe
chunk-ul despre `ORA-12541: TNS no listener` — peste pragul „sigur", deci Maria a
raspuns increzatoare cu alta eroare, fara sa escaladeze. Un cod e un identificator
exact: un document care nu-l pomeneste nu raspunde la el, oricat de bine ar semana
textul din jur. Codurile dau si un **al treilea clasament** (`rank.by_codes`), langa
cosinus si BM25 — la o captura de ecran, OCR-ul aduce zeci de tokeni de zgomot
(numele butoanelor din fereastra), iar BM25 singur ineca tocmai codul.
Codul se cauta oriunde in text, nu ca token intreg: OCR-ul lipeste `[Oracle][ODBC]`
de cod si scoate `OraJORA-06550`.
### Recalibrarea, cand se schimba documentele
Pragurile sunt masurate, nu alese din burta — si se **muta** cand se schimba