diff --git a/datasets/regrag-br/calibration/archive/20260726T185553Z/.judge-sealed.json b/datasets/regrag-br/calibration/archive/20260726T185553Z/.judge-sealed.json new file mode 100644 index 0000000..5438a4f --- /dev/null +++ b/datasets/regrag-br/calibration/archive/20260726T185553Z/.judge-sealed.json @@ -0,0 +1,81 @@ +{ + "run_id": "20260726T185553Z", + "judge_scores": { + "q199-graphrag-faithfulness": 1.0, + "q199-graphrag-answer_relevancy": 0.8347400935056873, + "q186-raptor-faithfulness": 1.0, + "q186-raptor-answer_relevancy": 0.85198688099497, + "q149-contextual-faithfulness": 1.0, + "q149-contextual-answer_relevancy": 0.8077504963301628, + "q149-raptor-faithfulness": 1.0, + "q149-raptor-answer_relevancy": 0.9460890444439526, + "q057-graphrag-faithfulness": 0.5, + "q057-graphrag-answer_relevancy": 0.0, + "q228-parent_child-faithfulness": 1.0, + "q228-parent_child-answer_relevancy": 0.6856243446899631, + "q188-graphrag-faithfulness": 1.0, + "q188-graphrag-answer_relevancy": 0.8336470959717595, + "q057-sac_contextual-faithfulness": 1.0, + "q057-sac_contextual-answer_relevancy": 0.8387442659907304, + "q129-hybrid_rrf-faithfulness": 1.0, + "q129-hybrid_rrf-answer_relevancy": 0.9124998734589621, + "q017-hybrid_rrf-faithfulness": 1.0, + "q017-hybrid_rrf-answer_relevancy": 0.7206135051759966, + "q017-hybrid_rrf-abstention": 1.0, + "q228-dense-faithfulness": 0.8571428571428571, + "q228-dense-answer_relevancy": 0.6870679326468675, + "q188-sac-faithfulness": 1.0, + "q188-sac-answer_relevancy": 0.8327270764043573, + "q162-sac-faithfulness": 1.0, + "q162-sac-answer_relevancy": 0.7749749305427135, + "q091-raptor-faithfulness": 1.0, + "q091-raptor-answer_relevancy": 0.9702814665461529, + "q091-raptor-abstention": 1.0, + "q147-reranked-faithfulness": 1.0, + "q147-reranked-answer_relevancy": 0.9533329415627246, + "q029-sac-faithfulness": 1.0, + "q029-sac-answer_relevancy": 0.8552758720163123, + "q086-contextual-faithfulness": 1.0, + "q086-contextual-answer_relevancy": 0.9940291063255439, + "q152-dense-faithfulness": 1.0, + "q152-dense-answer_relevancy": 0.8740158431078623, + "q053-contextual-faithfulness": 1.0, + "q053-contextual-answer_relevancy": 0.8949108045847701, + "q160-hybrid_rrf-faithfulness": 1.0, + "q160-hybrid_rrf-answer_relevancy": 0.7715785879645054, + "q011-reranked-faithfulness": 1.0, + "q011-reranked-answer_relevancy": 0.8502438689143164, + "q057-sac-faithfulness": 1.0, + "q057-sac-answer_relevancy": 0.9170167453202009, + "q129-contextual-faithfulness": 1.0, + "q129-contextual-answer_relevancy": 0.9112467674362174, + "q190-parent_child-faithfulness": 0.3333333333333333, + "q190-parent_child-answer_relevancy": 0.782537101530835, + "q190-parent_child-abstention": 1.0, + "q228-sac_contextual-faithfulness": 0.6666666666666666, + "q228-sac_contextual-answer_relevancy": 0.7052906182663375, + "q011-dense-faithfulness": 1.0, + "q011-dense-answer_relevancy": 0.7049204363155358, + "q129-raptor-faithfulness": 0.9230769230769231, + "q129-raptor-answer_relevancy": 0.9081927270706781, + "q017-raptor-faithfulness": 1.0, + "q017-raptor-answer_relevancy": 0.7381427478477991, + "q017-raptor-abstention": 1.0, + "q024-contextual-faithfulness": 1.0, + "q024-contextual-answer_relevancy": 0.9541869181118697, + "q193-raptor-faithfulness": 0.5, + "q193-raptor-answer_relevancy": 0.8704297565744411, + "q123-hybrid_rrf-faithfulness": 1.0, + "q123-hybrid_rrf-answer_relevancy": 0.8033356630688374, + "q205-sac_contextual-faithfulness": 1.0, + "q205-sac_contextual-answer_relevancy": 0.7516688618687585, + "q093-hybrid_rrf-faithfulness": 1.0, + "q093-hybrid_rrf-answer_relevancy": 0.7226008284858803, + "q187-graphrag-faithfulness": 1.0, + "q187-graphrag-answer_relevancy": 0.5653568713203554, + "q128-hybrid_rrf-faithfulness": 0.8571428571428571, + "q128-hybrid_rrf-answer_relevancy": 0.8334048457508137, + "q107-dense-faithfulness": 1.0, + "q107-dense-answer_relevancy": 0.931451117336013 + } +} \ No newline at end of file diff --git a/datasets/regrag-br/calibration/archive/20260726T185553Z/README.md b/datasets/regrag-br/calibration/archive/20260726T185553Z/README.md new file mode 100644 index 0000000..e22ba5b --- /dev/null +++ b/datasets/regrag-br/calibration/archive/20260726T185553Z/README.md @@ -0,0 +1,19 @@ +# Legacy calibration workspace + +This directory preserves the attempted calibration workspace derived from run +`20260726T185553Z` for audit history only. + +The run predates evidence schema v1 and does not contain the exact ordered +`judge_contexts` used by the Faithfulness judge. The worksheet reconstructs +cited source excerpts instead, so neither it nor the sealed scores are eligible +for judge calibration. Do not fill these labels or use this workspace to report +agreement. + +Original artifact SHA-256 values at archival time: + +- `worksheet.md`: `f7ff210d12f7265049cc4cd741d9b0a9f22e520eaefe04fcfb9fc0fbc234ffaa` +- `labels.json`: `b11eae0437820ac3578c8389a2ef63613b6fa17b45f1eddccb24abd00e5133ca` +- `.judge-sealed.json`: `af5ed04f740bf3799b0f55ebde36e68a54e3afa2dcb04a1ff134b1d0f621aaf9` + +A future eligible run must generate a fresh workspace directly under +`datasets/regrag-br/calibration/` with `build_calibration_worksheet.py`. diff --git a/datasets/regrag-br/calibration/archive/20260726T185553Z/labels.json b/datasets/regrag-br/calibration/archive/20260726T185553Z/labels.json new file mode 100644 index 0000000..6785ea6 --- /dev/null +++ b/datasets/regrag-br/calibration/archive/20260726T185553Z/labels.json @@ -0,0 +1,382 @@ +[ + { + "sample_id": "q199-graphrag-faithfulness", + "dimension": "faithfulness", + "human_score": null + }, + { + "sample_id": "q199-graphrag-answer_relevancy", + "dimension": "answer_relevancy", + "human_score": null + }, + { + "sample_id": "q186-raptor-faithfulness", + "dimension": "faithfulness", + "human_score": null + }, + { + "sample_id": "q186-raptor-answer_relevancy", + "dimension": "answer_relevancy", + "human_score": null + }, + { + "sample_id": "q149-contextual-faithfulness", + "dimension": "faithfulness", + "human_score": null + }, + { + "sample_id": "q149-contextual-answer_relevancy", + "dimension": "answer_relevancy", + "human_score": null + }, + { + "sample_id": "q149-raptor-faithfulness", + "dimension": "faithfulness", + "human_score": null + }, + { + "sample_id": "q149-raptor-answer_relevancy", + "dimension": "answer_relevancy", + "human_score": null + }, + { + "sample_id": "q057-graphrag-faithfulness", + "dimension": "faithfulness", + "human_score": null + }, + { + "sample_id": "q057-graphrag-answer_relevancy", + "dimension": "answer_relevancy", + "human_score": null + }, + { + "sample_id": "q228-parent_child-faithfulness", + "dimension": "faithfulness", + "human_score": null + }, + { + "sample_id": "q228-parent_child-answer_relevancy", + "dimension": "answer_relevancy", + "human_score": null + }, + { + "sample_id": "q188-graphrag-faithfulness", + "dimension": "faithfulness", + "human_score": null + }, + { + "sample_id": "q188-graphrag-answer_relevancy", + "dimension": "answer_relevancy", + "human_score": null + }, + { + "sample_id": "q057-sac_contextual-faithfulness", + "dimension": "faithfulness", + "human_score": null + }, + { + "sample_id": "q057-sac_contextual-answer_relevancy", + "dimension": "answer_relevancy", + "human_score": null + }, + { + "sample_id": "q129-hybrid_rrf-faithfulness", + "dimension": "faithfulness", + "human_score": null + }, + { + "sample_id": "q129-hybrid_rrf-answer_relevancy", + "dimension": "answer_relevancy", + "human_score": null + }, + { + "sample_id": "q017-hybrid_rrf-faithfulness", + "dimension": "faithfulness", + "human_score": null + }, + { + "sample_id": "q017-hybrid_rrf-answer_relevancy", + "dimension": "answer_relevancy", + "human_score": null + }, + { + "sample_id": "q017-hybrid_rrf-abstention", + "dimension": "abstention", + "human_score": null + }, + { + "sample_id": "q228-dense-faithfulness", + "dimension": "faithfulness", + "human_score": null + }, + { + "sample_id": "q228-dense-answer_relevancy", + "dimension": "answer_relevancy", + "human_score": null + }, + { + "sample_id": "q188-sac-faithfulness", + "dimension": "faithfulness", + "human_score": null + }, + { + "sample_id": "q188-sac-answer_relevancy", + "dimension": "answer_relevancy", + "human_score": null + }, + { + "sample_id": "q162-sac-faithfulness", + "dimension": "faithfulness", + "human_score": null + }, + { + "sample_id": "q162-sac-answer_relevancy", + "dimension": "answer_relevancy", + "human_score": null + }, + { + "sample_id": "q091-raptor-faithfulness", + "dimension": "faithfulness", + "human_score": null + }, + { + "sample_id": "q091-raptor-answer_relevancy", + "dimension": "answer_relevancy", + "human_score": null + }, + { + "sample_id": "q091-raptor-abstention", + "dimension": "abstention", + "human_score": null + }, + { + "sample_id": "q147-reranked-faithfulness", + "dimension": "faithfulness", + "human_score": null + }, + { + "sample_id": "q147-reranked-answer_relevancy", + "dimension": "answer_relevancy", + "human_score": null + }, + { + "sample_id": "q029-sac-faithfulness", + "dimension": "faithfulness", + "human_score": null + }, + { + "sample_id": "q029-sac-answer_relevancy", + "dimension": "answer_relevancy", + "human_score": null + }, + { + "sample_id": "q086-contextual-faithfulness", + "dimension": "faithfulness", + "human_score": null + }, + { + "sample_id": "q086-contextual-answer_relevancy", + "dimension": "answer_relevancy", + "human_score": null + }, + { + "sample_id": "q152-dense-faithfulness", + "dimension": "faithfulness", + "human_score": null + }, + { + "sample_id": "q152-dense-answer_relevancy", + "dimension": "answer_relevancy", + "human_score": null + }, + { + "sample_id": "q053-contextual-faithfulness", + "dimension": "faithfulness", + "human_score": null + }, + { + "sample_id": "q053-contextual-answer_relevancy", + "dimension": "answer_relevancy", + "human_score": null + }, + { + "sample_id": "q160-hybrid_rrf-faithfulness", + "dimension": "faithfulness", + "human_score": null + }, + { + "sample_id": "q160-hybrid_rrf-answer_relevancy", + "dimension": "answer_relevancy", + "human_score": null + }, + { + "sample_id": "q011-reranked-faithfulness", + "dimension": "faithfulness", + "human_score": null + }, + { + "sample_id": "q011-reranked-answer_relevancy", + "dimension": "answer_relevancy", + "human_score": null + }, + { + "sample_id": "q057-sac-faithfulness", + "dimension": "faithfulness", + "human_score": null + }, + { + "sample_id": "q057-sac-answer_relevancy", + "dimension": "answer_relevancy", + "human_score": null + }, + { + "sample_id": "q129-contextual-faithfulness", + "dimension": "faithfulness", + "human_score": null + }, + { + "sample_id": "q129-contextual-answer_relevancy", + "dimension": "answer_relevancy", + "human_score": null + }, + { + "sample_id": "q190-parent_child-faithfulness", + "dimension": "faithfulness", + "human_score": null + }, + { + "sample_id": "q190-parent_child-answer_relevancy", + "dimension": "answer_relevancy", + "human_score": null + }, + { + "sample_id": "q190-parent_child-abstention", + "dimension": "abstention", + "human_score": null + }, + { + "sample_id": "q228-sac_contextual-faithfulness", + "dimension": "faithfulness", + "human_score": null + }, + { + "sample_id": "q228-sac_contextual-answer_relevancy", + "dimension": "answer_relevancy", + "human_score": null + }, + { + "sample_id": "q011-dense-faithfulness", + "dimension": "faithfulness", + "human_score": null + }, + { + "sample_id": "q011-dense-answer_relevancy", + "dimension": "answer_relevancy", + "human_score": null + }, + { + "sample_id": "q129-raptor-faithfulness", + "dimension": "faithfulness", + "human_score": null + }, + { + "sample_id": "q129-raptor-answer_relevancy", + "dimension": "answer_relevancy", + "human_score": null + }, + { + "sample_id": "q017-raptor-faithfulness", + "dimension": "faithfulness", + "human_score": null + }, + { + "sample_id": "q017-raptor-answer_relevancy", + "dimension": "answer_relevancy", + "human_score": null + }, + { + "sample_id": "q017-raptor-abstention", + "dimension": "abstention", + "human_score": null + }, + { + "sample_id": "q024-contextual-faithfulness", + "dimension": "faithfulness", + "human_score": null + }, + { + "sample_id": "q024-contextual-answer_relevancy", + "dimension": "answer_relevancy", + "human_score": null + }, + { + "sample_id": "q193-raptor-faithfulness", + "dimension": "faithfulness", + "human_score": null + }, + { + "sample_id": "q193-raptor-answer_relevancy", + "dimension": "answer_relevancy", + "human_score": null + }, + { + "sample_id": "q123-hybrid_rrf-faithfulness", + "dimension": "faithfulness", + "human_score": null + }, + { + "sample_id": "q123-hybrid_rrf-answer_relevancy", + "dimension": "answer_relevancy", + "human_score": null + }, + { + "sample_id": "q205-sac_contextual-faithfulness", + "dimension": "faithfulness", + "human_score": null + }, + { + "sample_id": "q205-sac_contextual-answer_relevancy", + "dimension": "answer_relevancy", + "human_score": null + }, + { + "sample_id": "q093-hybrid_rrf-faithfulness", + "dimension": "faithfulness", + "human_score": null + }, + { + "sample_id": "q093-hybrid_rrf-answer_relevancy", + "dimension": "answer_relevancy", + "human_score": null + }, + { + "sample_id": "q187-graphrag-faithfulness", + "dimension": "faithfulness", + "human_score": null + }, + { + "sample_id": "q187-graphrag-answer_relevancy", + "dimension": "answer_relevancy", + "human_score": null + }, + { + "sample_id": "q128-hybrid_rrf-faithfulness", + "dimension": "faithfulness", + "human_score": null + }, + { + "sample_id": "q128-hybrid_rrf-answer_relevancy", + "dimension": "answer_relevancy", + "human_score": null + }, + { + "sample_id": "q107-dense-faithfulness", + "dimension": "faithfulness", + "human_score": null + }, + { + "sample_id": "q107-dense-answer_relevancy", + "dimension": "answer_relevancy", + "human_score": null + } +] \ No newline at end of file diff --git a/datasets/regrag-br/calibration/archive/20260726T185553Z/worksheet.md b/datasets/regrag-br/calibration/archive/20260726T185553Z/worksheet.md new file mode 100644 index 0000000..b6e2d01 --- /dev/null +++ b/datasets/regrag-br/calibration/archive/20260726T185553Z/worksheet.md @@ -0,0 +1,2142 @@ +# Judge calibration worksheet + +> [!WARNING] +> **Legacy evidence — do not label this worksheet.** Run `20260726T185553Z` +> predates exact `judge_contexts` persistence. Its cited-source excerpts are +> not the ordered contexts evaluated by RAGAS, so this artifact cannot produce +> a valid judge-vs-human calibration report. Preserve it for audit only and +> rerun the benchmark before rebuilding the calibration workspace. + +Run `20260726T185553Z` · 36 samples · selection seed `regrag-br-calibration-v1` + +Score each sample in `labels.json`. The judge's own scores are sealed +in `.judge-sealed.json` and must stay closed until you finish - seeing +them first turns the exercise into agreement-by-anchoring. + +## Scale + +Use `0.0`, `0.5`, or `1.0`. `_to_ordinal` bins continuous judge scores +into these same three categories, so intermediate values buy nothing. + +**Faithfulness** - is every assertion in the answer supported by the +cited authoritative text? + +- `1.0` fully supported; no claim goes beyond the cited articles +- `0.5` mostly supported, but at least one claim overreaches, softens an + exception, drops a condition, or cites an article that does not carry it +- `0.0` a central assertion contradicts the text or has no support + +**Answer Relevancy** - does the answer address what was asked? + +- `1.0` answers the question directly and completely +- `0.5` partially answers, or answers a related but different question +- `0.0` does not address the question + +For an **unanswerable** question, a correct abstention scores `1.0` on +both; a confident answer built from unrelated retrieved text scores `0.0`. + +## Watch for (ADR-0018's own list) + +Normative negation (`não constitui`, `veda`), exceptions (`salvo`, +`ressalvado`), cross-references (`na forma do art. X`), numerical claims +(deadlines, percentages, thresholds), and partial support - the answer is +true but the cited article is not where it says so. These are exactly the +cases where a general-purpose judge is expected to slip. + +--- + +## 1. `q199-graphrag` + +- Class: **exact_factual** +- Strategy: `graphrag` + +### Question + +O que deve constar do Acordo de Supervisão quanto à confissão do signatário, segundo o art. 101, inciso V da ICVM 607/2019? + +### Reference answer (golden set) + +Deve constar confissão expressa da participação do signatário do Acordo de Supervisão no ilícito (art. 101, V). + +### Cited authoritative text + +**`ICVM-607/2019::art-101::inc-v`** + +> V – confissão expressa da participação do signatário do Acordo de Supervisão no ilícito; + +### Generated answer + +Segundo o art. 101, inciso V da Instrução CVM nº 607/2019, o Acordo de Supervisão deve conter a confissão expressa da participação do signatário no ilícito [ICVM-607/2019::art-101::inc-v]. + +### Your scores + +| `q199-graphrag` | 0.0 / 0.5 / 1.0 | notes | +| --- | --- | --- | +| faithfulness | | | +| answer_relevancy | | | + +--- + +## 2. `q186-raptor` + +- Class: **exact_factual** +- Strategy: `raptor` + +### Question + +O proponente pode retificar ou desistir da proposta de Acordo de Supervisão, segundo o art. 95 da ICVM 607/2019? + +### Reference answer (golden set) + +Sim, o proponente poderá retificar ou desistir da proposta a qualquer momento antes da assinatura do respectivo instrumento (art. 95). + +### Cited authoritative text + +**`ICVM-607/2019::art-95`** + +> Art. 95. O proponente poderá retificar ou desistir da proposta de Acordo de Supervisão a +> qualquer momento antes da assinatura do respectivo instrumento. + +### Generated answer + +Sim, o proponente pode retificar ou desistir da proposta de Acordo de Supervisão a qualquer momento antes da assinatura do respectivo instrumento [ICVM-607/2019::art-95]. + +### Your scores + +| `q186-raptor` | 0.0 / 0.5 / 1.0 | notes | +| --- | --- | --- | +| faithfulness | | | +| answer_relevancy | | | + +--- + +## 3. `q149-contextual` + +- Class: **numeric_tabular** +- Strategy: `contextual` + +### Question + +Qual é um dos valores máximos para a penalidade de multa, segundo o art. 61, inciso I da ICVM 607/2019? + +### Reference answer (golden set) + +A multa não deverá exceder R$ 50.000.000,00 (cinquenta milhões de reais), entre outros critérios possíveis (art. 61, I). + +### Cited authoritative text + +**`ICVM-607/2019::art-61::inc-i`** + +> I – R$ 50.000.000,00 (cinquenta milhões de reais); + +### Generated answer + +De acordo com o art. 61, inciso I, da Instrução CVM nº 607/2019, um dos valores máximos para a penalidade de multa é de R$ 50.000.000,00 (cinquenta milhões de reais) [ICVM-607/2019::art-61::inc-i]. + +### Your scores + +| `q149-contextual` | 0.0 / 0.5 / 1.0 | notes | +| --- | --- | --- | +| faithfulness | | | +| answer_relevancy | | | + +--- + +## 4. `q149-raptor` + +- Class: **numeric_tabular** +- Strategy: `raptor` + +### Question + +Qual é um dos valores máximos para a penalidade de multa, segundo o art. 61, inciso I da ICVM 607/2019? + +### Reference answer (golden set) + +A multa não deverá exceder R$ 50.000.000,00 (cinquenta milhões de reais), entre outros critérios possíveis (art. 61, I). + +### Cited authoritative text + +**`ICVM-607/2019::art-61::inc-i`** + +> I – R$ 50.000.000,00 (cinquenta milhões de reais); + +### Generated answer + +Segundo o art. 61, inciso I, da Instrução CVM nº 607/2019, um dos valores máximos para a penalidade de multa é de R$ 50.000.000,00 (cinquenta milhões de reais) [ICVM-607/2019::art-61::inc-i]. + +### Your scores + +| `q149-raptor` | 0.0 / 0.5 / 1.0 | notes | +| --- | --- | --- | +| faithfulness | | | +| answer_relevancy | | | + +--- + +## 5. `q057-graphrag` + +- Class: **semantic** +- Strategy: `graphrag` + +### Question + +Quais informações sobre o tratamento de dados devem ser disponibilizadas ao titular de forma clara e ostensiva, segundo o art. 9º da LGPD? + +### Reference answer (golden set) + +Devem ser disponibilizadas informações sobre a finalidade específica do tratamento, a forma e duração do tratamento, a identificação do controlador, informações de contato, uso compartilhado de dados, responsabilidades dos agentes, e os direitos do titular (art. 9º, caput). + +### Cited authoritative text + +_The answer cites nothing._ + +### Generated answer + +O contexto fornecido não contém o artigo 9º da Lei Geral de Proteção de Dados (LGPD), portanto, não é possível responder à sua pergunta com base nas informações disponibilizadas. + +### Your scores + +| `q057-graphrag` | 0.0 / 0.5 / 1.0 | notes | +| --- | --- | --- | +| faithfulness | | | +| answer_relevancy | | | + +--- + +## 6. `q228-parent_child` + +- Class: **multi_hop** +- Strategy: `parent_child` + +### Question + +Como o adiamento de sessão de julgamento por motivo de força maior (art. 50, § 4º) se relaciona com a exigência de presença mínima de membros do Colegiado (art. 50, caput) na ICVM 607/2019? + +### Reference answer (golden set) + +O art. 50, caput, exige a presença de no mínimo 3 membros do Colegiado para a sessão se realizar; se isso não ocorrer por motivo de força maior, o art. 50, § 4º, permite que a sessão seja transferida para o primeiro dia útil seguinte, sem necessidade de nova convocação. + +### Cited authoritative text + +**`ICVM-607/2019::art-50`** + +> Art. 50. A sessão será presidida pelo Presidente da CVM ou, na sua ausência ou +> impedimento, por seu substituto eventual e somente será realizada com a presença de no mínimo 3 +> (três) membros do Colegiado. +> § 1º A participação dos membros do Colegiado nas sessões de julgamento poderá ocorrer por +> videoconferência. +> COMISSÃO DE VALORES MOBILIÁRIOS +> Rua Sete de Setembro, 111/2-5º e 23-34º Andares, Centro, Rio de Janeiro/RJ – CEP: 20050-901 – Brasil - Tel.: (21) 3554-8686 +> Rua Cincinato Braga, 340/2º, 3º e 4º Andares, Bela Vista, São Paulo/ SP – CEP: 01333-010 – Brasil - Tel.: (11) 2146-2000 +> SCN Q.02 – Bl. A – Ed. Corporate Financial Center, S.404/4º Andar, Brasília/DF – CEP: 70712-900 – Brasil -Tel.: (61) 3327-2030/2031 +> +> INSTRUÇÃO CVM Nº 607, DE 17 DE JUNHO DE 2019 +> 21 +> § 2º No julgamento dos processos administrativos sancionadores em que não comparecer +> nenhum acusado ou nenhum de seus respectivos procuradores constituídos nos autos, a sessão +> poderá realizar-se por meio eletrônico. +> § 3º Considerando o andamento dos trabalhos da sessão, fica facultado ao Presidente +> suspendê-la e reiniciá-la no dia útil subsequente, independente de nova convocação e publicação. +> § 4º A sessão que não se realizar, por motivo de força maior, poderá ser transferida para o +> primeiro dia útil seguinte, na hora anteriormente marcada, independentemente de nova convocação +> e publicação. + +**`ICVM-607/2019::art-50::par-4`** + +> § 4º A sessão que não se realizar, por motivo de força maior, poderá ser transferida para o +> primeiro dia útil seguinte, na hora anteriormente marcada, independentemente de nova convocação +> e publicação. + +### Generated answer + +A Instrução CVM nº 607/2019 estabelece que a sessão de julgamento somente será realizada com a presença de, no mínimo, 3 (três) membros do Colegiado [ICVM-607/2019::art-50]. + +Caso a sessão não ocorra por motivo de força maior, ela poderá ser transferida para o primeiro dia útil seguinte, no mesmo horário anteriormente marcado, sem a necessidade de nova convocação ou publicação [ICVM-607/2019::art-50::par-4]. Embora o texto não explicite a relação direta entre o quórum e o adiamento, a regra de transferência mantém a sessão agendada, submetendo-a, na nova data, à exigência geral de presença mínima de 3 (três) membros para a sua efetiva realização [ICVM-607/2019::art-50]. + +### Your scores + +| `q228-parent_child` | 0.0 / 0.5 / 1.0 | notes | +| --- | --- | --- | +| faithfulness | | | +| answer_relevancy | | | + +--- + +## 7. `q188-graphrag` + +- Class: **section_comparative** +- Strategy: `graphrag` + +### Question + +Compare os efeitos do termo de compromisso (art. 88) com os efeitos do Acordo de Supervisão (art. 92) na ICVM 607/2019. + +### Reference answer (golden set) + +O termo de compromisso (art. 88) suspende o processo ou impede sua instauração, sem admissão de culpa. Já o Acordo de Supervisão (art. 92) pressupõe confissão da infração pelo investigado, em troca de extinção da ação punitiva ou redução de 1/3 a 2/3 da penalidade, mediante cooperação efetiva na apuração dos fatos. + +### Cited authoritative text + +**`ICVM-607/2019::art-88::inc-i`** + +> I – a suspensão do processo administrativo em curso, pelo prazo estipulado para o +> cumprimento do compromisso; ou + +**`ICVM-607/2019::art-88::inc-ii`** + +> II – a não instauração de processo administrativo sancionador, nos casos em que a proposta +> for apresentada ainda em fase de apuração ou antes desta. +> COMISSÃO DE VALORES MOBILIÁRIOS +> Rua Sete de Setembro, 111/2-5º e 23-34º Andares, Centro, Rio de Janeiro/RJ – CEP: 20050-901 – Brasil - Tel.: (21) 3554-8686 +> Rua Cincinato Braga, 340/2º, 3º e 4º Andares, Bela Vista, São Paulo/ SP – CEP: 01333-010 – Brasil - Tel.: (11) 2146-2000 +> SCN Q.02 – Bl. A – Ed. Corporate Financial Center, S.404/4º Andar, Brasília/DF – CEP: 70712-900 – Brasil -Tel.: (61) 3327-2030/2031 +> +> INSTRUÇÃO CVM Nº 607, DE 17 DE JUNHO DE 2019 +> 35 + +**`ICVM-607/2019::art-92`** + +> Art. 92. A CVM poderá celebrar acordo administrativo em processo de supervisão (“Acordo +> de Supervisão”) com pessoas naturais ou jurídicas que confessarem a prática de infração às normas +> legais ou regulamentares cujo cumprimento lhe caiba fiscalizar, com extinção de sua ação punitiva +> ou redução de 1/3 (um terço) a 2/3 (dois terços) da penalidade aplicável, mediante efetiva, plena e +> permanente cooperação para a apuração dos fatos, da qual resulte utilidade para o processo, em +> especial: +> I – a identificação dos demais envolvidos na prática da infração, quando couber; e +> COMISSÃO DE VALORES MOBILIÁRIOS +> Rua Sete de Setembro, 111/2-5º e 23-34º Andares, Centro, Rio de Janeiro/RJ – CEP: 20050-901 – Brasil - Tel.: (21) 3554-8686 +> Rua Cincinato Braga, 340/2º, 3º e 4º Andares, Bela Vista, São Paulo/ SP – CEP: 01333-010 – Brasil - Tel.: (11) 2146-2000 +> SCN Q.02 – Bl. A – Ed. Corporate Financial Center, S.404/4º Andar, Brasília/DF – CEP: 70712-900 – Brasil -Tel.: (61) 3327-2030/2031 +> +> INSTRUÇÃO CVM Nº 607, DE 17 DE JUNHO DE 2019 +> 36 +> II – a obtenção de informações e de documentos que comprovem a infração noticiada ou sob +> apuração. + +**`ICVM-607/2019::art-101::par-3`** + +> § 3º A celebração do Acordo de Supervisão pela CVM suspenderá o prazo prescricional no +> âmbito administrativo com relação ao seu signatário. + +### Generated answer + +Com base na Instrução CVM nº 607/2019, os efeitos dos dois institutos são distintos: + +**Termo de Compromisso (art. 88):** +A celebração do termo de compromisso tem como efeitos: + +- A suspensão de processo administrativo em curso, pelo prazo estipulado para o cumprimento do compromisso [ICVM-607/2019::art-88::inc-i]; ou +- A não instauração de processo administrativo sancionador, caso a proposta seja apresentada em fase de apuração ou antes dela [ICVM-607/2019::art-88::inc-ii]. + +**Acordo de Supervisão (art. 92):** +A celebração do Acordo de Supervisão, que exige a confissão da prática de infração e cooperação efetiva, plena e permanente, resulta em: + +- Extinção da ação punitiva da CVM; ou +- Redução de 1/3 (um terço) a 2/3 (dois terços) da penalidade aplicável [ICVM-607/2019::art-92]. + +Adicionalmente, a celebração do Acordo de Supervisão produz efeitos específicos não mencionados para o termo de compromisso no contexto fornecido, tais como a suspensão do prazo prescricional no âmbito administrativo em relação ao signatário [ICVM-607/2019::art-101::par-3]. + +### Your scores + +| `q188-graphrag` | 0.0 / 0.5 / 1.0 | notes | +| --- | --- | --- | +| faithfulness | | | +| answer_relevancy | | | + +--- + +## 8. `q057-sac_contextual` + +- Class: **semantic** +- Strategy: `sac_contextual` + +### Question + +Quais informações sobre o tratamento de dados devem ser disponibilizadas ao titular de forma clara e ostensiva, segundo o art. 9º da LGPD? + +### Reference answer (golden set) + +Devem ser disponibilizadas informações sobre a finalidade específica do tratamento, a forma e duração do tratamento, a identificação do controlador, informações de contato, uso compartilhado de dados, responsabilidades dos agentes, e os direitos do titular (art. 9º, caput). + +### Cited authoritative text + +**`LEI-13709/2018::art-9::inc-i`** + +> I - finalidade específica do tratamento; + +**`LEI-13709/2018::art-9::inc-ii`** + +> II - forma e duração do tratamento, observados os segredos comercial e industrial; + +**`LEI-13709/2018::art-9::inc-iii`** + +> III - identificação do controlador; + +**`LEI-13709/2018::art-9::inc-iv`** + +> IV - informações de contato do controlador; + +**`LEI-13709/2018::art-9::inc-v`** + +> V - informações acerca do uso compartilhado de dados pelo controlador e a finalidade; + +**`LEI-13709/2018::art-9::inc-vi`** + +> VI - responsabilidades dos agentes que realizarão o tratamento; e + +**`LEI-13709/2018::art-9::inc-vii`** + +> VII - direitos do titular, com menção explícita aos direitos contidos no art. 18 desta Lei. + +### Generated answer + +Segundo o art. 9º da LGPD, o titular tem direito ao acesso facilitado a informações sobre o tratamento de seus dados, que devem ser disponibilizadas de forma clara, adequada e ostensiva, incluindo: + +- A finalidade específica do tratamento [LEI-13709/2018::art-9::inc-i]; +- A forma e a duração do tratamento, observados os segredos comercial e industrial [LEI-13709/2018::art-9::inc-ii]; +- A identificação do controlador [LEI-13709/2018::art-9::inc-iii]; +- As informações de contato do controlador [LEI-13709/2018::art-9::inc-iv]; +- Informações acerca do uso compartilhado de dados pelo controlador e a finalidade desse compartilhamento [LEI-13709/2018::art-9::inc-v]; +- As responsabilidades dos agentes que realizarão o tratamento [LEI-13709/2018::art-9::inc-vi]; +- Os direitos do titular, com menção explícita aos direitos contidos no art. 18 da referida Lei [LEI-13709/2018::art-9::inc-vii]. + +### Your scores + +| `q057-sac_contextual` | 0.0 / 0.5 / 1.0 | notes | +| --- | --- | --- | +| faithfulness | | | +| answer_relevancy | | | + +--- + +## 9. `q129-hybrid_rrf` + +- Class: **global** +- Strategy: `hybrid_rrf` + +### Question + +De modo geral, quais são as etapas do rito processual sancionador estabelecido pela ICVM 607/2019 até a apresentação de defesa? + +### Reference answer (golden set) + +O processo se inicia com a lavratura de termo de acusação (art. 6º), podendo ser precedido de inquérito administrativo (art. 8º); instaura-se com a citação dos acusados (art. 21); o acusado apresenta defesa em até 30 dias (art. 29); e após a defesa, é designado Relator por sorteio (art. 31). + +### Cited authoritative text + +**`ICVM-607/2019::art-4`** + +> Art. 4° Considerando as informações obtidas na investigação das infrações administrativas, +> as superintendências poderão: +> I – deixar de lavrar termo de acusação nos casos em que: +> a) concluir pela inexistência de irregularidades ou pela extinção da punibilidade; ou +> b) restar demonstrada a pouca relevância da conduta, a baixa expressividade da ameaça ou da +> lesão ao bem jurídico tutelado e a possibilidade de utilização de outros instrumentos ou medidas de +> supervisão que julgarem mais efetivos; +> II – lavrar termo de acusação, nos termos do art. 6º; ou +> III – propor inquérito administrativo destinado a aprofundar a coleta de elementos adicionais à +> verificação da autoria e da materialidade da infração, nos temos do art. 8º. +> § 1º Na avaliação da relevância da conduta ou da expressividade da ameaça ou lesão ao bem +> jurídico, poderão ser utilizados os seguintes parâmetros, dentre outros: +> I – o grau de reprovabilidade ou da repercussão da conduta; +> II – a expressividade de valores relacionados à conduta; +> III – a expressividade de prejuízos causados a investidores e demais participantes do mercado; +> IV – o impacto da conduta na credibilidade do mercado de capitais; +> V – os antecedentes das pessoas envolvidas; +> COMISSÃO DE VALORES MOBILIÁRIOS +> Rua Sete de Setembro, 111/2-5º e 23-34º Andares, Centro, Rio de Janeiro/RJ – CEP: 20050-901 – Brasil - Tel.: (21) 3554-8686 +> Rua Cincinato Braga, 340/2º, 3º e 4º Andares, Bela Vista, São Paulo/ SP – CEP: 01333-010 – Brasil - Tel.: (11) 2146-2000 +> SCN Q.02 – Bl. A – Ed. Corporate Financial Center, S.404/4º Andar, Brasília/DF – CEP: 70712-900 – Brasil -Tel.: (61) 3327-2030/2031 +> +> INSTRUÇÃO CVM Nº 607, DE 17 DE JUNHO DE 2019 +> 3 +> VI – a boa-fé das pessoas envolvidas; +> VII – a regularização da suposta infração pelo administrado; e +> VIII – o ressarcimento dos investidores lesados. +> § 2º Consideram-se instrumentos e medidas de supervisão, para os fins deste artigo, a +> expedição de ofício de alerta, a atuação prévia e coordenada de instituição autorreguladora, entre +> outros. +> § 3º A expedição de ofício de alerta à pessoa natural ou jurídica supervisionada, nos termos +> do § 2º, deverá indicar claramente o desvio de conduta verificado e assinalar prazo razoável para a +> devida correção, se aplicável. +> § 4º Somente caberá recurso da decisão contida no inciso I, do caput, se ausente a +> fundamentação ou caso esteja em desacordo com posicionamento prevalecente no Colegiado. +> § 5º No recurso de que trata o § 4º, incumbe ao recorrente demonstrar expressamente a +> ausência de fundamentação ou a dissonância em relação ao posicionamento prevalecente do +> Colegiado. +> § 6º A decisão do Colegiado nas hipóteses de deferimento do recurso previsto no § 4º, não +> determinará a instauração de processo administrativo sancionador, cabendo à superintendência, em +> cada caso, a eventual complementação da fundamentação ou revisão das circunstâncias de fato de +> acordo com o posicionamento prevalecente no Colegiado ou com nova orientação sobre a matéria +> por ele emitida, nos termos do § 8º do art. 4º. +> § 7º A norma que dispõe sobre o recurso ao Colegiado de decisões proferidas pelos +> superintendentes da CVM aplica-se aos recursos previstos no § 4º exclusivamente no que diz +> respeito aos prazos e procedimentos. +> § 8º O Colegiado poderá, de ofício ou a pedido da superintendência, conhecer de tema objeto +> de recurso sob a forma de consulta, hipótese na qual deverá manifestar-se sobre a matéria. +> COMISSÃO DE VALORES MOBILIÁRIOS +> Rua Sete de Setembro, 111/2-5º e 23-34º Andares, Centro, Rio de Janeiro/RJ – CEP: 20050-901 – Brasil - Tel.: (21) 3554-8686 +> Rua Cincinato Braga, 340/2º, 3º e 4º Andares, Bela Vista, São Paulo/ SP – CEP: 01333-010 – Brasil - Tel.: (11) 2146-2000 +> SCN Q.02 – Bl. A – Ed. Corporate Financial Center, S.404/4º Andar, Brasília/DF – CEP: 70712-900 – Brasil -Tel.: (61) 3327-2030/2031 +> +> INSTRUÇÃO CVM Nº 607, DE 17 DE JUNHO DE 2019 +> 4 + +**`ICVM-607/2019::art-7`** + +> Art. 7º. Antes da citação dos acusados para apresentação de defesa, a PFE emitirá parecer +> sobre o termo de acusação, no prazo de 30 (trinta) dias contados da data de recebimento do termo +> de acusação, com o seguinte escopo: +> I – exame do cumprimento do art. 5º; +> II – análise objetiva da observância dos requisitos do art. 6º; e +> III – exame da adequação do rito adotado para o processo administrativo sancionador. +> § 1° Considerando o parecer da PFE, a superintendência tomará as providências que +> considerar cabíveis, podendo, inclusive, arquivar o processo, adequar o rito processual ou realizar +> eventuais ajustes no termo de acusação. +> § 2° O superintendente deverá justificar a não adoção de eventuais providências +> recomendadas pelo parecer. +> § 3º O parecer da PFE não será obrigatório nos processos administrativos sancionadores +> submetidos ao rito simplificado de que trata o art. 73 desta Instrução. +> § 4º Sem prejuízo da emissão do parecer de que trata este artigo, as superintendências +> poderão solicitar assessoramento jurídico direto à PFE ainda na fase de instrução. +> COMISSÃO DE VALORES MOBILIÁRIOS +> Rua Sete de Setembro, 111/2-5º e 23-34º Andares, Centro, Rio de Janeiro/RJ – CEP: 20050-901 – Brasil - Tel.: (21) 3554-8686 +> Rua Cincinato Braga, 340/2º, 3º e 4º Andares, Bela Vista, São Paulo/ SP – CEP: 01333-010 – Brasil - Tel.: (11) 2146-2000 +> SCN Q.02 – Bl. A – Ed. Corporate Financial Center, S.404/4º Andar, Brasília/DF – CEP: 70712-900 – Brasil -Tel.: (61) 3327-2030/2031 +> +> INSTRUÇÃO CVM Nº 607, DE 17 DE JUNHO DE 2019 +> 6 + +**`ICVM-607/2019::art-7::par-3`** + +> § 3º O parecer da PFE não será obrigatório nos processos administrativos sancionadores +> submetidos ao rito simplificado de que trata o art. 73 desta Instrução. + +**`ICVM-607/2019::art-7::par-1`** + +> § 1° Considerando o parecer da PFE, a superintendência tomará as providências que +> considerar cabíveis, podendo, inclusive, arquivar o processo, adequar o rito processual ou realizar +> eventuais ajustes no termo de acusação. + +**`ICVM-607/2019::art-21`** + +> Art. 21. Considera-se instaurado o processo administrativo sancionador com a citação dos +> acusados para apresentação de defesa. +> § 1º A citação conterá: +> I – a identificação do acusado; +> II – a indicação dos fatos imputados ao acusado; +> III – a finalidade da citação; +> IV – o prazo para a apresentação de defesa; +> V – a informação da continuidade do processo, independentemente de seu comparecimento; +> VI – o dever do acusado, ou de procurador por ele constituído, de se cadastrar no sistema de +> processo eletrônico existente na página da CVM na rede mundial de computadores para fins de +> acesso aos autos e posterior acompanhamento do andamento do processo; e +> VII – o aviso de que o acusado poderá propor a celebração de termo de compromisso, em +> conformidade com o disposto no Capítulo IV desta Instrução. +> COMISSÃO DE VALORES MOBILIÁRIOS +> Rua Sete de Setembro, 111/2-5º e 23-34º Andares, Centro, Rio de Janeiro/RJ – CEP: 20050-901 – Brasil - Tel.: (21) 3554-8686 +> Rua Cincinato Braga, 340/2º, 3º e 4º Andares, Bela Vista, São Paulo/ SP – CEP: 01333-010 – Brasil - Tel.: (11) 2146-2000 +> SCN Q.02 – Bl. A – Ed. Corporate Financial Center, S.404/4º Andar, Brasília/DF – CEP: 70712-900 – Brasil -Tel.: (61) 3327-2030/2031 +> +> INSTRUÇÃO CVM Nº 607, DE 17 DE JUNHO DE 2019 +> 10 +> § 2º O requisito de que trata o inciso II do § 1º poderá ser atendido por meio da juntada do +> termo ou da peça de acusação. +> § 3º Quando se tratar de processo em meio físico, a citação deverá conter, além dos requisitos +> previstos no § 1º, o termo de acusação ou a peça acusatória, a depender do caso. +> § 4º O acusado que, embora citado, não apresentar defesa será considerado revel. + +**`ICVM-607/2019::art-21::par-1`** + +> § 1º A citação conterá: +> I – a identificação do acusado; +> II – a indicação dos fatos imputados ao acusado; +> III – a finalidade da citação; +> IV – o prazo para a apresentação de defesa; +> V – a informação da continuidade do processo, independentemente de seu comparecimento; +> VI – o dever do acusado, ou de procurador por ele constituído, de se cadastrar no sistema de +> processo eletrônico existente na página da CVM na rede mundial de computadores para fins de +> acesso aos autos e posterior acompanhamento do andamento do processo; e +> VII – o aviso de que o acusado poderá propor a celebração de termo de compromisso, em +> conformidade com o disposto no Capítulo IV desta Instrução. +> COMISSÃO DE VALORES MOBILIÁRIOS +> Rua Sete de Setembro, 111/2-5º e 23-34º Andares, Centro, Rio de Janeiro/RJ – CEP: 20050-901 – Brasil - Tel.: (21) 3554-8686 +> Rua Cincinato Braga, 340/2º, 3º e 4º Andares, Bela Vista, São Paulo/ SP – CEP: 01333-010 – Brasil - Tel.: (11) 2146-2000 +> SCN Q.02 – Bl. A – Ed. Corporate Financial Center, S.404/4º Andar, Brasília/DF – CEP: 70712-900 – Brasil -Tel.: (61) 3327-2030/2031 +> +> INSTRUÇÃO CVM Nº 607, DE 17 DE JUNHO DE 2019 +> 10 + +**`ICVM-607/2019::art-29`** + +> Art. 29. O acusado deverá apresentar sua defesa por escrito no prazo de 30 (trinta) dias após a +> citação, oportunidade em que deverá juntar os documentos destinados a provar suas alegações e +> especificar as demais provas que pretenda produzir, observado o disposto nos arts. 42 e 43 desta +> Instrução. +> § 1º O interessado deverá manifestar sua intenção de celebrar termo de compromisso até o +> término do prazo para a apresentação de defesa, e sem prejuízo do ônus de apresentação desta. +> § 2º A manifestação de intenção ou a apresentação de proposta de termo de compromisso não +> suspende nem interrompe o prazo para apresentação da defesa. +> COMISSÃO DE VALORES MOBILIÁRIOS +> Rua Sete de Setembro, 111/2-5º e 23-34º Andares, Centro, Rio de Janeiro/RJ – CEP: 20050-901 – Brasil - Tel.: (21) 3554-8686 +> Rua Cincinato Braga, 340/2º, 3º e 4º Andares, Bela Vista, São Paulo/ SP – CEP: 01333-010 – Brasil - Tel.: (11) 2146-2000 +> SCN Q.02 – Bl. A – Ed. Corporate Financial Center, S.404/4º Andar, Brasília/DF – CEP: 70712-900 – Brasil -Tel.: (61) 3327-2030/2031 +> +> INSTRUÇÃO CVM Nº 607, DE 17 DE JUNHO DE 2019 +> 14 +> § 3º Serão computados individualmente os prazos para todas as manifestações dos acusados, +> sendo admitida uma única prorrogação pelo mesmo prazo, diante de pedido devidamente +> fundamentado. +> § 4º Os acusados que constituírem o mesmo procurador e apresentarem defesa conjunta terão +> o mesmo prazo para se manifestarem nos autos, contado da citação que for efetivada por último, nos +> termos do art. 29, § 3º, desta Instrução. +> § 5º Nos processos sancionadores instaurados em desfavor de múltiplos acusados, as defesas +> serão consideradas sigilosas e não serão fornecidas a terceiros ou a outros acusados até o +> encerramento do último prazo de apresentação de defesa. + +### Generated answer + +Com base na Instrução CVM nº 607/2019, as etapas do rito processual sancionador até a apresentação da defesa são as seguintes: + +1. **Investigação e Decisão da Superintendência:** Após a investigação das infrações, a superintendência pode optar por lavrar o termo de acusação, propor inquérito administrativo ou deixar de lavrar o termo (em casos de inexistência de irregularidades ou pouca relevância da conduta) [ICVM-607/2019::art-4]. +2. **Parecer da PFE:** Antes da citação dos acusados, a Procuradoria Federal Especializada (PFE) deve emitir um parecer sobre o termo de acusação no prazo de 30 dias, examinando o cumprimento dos requisitos legais e a adequação do rito [ICVM-607/2019::art-7]. Este parecer não é obrigatório em processos sob rito simplificado [ICVM-607/2019::art-7::par-3]. +3. **Providências da Superintendência:** Com base no parecer da PFE, a superintendência pode arquivar o processo, ajustar o termo de acusação ou adequar o rito processual [ICVM-607/2019::art-7::par-1]. +4. **Citação:** O processo administrativo sancionador é considerado instaurado com a citação dos acusados [ICVM-607/2019::art-21]. A citação deve conter informações como a identificação do acusado, os fatos imputados, o prazo para defesa e o aviso sobre a possibilidade de propor termo de compromisso [ICVM-607/2019::art-21::par-1]. +5. **Apresentação de Defesa:** O acusado deve apresentar sua defesa por escrito no prazo de 30 dias após a citação, juntando os documentos necessários e especificando as provas que pretende produzir [ICVM-607/2019::art-29]. + +### Your scores + +| `q129-hybrid_rrf` | 0.0 / 0.5 / 1.0 | notes | +| --- | --- | --- | +| faithfulness | | | +| answer_relevancy | | | + +--- + +## 10. `q017-hybrid_rrf` + +- Class: **unanswerable** · **UNANSWERABLE** +- Strategy: `hybrid_rrf` + +### Question + +Qual é o valor da multa pecuniária prevista na RES-CMN-5274/2025 para o descumprimento do prazo de adaptação até março de 2026? + +### Reference answer (golden set) + +A RES-CMN-5274/2025 não estabelece um valor de multa pecuniária para o descumprimento desse prazo; o texto da resolução não trata dessa questão. + +### Cited authoritative text + +**`RES-CMN-5274/2025::art-2`** + +> Art. 2º As instituições em funcionamento na data da entrada em vigor desta Resolução devem promover as adaptações necessárias à adequação ao disposto nesta Resolução até 1º de março de 2026. + +### Generated answer + +O contexto fornecido não contém informações sobre o valor de multas pecuniárias específicas para o descumprimento do prazo de adaptação estabelecido pela Resolução CMN nº 5274/2025. O documento apenas determina que as instituições em funcionamento devem promover as adaptações necessárias até 1º de março de 2026 [RES-CMN-5274/2025::art-2]. + +### Your scores + +| `q017-hybrid_rrf` | 0.0 / 0.5 / 1.0 | notes | +| --- | --- | --- | +| faithfulness | | | +| answer_relevancy | | | +| abstention | | | + +--- + +## 11. `q228-dense` + +- Class: **multi_hop** +- Strategy: `dense` + +### Question + +Como o adiamento de sessão de julgamento por motivo de força maior (art. 50, § 4º) se relaciona com a exigência de presença mínima de membros do Colegiado (art. 50, caput) na ICVM 607/2019? + +### Reference answer (golden set) + +O art. 50, caput, exige a presença de no mínimo 3 membros do Colegiado para a sessão se realizar; se isso não ocorrer por motivo de força maior, o art. 50, § 4º, permite que a sessão seja transferida para o primeiro dia útil seguinte, sem necessidade de nova convocação. + +### Cited authoritative text + +**`ICVM-607/2019::art-50`** + +> Art. 50. A sessão será presidida pelo Presidente da CVM ou, na sua ausência ou +> impedimento, por seu substituto eventual e somente será realizada com a presença de no mínimo 3 +> (três) membros do Colegiado. +> § 1º A participação dos membros do Colegiado nas sessões de julgamento poderá ocorrer por +> videoconferência. +> COMISSÃO DE VALORES MOBILIÁRIOS +> Rua Sete de Setembro, 111/2-5º e 23-34º Andares, Centro, Rio de Janeiro/RJ – CEP: 20050-901 – Brasil - Tel.: (21) 3554-8686 +> Rua Cincinato Braga, 340/2º, 3º e 4º Andares, Bela Vista, São Paulo/ SP – CEP: 01333-010 – Brasil - Tel.: (11) 2146-2000 +> SCN Q.02 – Bl. A – Ed. Corporate Financial Center, S.404/4º Andar, Brasília/DF – CEP: 70712-900 – Brasil -Tel.: (61) 3327-2030/2031 +> +> INSTRUÇÃO CVM Nº 607, DE 17 DE JUNHO DE 2019 +> 21 +> § 2º No julgamento dos processos administrativos sancionadores em que não comparecer +> nenhum acusado ou nenhum de seus respectivos procuradores constituídos nos autos, a sessão +> poderá realizar-se por meio eletrônico. +> § 3º Considerando o andamento dos trabalhos da sessão, fica facultado ao Presidente +> suspendê-la e reiniciá-la no dia útil subsequente, independente de nova convocação e publicação. +> § 4º A sessão que não se realizar, por motivo de força maior, poderá ser transferida para o +> primeiro dia útil seguinte, na hora anteriormente marcada, independentemente de nova convocação +> e publicação. + +**`ICVM-607/2019::art-50::par-4`** + +> § 4º A sessão que não se realizar, por motivo de força maior, poderá ser transferida para o +> primeiro dia útil seguinte, na hora anteriormente marcada, independentemente de nova convocação +> e publicação. + +### Generated answer + +De acordo com a Instrução CVM nº 607/2019, a realização de uma sessão de julgamento exige a presença de, no mínimo, 3 (três) membros do Colegiado [ICVM-607/2019::art-50]. + +Caso a sessão não ocorra por motivo de força maior, ela poderá ser transferida para o primeiro dia útil seguinte, no mesmo horário anteriormente marcado, sem a necessidade de nova convocação ou publicação [ICVM-607/2019::art-50::par-4]. Embora o texto não estabeleça uma relação direta de dependência entre o motivo de força maior e a falta de quórum, a exigência de presença mínima de 3 membros permanece como regra geral para a realização da sessão [ICVM-607/2019::art-50]. + +### Your scores + +| `q228-dense` | 0.0 / 0.5 / 1.0 | notes | +| --- | --- | --- | +| faithfulness | | | +| answer_relevancy | | | + +--- + +## 12. `q188-sac` + +- Class: **section_comparative** +- Strategy: `sac` + +### Question + +Compare os efeitos do termo de compromisso (art. 88) com os efeitos do Acordo de Supervisão (art. 92) na ICVM 607/2019. + +### Reference answer (golden set) + +O termo de compromisso (art. 88) suspende o processo ou impede sua instauração, sem admissão de culpa. Já o Acordo de Supervisão (art. 92) pressupõe confissão da infração pelo investigado, em troca de extinção da ação punitiva ou redução de 1/3 a 2/3 da penalidade, mediante cooperação efetiva na apuração dos fatos. + +### Cited authoritative text + +**`ICVM-607/2019::art-88::inc-i`** + +> I – a suspensão do processo administrativo em curso, pelo prazo estipulado para o +> cumprimento do compromisso; ou + +**`ICVM-607/2019::art-88::inc-ii`** + +> II – a não instauração de processo administrativo sancionador, nos casos em que a proposta +> for apresentada ainda em fase de apuração ou antes desta. +> COMISSÃO DE VALORES MOBILIÁRIOS +> Rua Sete de Setembro, 111/2-5º e 23-34º Andares, Centro, Rio de Janeiro/RJ – CEP: 20050-901 – Brasil - Tel.: (21) 3554-8686 +> Rua Cincinato Braga, 340/2º, 3º e 4º Andares, Bela Vista, São Paulo/ SP – CEP: 01333-010 – Brasil - Tel.: (11) 2146-2000 +> SCN Q.02 – Bl. A – Ed. Corporate Financial Center, S.404/4º Andar, Brasília/DF – CEP: 70712-900 – Brasil -Tel.: (61) 3327-2030/2031 +> +> INSTRUÇÃO CVM Nº 607, DE 17 DE JUNHO DE 2019 +> 35 + +**`ICVM-607/2019::art-92`** + +> Art. 92. A CVM poderá celebrar acordo administrativo em processo de supervisão (“Acordo +> de Supervisão”) com pessoas naturais ou jurídicas que confessarem a prática de infração às normas +> legais ou regulamentares cujo cumprimento lhe caiba fiscalizar, com extinção de sua ação punitiva +> ou redução de 1/3 (um terço) a 2/3 (dois terços) da penalidade aplicável, mediante efetiva, plena e +> permanente cooperação para a apuração dos fatos, da qual resulte utilidade para o processo, em +> especial: +> I – a identificação dos demais envolvidos na prática da infração, quando couber; e +> COMISSÃO DE VALORES MOBILIÁRIOS +> Rua Sete de Setembro, 111/2-5º e 23-34º Andares, Centro, Rio de Janeiro/RJ – CEP: 20050-901 – Brasil - Tel.: (21) 3554-8686 +> Rua Cincinato Braga, 340/2º, 3º e 4º Andares, Bela Vista, São Paulo/ SP – CEP: 01333-010 – Brasil - Tel.: (11) 2146-2000 +> SCN Q.02 – Bl. A – Ed. Corporate Financial Center, S.404/4º Andar, Brasília/DF – CEP: 70712-900 – Brasil -Tel.: (61) 3327-2030/2031 +> +> INSTRUÇÃO CVM Nº 607, DE 17 DE JUNHO DE 2019 +> 36 +> II – a obtenção de informações e de documentos que comprovem a infração noticiada ou sob +> apuração. + +**`ICVM-607/2019::art-93::par-2`** + +> § 2º A proposta de Acordo de Supervisão não obstará as atividades de investigação e +> instrução nem a tramitação do processo administrativo sancionador que porventura já tenha sido +> anteriormente instaurado para a apuração das condutas narradas na proposta. + +### Generated answer + +Os efeitos dos dois institutos previstos na Instrução CVM nº 607/2019 são distintos conforme a natureza do acordo: + +**Termo de Compromisso (art. 88):** +A celebração do termo de compromisso produz os seguintes efeitos: + +- A suspensão de um processo administrativo que já esteja em curso, durante o prazo estipulado para o cumprimento do compromisso [ICVM-607/2019::art-88::inc-i]; ou +- A não instauração de processo administrativo sancionador, caso a proposta seja apresentada antes ou durante a fase de apuração [ICVM-607/2019::art-88::inc-ii]. + +**Acordo de Supervisão (art. 92):** +A celebração do Acordo de Supervisão, que exige a confissão da prática de infração e cooperação efetiva, plena e permanente, produz os seguintes efeitos: + +- A extinção da ação punitiva da CVM; ou +- A redução de 1/3 (um terço) a 2/3 (dois terços) da penalidade aplicável [ICVM-607/2019::art-92]. + +Vale ressaltar que, diferentemente do termo de compromisso, a proposta de Acordo de Supervisão não impede as atividades de investigação, instrução ou a tramitação de processo administrativo sancionador que já tenha sido instaurado para apurar as condutas narradas [ICVM-607/2019::art-93::par-2]. + +### Your scores + +| `q188-sac` | 0.0 / 0.5 / 1.0 | notes | +| --- | --- | --- | +| faithfulness | | | +| answer_relevancy | | | + +--- + +## 13. `q162-sac` + +- Class: **global** +- Strategy: `sac` + +### Question + +De modo geral, como a ICVM 607/2019 estrutura o cálculo e a dosimetria das penalidades aplicáveis pela CVM? + +### Reference answer (golden set) + +A CVM pode impor sete tipos de penalidade (art. 60), com limites para a multa (art. 61); o Colegiado fixa uma pena-base observando proporcionalidade e capacidade econômica (art. 63), sobre a qual incidem circunstâncias agravantes, que aumentam a pena (art. 65), e atenuantes, que a reduzem (art. 66). + +### Cited authoritative text + +**`ICVM-607/2019::art-63`** + +> Art. 63. Na fixação da pena-base, o Colegiado observará os princípios da proporcionalidade e +> da razoabilidade, bem como a capacidade econômica do infrator e os motivos que justifiquem a +> imposição da penalidade. +> COMISSÃO DE VALORES MOBILIÁRIOS +> Rua Sete de Setembro, 111/2-5º e 23-34º Andares, Centro, Rio de Janeiro/RJ – CEP: 20050-901 – Brasil - Tel.: (21) 3554-8686 +> Rua Cincinato Braga, 340/2º, 3º e 4º Andares, Bela Vista, São Paulo/ SP – CEP: 01333-010 – Brasil - Tel.: (11) 2146-2000 +> SCN Q.02 – Bl. A – Ed. Corporate Financial Center, S.404/4º Andar, Brasília/DF – CEP: 70712-900 – Brasil -Tel.: (61) 3327-2030/2031 +> +> INSTRUÇÃO CVM Nº 607, DE 17 DE JUNHO DE 2019 +> 25 +> § 1º Se adotado o critério de que trata o art. 61, inciso I, a pena-base da multa deverá +> observar os limites aplicáveis a cada infração, previstos no Anexo 63, sem prejuízo da aplicação +> cumulativa de outras modalidades de pena descritas no art. 60 desta Instrução. +> § 2º Na hipótese do § 1º em que a infração não esteja prevista no Anexo 63, o Colegiado +> deverá, com base na gravidade da conduta, enquadrá-la em um dos grupos previstos no referido +> Anexo. +> § 3º A pena-base das penalidades descritas no art. 60, incisos III a VI, deverá ser fixada em +> meses e não poderá ser superior a 10 (dez) anos. +> § 4º A pena-base da penalidade descrita no art. 60, inciso VII, deverá ser fixada em meses e +> não poderá ser superior a 5 (cinco) anos. + +**`ICVM-607/2019::art-63::par-1`** + +> § 1º Se adotado o critério de que trata o art. 61, inciso I, a pena-base da multa deverá +> observar os limites aplicáveis a cada infração, previstos no Anexo 63, sem prejuízo da aplicação +> cumulativa de outras modalidades de pena descritas no art. 60 desta Instrução. + +**`ICVM-607/2019::art-63::par-2`** + +> § 2º Na hipótese do § 1º em que a infração não esteja prevista no Anexo 63, o Colegiado +> deverá, com base na gravidade da conduta, enquadrá-la em um dos grupos previstos no referido +> Anexo. + +**`ICVM-607/2019::art-63::par-3`** + +> § 3º A pena-base das penalidades descritas no art. 60, incisos III a VI, deverá ser fixada em +> meses e não poderá ser superior a 10 (dez) anos. + +**`ICVM-607/2019::art-63::par-4`** + +> § 4º A pena-base da penalidade descrita no art. 60, inciso VII, deverá ser fixada em meses e +> não poderá ser superior a 5 (cinco) anos. + +**`ICVM-607/2019::art-62`** + +> Art. 62. Na dosimetria da pena, salvo se aplicada a penalidade de advertência, o Colegiado +> fixará inicialmente a pena-base, aplicando na sequência as circunstâncias agravantes e atenuantes, +> bem como a causa de redução da pena, nessa ordem. +> Parágrafo único. O Colegiado considerará na dosimetria as demais sanções relativas aos +> mesmos fatos, aplicadas definitivamente por outras autoridades, cabendo ao acusado demonstrar, +> até o julgamento do processo pelo Colegiado, o cabimento dessa circunstância. + +**`ICVM-607/2019::art-65::par-1`** + +> § 1º A penalidade de multa será acrescida em até 25% (vinte e cinco por cento) para cada +> agravante verificada. + +**`ICVM-607/2019::art-65::par-2`** + +> § 2º As penalidades de suspensão, inabilitação e proibição serão acrescidas em até 25% (vinte +> e cinco por cento) para cada agravante verificada, considerando-se o número de meses da pena-base +> e desprezando-se as frações. + +**`ICVM-607/2019::art-62::par-unico`** + +> Parágrafo único. O Colegiado considerará na dosimetria as demais sanções relativas aos +> mesmos fatos, aplicadas definitivamente por outras autoridades, cabendo ao acusado demonstrar, +> até o julgamento do processo pelo Colegiado, o cabimento dessa circunstância. + +**`ICVM-607/2019::art-4::par-1`** + +> § 1º Na avaliação da relevância da conduta ou da expressividade da ameaça ou lesão ao bem +> jurídico, poderão ser utilizados os seguintes parâmetros, dentre outros: +> I – o grau de reprovabilidade ou da repercussão da conduta; +> II – a expressividade de valores relacionados à conduta; +> III – a expressividade de prejuízos causados a investidores e demais participantes do mercado; +> IV – o impacto da conduta na credibilidade do mercado de capitais; +> V – os antecedentes das pessoas envolvidas; +> COMISSÃO DE VALORES MOBILIÁRIOS +> Rua Sete de Setembro, 111/2-5º e 23-34º Andares, Centro, Rio de Janeiro/RJ – CEP: 20050-901 – Brasil - Tel.: (21) 3554-8686 +> Rua Cincinato Braga, 340/2º, 3º e 4º Andares, Bela Vista, São Paulo/ SP – CEP: 01333-010 – Brasil - Tel.: (11) 2146-2000 +> SCN Q.02 – Bl. A – Ed. Corporate Financial Center, S.404/4º Andar, Brasília/DF – CEP: 70712-900 – Brasil -Tel.: (61) 3327-2030/2031 +> +> INSTRUÇÃO CVM Nº 607, DE 17 DE JUNHO DE 2019 +> 3 +> VI – a boa-fé das pessoas envolvidas; +> VII – a regularização da suposta infração pelo administrado; e +> VIII – o ressarcimento dos investidores lesados. + +### Generated answer + +A Instrução CVM 607/2019 estrutura a dosimetria das penalidades seguindo uma ordem específica de aplicação, conforme detalhado abaixo: + +**1. Fixação da Pena-Base** + +- **Critérios:** Ao fixar a pena-base, o Colegiado deve observar os princípios da proporcionalidade e da razoabilidade, a capacidade econômica do infrator e os motivos que justificam a penalidade [ICVM-607/2019::art-63]. +- **Limites:** Para a multa, deve-se observar os limites previstos no Anexo 63 da Instrução [ICVM-607/2019::art-63::par-1]. Caso a infração não esteja no Anexo, o Colegiado deve enquadrá-la em um dos grupos previstos com base na gravidade da conduta [ICVM-607/2019::art-63::par-2]. +- **Prazos:** Para as penalidades de inabilitação, suspensão e proibição (incisos III a VI do art. 60), a pena-base não pode exceder 10 anos [ICVM-607/2019::art-63::par-3]. Para a proibição de atuar no mercado (inciso VII do art. 60), o limite é de 5 anos [ICVM-607/2019::art-63::par-4]. + +**2. Ordem de Aplicação** +Salvo no caso de advertência, a dosimetria segue a seguinte sequência: + +1. Fixação da pena-base [ICVM-607/2019::art-62]. +2. Aplicação das circunstâncias agravantes e atenuantes [ICVM-607/2019::art-62]. +3. Aplicação da causa de redução da pena [ICVM-607/2019::art-62]. + +**3. Ajustes por Agravantes** + +- **Multa:** Pode ser acrescida em até 25% para cada agravante verificada [ICVM-607/2019::art-65::par-1]. +- **Suspensão, Inabilitação e Proibição:** Também podem ser acrescidas em até 25% por agravante, calculadas sobre o número de meses da pena-base e desprezando-se as frações [ICVM-607/2019::art-65::par-2]. + +**4. Considerações Adicionais** + +- **Outras sanções:** O Colegiado deve considerar na dosimetria sanções aplicadas definitivamente por outras autoridades sobre os mesmos fatos, cabendo ao acusado demonstrar essa circunstância até o julgamento [ICVM-607/2019::art-62::par-unico]. +- **Relevância:** Na avaliação da conduta, podem ser considerados parâmetros como o grau de reprovabilidade, valores envolvidos, prejuízos a investidores, impacto na credibilidade do mercado, antecedentes, boa-fé, regularização da infração e ressarcimento aos lesados [ICVM-607/2019::art-4::par-1]. + +### Your scores + +| `q162-sac` | 0.0 / 0.5 / 1.0 | notes | +| --- | --- | --- | +| faithfulness | | | +| answer_relevancy | | | + +--- + +## 14. `q091-raptor` + +- Class: **unanswerable** · **UNANSWERABLE** +- Strategy: `raptor` + +### Question + +Qual é o valor mínimo da multa diária prevista no art. 52, inciso III, da LGPD? + +### Reference answer (golden set) + +O art. 52, III, não estabelece um valor mínimo para a multa diária; apenas determina que ela observe o limite total do inciso II (até R$ 50 milhões por infração), sem fixar piso mínimo. + +### Cited authoritative text + +**`LEI-13709/2018::art-54`** + +> Art. 54. O valor da sanção de multa diária aplicável às infrações a esta Lei deve observar a gravidade da falta e a extensão do dano ou prejuízo causado e ser fundamentado pela autoridade nacional. +> Parágrafo único. A intimação da sanção de multa diária deverá conter, no mínimo, a descrição da obrigação imposta, o prazo razoável e estipulado pelo órgão para o seu cumprimento e o valor da multa diária a ser aplicada pelo seu descumprimento. (Vigência) +> DA AUTORIDADE NACIONAL DE PROTEÇÃO DE DADOS (ANPD) E DO CONSELHO NACIONAL DE PROTEÇÃO DE DADOS PESSOAIS E DA PRIVACIDADE +> Da Autoridade Nacional de Proteção de Dados (ANPD) +> (Redação dada pela Medida Provisória nº 1.317, de 2025) +> DA AGÊNCIA NACIONAL DE PROTEÇÃO DE DADOS E DO CONSELHO NACIONAL DE PROTEÇÃO DE DADOS PESSOAIS E DA PRIVACIDADE +> Da Agência Nacional de Proteção de Dados +> (Redação dada pela Lei nº 15.352, de 2026) +> DA AGÊNCIA NACIONAL DE PROTEÇÃO DE DADOS E DO CONSELHO NACIONAL DE PROTEÇÃO DE DADOS PESSOAIS E DA PRIVACIDADE’ +> Da Agência Nacional de Proteção de Dados + +### Generated answer + +O contexto fornecido não estabelece um valor mínimo para a multa diária prevista no art. 52, inciso III, da LGPD. O texto menciona apenas que a multa diária deve observar o limite total estabelecido para a multa simples (limitada a R$ 50.000.000,00 por infração) [LEI-13709/2018::art-52::inc-ii, LEI-13709/2018::art-52::inc-iii] e que o seu valor deve ser fundamentado pela autoridade nacional, considerando a gravidade da falta e a extensão do dano ou prejuízo causado [LEI-13709/2018::art-54]. + +### Your scores + +| `q091-raptor` | 0.0 / 0.5 / 1.0 | notes | +| --- | --- | --- | +| faithfulness | | | +| answer_relevancy | | | +| abstention | | | + +--- + +## 15. `q147-reranked` + +- Class: **exact_factual** +- Strategy: `reranked` + +### Question + +Quais penalidades a CVM pode impor aos infratores, segundo o art. 60 da ICVM 607/2019? + +### Reference answer (golden set) + +Advertência, multa, inabilitação temporária para cargos, suspensão de autorização ou registro, inabilitação para atividades da Lei 6.385/1976, proibição temporária de praticar atividades, e proibição temporária de atuar no mercado de valores mobiliários (art. 60). + +### Cited authoritative text + +**`ICVM-607/2019::art-60::inc-i`** + +> I – advertência; + +**`ICVM-607/2019::art-60::inc-ii`** + +> II – multa; + +**`ICVM-607/2019::art-60::inc-iii`** + +> III – inabilitação temporária, até o máximo de 20 (vinte) anos, para o exercício de cargo de +> administrador ou de conselheiro fiscal de companhia aberta, de entidade do sistema de distribuição +> ou de outras entidades que dependam de autorização ou registro na Comissão de Valores +> Mobiliários; + +**`ICVM-607/2019::art-60::inc-iv`** + +> IV – suspensão da autorização ou registro para o exercício das atividades de que trata a Lei nº +> 6.385, de 1976; + +**`ICVM-607/2019::art-60::inc-v`** + +> V – inabilitação temporária, até o máximo de 20 (vinte) anos, para o exercício das atividades +> de que trata a Lei nº 6.385, de 7 de dezembro de 1976; + +**`ICVM-607/2019::art-60::inc-vi`** + +> VI – proibição temporária, até o máximo de 20 (vinte) anos, de praticar determinadas +> atividades ou operações, para os integrantes do sistema de distribuição ou de outras entidades que +> dependam de autorização ou registro na Comissão de Valores Mobiliários; e +> COMISSÃO DE VALORES MOBILIÁRIOS +> Rua Sete de Setembro, 111/2-5º e 23-34º Andares, Centro, Rio de Janeiro/RJ – CEP: 20050-901 – Brasil - Tel.: (21) 3554-8686 +> Rua Cincinato Braga, 340/2º, 3º e 4º Andares, Bela Vista, São Paulo/ SP – CEP: 01333-010 – Brasil - Tel.: (11) 2146-2000 +> SCN Q.02 – Bl. A – Ed. Corporate Financial Center, S.404/4º Andar, Brasília/DF – CEP: 70712-900 – Brasil -Tel.: (61) 3327-2030/2031 +> +> INSTRUÇÃO CVM Nº 607, DE 17 DE JUNHO DE 2019 +> 24 + +**`ICVM-607/2019::art-60::inc-vii`** + +> VII – proibição temporária, até o máximo de 10 (dez) anos, de atuar, direta ou indiretamente, +> em uma ou mais modalidades de operação no mercado de valores mobiliários. + +### Generated answer + +Segundo o art. 60 da Instrução CVM nº 607/2019, a CVM pode impor as seguintes penalidades, de forma isolada ou cumulativa: + +- **Advertência** [ICVM-607/2019::art-60::inc-i]; +- **Multa** [ICVM-607/2019::art-60::inc-ii]; +- **Inabilitação temporária**, até o máximo de 20 anos, para o exercício de cargo de administrador ou de conselheiro fiscal de companhia aberta, de entidade do sistema de distribuição ou de outras entidades que dependam de autorização ou registro na CVM [ICVM-607/2019::art-60::inc-iii]; +- **Suspensão da autorização ou registro** para o exercício das atividades previstas na Lei nº 6.385/1976 [ICVM-607/2019::art-60::inc-iv]; +- **Inabilitação temporária**, até o máximo de 20 anos, para o exercício das atividades previstas na Lei nº 6.385/1976 [ICVM-607/2019::art-60::inc-v]; +- **Proibição temporária**, até o máximo de 20 anos, de praticar determinadas atividades ou operações, para integrantes do sistema de distribuição ou outras entidades que dependam de autorização ou registro na CVM [ICVM-607/2019::art-60::inc-vi]; +- **Proibição temporária**, até o máximo de 10 anos, de atuar, direta ou indiretamente, em uma ou mais modalidades de operação no mercado de valores mobiliários [ICVM-607/2019::art-60::inc-vii]. + +### Your scores + +| `q147-reranked` | 0.0 / 0.5 / 1.0 | notes | +| --- | --- | --- | +| faithfulness | | | +| answer_relevancy | | | + +--- + +## 16. `q029-sac` + +- Class: **exact_factual** +- Strategy: `sac` + +### Question + +Quais resoluções são revogadas pela RES-CMN-4893/2021, segundo seu art. 27? + +### Reference answer (golden set) + +São revogadas a Resolução nº 4.658, de 26 de abril de 2018, e a Resolução nº 4.752, de 26 de setembro de 2019 (art. 27). + +### Cited authoritative text + +**`RES-CMN-4893/2021::art-27::inc-i`** + +> I - a Resolução nº 4.658, de 26 de abril de 2018; e + +**`RES-CMN-4893/2021::art-27::inc-ii`** + +> II - a Resolução nº 4.752, de 26 de setembro de 2019. + +### Generated answer + +De acordo com o art. 27 da Resolução CMN nº 4.893/2021, as resoluções revogadas são: + +- Resolução nº 4.658, de 26 de abril de 2018 [RES-CMN-4893/2021::art-27::inc-i]; +- Resolução nº 4.752, de 26 de setembro de 2019 [RES-CMN-4893/2021::art-27::inc-ii]. + +### Your scores + +| `q029-sac` | 0.0 / 0.5 / 1.0 | notes | +| --- | --- | --- | +| faithfulness | | | +| answer_relevancy | | | + +--- + +## 17. `q086-contextual` + +- Class: **numeric_tabular** +- Strategy: `contextual` + +### Question + +Qual é o valor máximo da multa simples prevista no art. 52, inciso II, da LGPD, por infração? + +### Reference answer (golden set) + +Multa simples de até 2% do faturamento da pessoa jurídica de direito privado, grupo ou conglomerado no Brasil no último exercício, excluídos os tributos, limitada, no total, a R$ 50.000.000,00 (cinquenta milhões de reais) por infração (art. 52, II). + +### Cited authoritative text + +**`LEI-13709/2018::art-52::inc-ii`** + +> II - multa simples, de até 2% (dois por cento) do faturamento da pessoa jurídica de direito privado, grupo ou conglomerado no Brasil no seu último exercício, excluídos os tributos, limitada, no total, a R$ 50.000.000,00 (cinquenta milhões de reais) por infração; + +### Generated answer + +O valor máximo da multa simples prevista no art. 52, inciso II, da LGPD é de R$ 50.000.000,00 (cinquenta milhões de reais) por infração [LEI-13709/2018::art-52::inc-ii]. + +### Your scores + +| `q086-contextual` | 0.0 / 0.5 / 1.0 | notes | +| --- | --- | --- | +| faithfulness | | | +| answer_relevancy | | | + +--- + +## 18. `q152-dense` + +- Class: **numeric_tabular** +- Strategy: `dense` + +### Question + +Qual o limite máximo, em anos, para a pena-base das penalidades descritas no art. 60, incisos III a VI, segundo o art. 63, § 3º da ICVM 607/2019? + +### Reference answer (golden set) + +Não poderá ser superior a 10 (dez) anos (art. 63, § 3º). + +### Cited authoritative text + +**`ICVM-607/2019::art-63::par-3`** + +> § 3º A pena-base das penalidades descritas no art. 60, incisos III a VI, deverá ser fixada em +> meses e não poderá ser superior a 10 (dez) anos. + +### Generated answer + +O limite máximo para a pena-base das penalidades descritas nos incisos III a VI do art. 60 da Instrução CVM nº 607/2019 é de 10 (dez) anos [ICVM-607/2019::art-63::par-3]. + +### Your scores + +| `q152-dense` | 0.0 / 0.5 / 1.0 | notes | +| --- | --- | --- | +| faithfulness | | | +| answer_relevancy | | | + +--- + +## 19. `q053-contextual` + +- Class: **semantic** +- Strategy: `contextual` + +### Question + +O que caracteriza o princípio da necessidade no tratamento de dados pessoais, segundo o art. 6º, inciso III da LGPD? + +### Reference answer (golden set) + +É a limitação do tratamento ao mínimo necessário para a realização de suas finalidades, com abrangência dos dados pertinentes, proporcionais e não excessivos em relação às finalidades do tratamento (art. 6º, III). + +### Cited authoritative text + +**`LEI-13709/2018::art-6::inc-iii`** + +> III - necessidade: limitação do tratamento ao mínimo necessário para a realização de suas finalidades, com abrangência dos dados pertinentes, proporcionais e não excessivos em relação às finalidades do tratamento de dados; + +### Generated answer + +Segundo o art. 6º, inciso III da LGPD, o princípio da necessidade caracteriza-se pela limitação do tratamento de dados ao mínimo necessário para a realização de suas finalidades, abrangendo dados que sejam pertinentes, proporcionais e não excessivos em relação a tais finalidades [LEI-13709/2018::art-6::inc-iii]. + +### Your scores + +| `q053-contextual` | 0.0 / 0.5 / 1.0 | notes | +| --- | --- | --- | +| faithfulness | | | +| answer_relevancy | | | + +--- + +## 20. `q160-hybrid_rrf` + +- Class: **multi_hop** +- Strategy: `hybrid_rrf` + +### Question + +Como as circunstâncias agravantes do art. 65 se relacionam com o cálculo da pena-base previsto no art. 63 da ICVM 607/2019? + +### Reference answer (golden set) + +O art. 63 determina que o Colegiado fixe a pena-base observando proporcionalidade, razoabilidade e capacidade econômica do infrator; sobre essa pena-base incidem as agravantes do art. 65, cada uma acrescendo até 25% ao valor da multa (art. 65, § 1º). + +### Cited authoritative text + +**`ICVM-607/2019::art-62, ICVM-607/2019::art-63`** + +> _(not resolvable - the cited ID does not exist in the parsed corpus)_ + +**`ICVM-607/2019::art-65::par-1`** + +> § 1º A penalidade de multa será acrescida em até 25% (vinte e cinco por cento) para cada +> agravante verificada. + +**`ICVM-607/2019::art-65::par-2`** + +> § 2º As penalidades de suspensão, inabilitação e proibição serão acrescidas em até 25% (vinte +> e cinco por cento) para cada agravante verificada, considerando-se o número de meses da pena-base +> e desprezando-se as frações. + +**`ICVM-607/2019::art-65`** + +> Art. 65. São circunstâncias agravantes, quando não constituem ou qualificam a infração: +> I – a prática sistemática ou reiterada da conduta irregular; +> II – o elevado prejuízo causado; +> III – a expressiva vantagem auferida ou pretendida pelo infrator; +> IV – a existência de dano relevante à imagem do mercado de valores mobiliários ou do +> segmento em que atua; +> V – o cometimento de infração mediante ardil, fraude ou simulação; +> COMISSÃO DE VALORES MOBILIÁRIOS +> Rua Sete de Setembro, 111/2-5º e 23-34º Andares, Centro, Rio de Janeiro/RJ – CEP: 20050-901 – Brasil - Tel.: (21) 3554-8686 +> Rua Cincinato Braga, 340/2º, 3º e 4º Andares, Bela Vista, São Paulo/ SP – CEP: 01333-010 – Brasil - Tel.: (11) 2146-2000 +> SCN Q.02 – Bl. A – Ed. Corporate Financial Center, S.404/4º Andar, Brasília/DF – CEP: 70712-900 – Brasil -Tel.: (61) 3327-2030/2031 +> +> INSTRUÇÃO CVM Nº 607, DE 17 DE JUNHO DE 2019 +> 26 +> VI – o comprometimento ou risco de comprometimento da solvência do emissor; +> VII – a violação de deveres fiduciários decorrentes do cargo, posição ou função que ocupa; e +> VIII – a ocultação de provas da infração mediante ardil, fraude ou simulação. +> § 1º A penalidade de multa será acrescida em até 25% (vinte e cinco por cento) para cada +> agravante verificada. +> § 2º As penalidades de suspensão, inabilitação e proibição serão acrescidas em até 25% (vinte +> e cinco por cento) para cada agravante verificada, considerando-se o número de meses da pena-base +> e desprezando-se as frações. +> § 3º Ocorrerá reincidência quando o agente comete nova infração depois de ter sido punido +> por força de decisão administrativa definitiva, salvo se decorridos 5 (cinco) anos do cumprimento +> da respectiva punição ou da extinção da pena. + +### Generated answer + +De acordo com a Instrução CVM 607/2019, a dosimetria da pena segue uma ordem específica: o Colegiado fixa inicialmente a pena-base (observando os princípios da proporcionalidade, razoabilidade, capacidade econômica do infrator e os motivos da penalidade) e, na sequência, aplica as circunstâncias agravantes e atenuantes [ICVM-607/2019::art-62, ICVM-607/2019::art-63]. + +Em relação ao cálculo, as circunstâncias agravantes do art. 65 impactam a pena da seguinte forma: + +- **Multa:** A penalidade de multa é acrescida em até 25% para cada agravante verificada [ICVM-607/2019::art-65::par-1]. +- **Suspensão, inabilitação e proibição:** Estas penalidades são acrescidas em até 25% para cada agravante verificada, calculando-se o acréscimo sobre o número de meses da pena-base e desprezando-se as frações [ICVM-607/2019::art-65::par-2]. + +Vale ressaltar que as agravantes só são aplicadas quando não constituem ou qualificam a própria infração [ICVM-607/2019::art-65]. + +### Your scores + +| `q160-hybrid_rrf` | 0.0 / 0.5 / 1.0 | notes | +| --- | --- | --- | +| faithfulness | | | +| answer_relevancy | | | + +--- + +## 21. `q011-reranked` + +- Class: **section_comparative** +- Strategy: `reranked` + +### Question + +Compare as regras de fornecimento de informações sigilosas ao Poder Judiciário (art. 3º) e ao Poder Legislativo Federal (art. 4º) na LC 105/2001. + +### Reference answer (golden set) + +Ao Poder Judiciário, as informações ordenadas são prestadas preservando o caráter sigiloso mediante acesso restrito às partes do processo (art. 3º). Ao Poder Legislativo Federal, as informações e documentos sigilosos são fornecidos quando fundamentadamente necessários ao exercício de competências constitucionais e legais, sendo que, no caso de comissões parlamentares de inquérito, as solicitações devem ser previamente aprovadas pelo plenário da respectiva Casa ou comissão (art. 4º). + +### Cited authoritative text + +**`LC-105/2001::art-3`** + +> Art. 3o Serão prestadas pelo Banco Central do Brasil, pela Comissão de Valores Mobiliários e pelas instituições financeiras as informações ordenadas pelo Poder Judiciário, preservado o seu caráter sigiloso mediante acesso restrito às partes, que delas não poderão servir-se para fins estranhos à lide. +> § 1o Dependem de prévia autorização do Poder Judiciário a prestação de informações e o fornecimento de documentos sigilosos solicitados por comissão de inquérito administrativo destinada a apurar responsabilidade de servidor público por infração praticada no exercício de suas atribuições, ou que tenha relação com as atribuições do cargo em que se encontre investido. +> § 2o Nas hipóteses do § 1o, o requerimento de quebra de sigilo independe da existência de processo judicial em curso. +> § 3o Além dos casos previstos neste artigo o Banco Central do Brasil e a Comissão de Valores Mobiliários fornecerão à Advocacia-Geral da União as informações e os documentos necessários à defesa da União nas ações em que seja parte. + +**`LC-105/2001::art-4`** + +> Art. 4o O Banco Central do Brasil e a Comissão de Valores Mobiliários, nas áreas de suas atribuições, e as instituições financeiras fornecerão ao Poder Legislativo Federal as informações e os documentos sigilosos que, fundamentadamente, se fizerem necessários ao exercício de suas respectivas competências constitucionais e legais. +> § 1o As comissões parlamentares de inquérito, no exercício de sua competência constitucional e legal de ampla investigação, obterão as informações e documentos sigilosos de que necessitarem, diretamente das instituições financeiras, ou por intermédio do Banco Central do Brasil ou da Comissão de Valores Mobiliários. +> § 2o As solicitações de que trata este artigo deverão ser previamente aprovadas pelo Plenário da Câmara dos Deputados, do Senado Federal, ou do plenário de suas respectivas comissões parlamentares de inquérito. + +**`LC-105/2001::art-4::par-1`** + +> § 1o As comissões parlamentares de inquérito, no exercício de sua competência constitucional e legal de ampla investigação, obterão as informações e documentos sigilosos de que necessitarem, diretamente das instituições financeiras, ou por intermédio do Banco Central do Brasil ou da Comissão de Valores Mobiliários. + +**`LC-105/2001::art-4::par-2`** + +> § 2o As solicitações de que trata este artigo deverão ser previamente aprovadas pelo Plenário da Câmara dos Deputados, do Senado Federal, ou do plenário de suas respectivas comissões parlamentares de inquérito. + +### Generated answer + +As regras para o fornecimento de informações sigilosas ao Poder Judiciário e ao Poder Legislativo Federal, conforme a LC 105/2001, apresentam as seguintes características: + +**Fornecimento ao Poder Judiciário (Art. 3º):** + +- **Abrangência:** As informações são prestadas pelo Banco Central do Brasil, pela Comissão de Valores Mobiliários (CVM) e pelas instituições financeiras mediante ordem do Poder Judiciário [LC-105/2001::art-3]. +- **Sigilo:** O caráter sigiloso das informações é preservado, com acesso restrito às partes, que não podem utilizá-las para fins estranhos à lide [LC-105/2001::art-3]. +- **Comissões de Inquérito Administrativo:** O fornecimento de documentos sigilosos para comissões de inquérito administrativo (que apurem responsabilidade de servidor público) depende de prévia autorização judicial, sendo que, nestes casos, o requerimento independe da existência de processo judicial em curso [LC-105/2001::art-3::par-1, LC-105/2001::art-3::par-2]. + +**Fornecimento ao Poder Legislativo Federal (Art. 4º):** + +- **Abrangência:** O Banco Central, a CVM e as instituições financeiras fornecem as informações e documentos sigilosos que se fizerem necessários ao exercício das competências constitucionais e legais do Poder Legislativo [LC-105/2001::art-4]. +- **Fundamentação:** As solicitações devem ser fundamentadas [LC-105/2001::art-4]. +- **Comissões Parlamentares de Inquérito (CPIs):** As CPIs podem obter as informações diretamente das instituições financeiras ou por intermédio do Banco Central ou da CVM [LC-105/2001::art-4::par-1]. +- **Aprovação Prévia:** As solicitações feitas ao Poder Legislativo devem ser previamente aprovadas pelo Plenário da Câmara dos Deputados, do Senado Federal ou pelo plenário de suas respectivas CPIs [LC-105/2001::art-4::par-2]. + +### Your scores + +| `q011-reranked` | 0.0 / 0.5 / 1.0 | notes | +| --- | --- | --- | +| faithfulness | | | +| answer_relevancy | | | + +--- + +## 22. `q057-sac` + +- Class: **semantic** +- Strategy: `sac` + +### Question + +Quais informações sobre o tratamento de dados devem ser disponibilizadas ao titular de forma clara e ostensiva, segundo o art. 9º da LGPD? + +### Reference answer (golden set) + +Devem ser disponibilizadas informações sobre a finalidade específica do tratamento, a forma e duração do tratamento, a identificação do controlador, informações de contato, uso compartilhado de dados, responsabilidades dos agentes, e os direitos do titular (art. 9º, caput). + +### Cited authoritative text + +**`LEI-13709/2018::art-9::inc-i`** + +> I - finalidade específica do tratamento; + +**`LEI-13709/2018::art-9::inc-ii`** + +> II - forma e duração do tratamento, observados os segredos comercial e industrial; + +**`LEI-13709/2018::art-9::inc-iii`** + +> III - identificação do controlador; + +**`LEI-13709/2018::art-9::inc-iv`** + +> IV - informações de contato do controlador; + +**`LEI-13709/2018::art-9::inc-v`** + +> V - informações acerca do uso compartilhado de dados pelo controlador e a finalidade; + +**`LEI-13709/2018::art-9::inc-vi`** + +> VI - responsabilidades dos agentes que realizarão o tratamento; e + +**`LEI-13709/2018::art-9::inc-vii`** + +> VII - direitos do titular, com menção explícita aos direitos contidos no art. 18 desta Lei. + +### Generated answer + +Segundo o art. 9º da LGPD, o titular tem direito ao acesso facilitado a informações sobre o tratamento de seus dados, que devem ser disponibilizadas de forma clara, adequada e ostensiva, incluindo: + +- A finalidade específica do tratamento [LEI-13709/2018::art-9::inc-i]; +- A forma e a duração do tratamento, observados os segredos comercial e industrial [LEI-13709/2018::art-9::inc-ii]; +- A identificação do controlador [LEI-13709/2018::art-9::inc-iii]; +- As informações de contato do controlador [LEI-13709/2018::art-9::inc-iv]; +- Informações acerca do uso compartilhado de dados pelo controlador e a finalidade [LEI-13709/2018::art-9::inc-v]; +- As responsabilidades dos agentes que realizarão o tratamento [LEI-13709/2018::art-9::inc-vi]; +- Os direitos do titular, com menção explícita aos direitos contidos no art. 18 da referida Lei [LEI-13709/2018::art-9::inc-vii]. + +### Your scores + +| `q057-sac` | 0.0 / 0.5 / 1.0 | notes | +| --- | --- | --- | +| faithfulness | | | +| answer_relevancy | | | + +--- + +## 23. `q129-contextual` + +- Class: **global** +- Strategy: `contextual` + +### Question + +De modo geral, quais são as etapas do rito processual sancionador estabelecido pela ICVM 607/2019 até a apresentação de defesa? + +### Reference answer (golden set) + +O processo se inicia com a lavratura de termo de acusação (art. 6º), podendo ser precedido de inquérito administrativo (art. 8º); instaura-se com a citação dos acusados (art. 21); o acusado apresenta defesa em até 30 dias (art. 29); e após a defesa, é designado Relator por sorteio (art. 31). + +### Cited authoritative text + +**`ICVM-607/2019::art-7`** + +> Art. 7º. Antes da citação dos acusados para apresentação de defesa, a PFE emitirá parecer +> sobre o termo de acusação, no prazo de 30 (trinta) dias contados da data de recebimento do termo +> de acusação, com o seguinte escopo: +> I – exame do cumprimento do art. 5º; +> II – análise objetiva da observância dos requisitos do art. 6º; e +> III – exame da adequação do rito adotado para o processo administrativo sancionador. +> § 1° Considerando o parecer da PFE, a superintendência tomará as providências que +> considerar cabíveis, podendo, inclusive, arquivar o processo, adequar o rito processual ou realizar +> eventuais ajustes no termo de acusação. +> § 2° O superintendente deverá justificar a não adoção de eventuais providências +> recomendadas pelo parecer. +> § 3º O parecer da PFE não será obrigatório nos processos administrativos sancionadores +> submetidos ao rito simplificado de que trata o art. 73 desta Instrução. +> § 4º Sem prejuízo da emissão do parecer de que trata este artigo, as superintendências +> poderão solicitar assessoramento jurídico direto à PFE ainda na fase de instrução. +> COMISSÃO DE VALORES MOBILIÁRIOS +> Rua Sete de Setembro, 111/2-5º e 23-34º Andares, Centro, Rio de Janeiro/RJ – CEP: 20050-901 – Brasil - Tel.: (21) 3554-8686 +> Rua Cincinato Braga, 340/2º, 3º e 4º Andares, Bela Vista, São Paulo/ SP – CEP: 01333-010 – Brasil - Tel.: (11) 2146-2000 +> SCN Q.02 – Bl. A – Ed. Corporate Financial Center, S.404/4º Andar, Brasília/DF – CEP: 70712-900 – Brasil -Tel.: (61) 3327-2030/2031 +> +> INSTRUÇÃO CVM Nº 607, DE 17 DE JUNHO DE 2019 +> 6 + +**`ICVM-607/2019::art-7::par-3`** + +> § 3º O parecer da PFE não será obrigatório nos processos administrativos sancionadores +> submetidos ao rito simplificado de que trata o art. 73 desta Instrução. + +**`ICVM-607/2019::art-7::par-1`** + +> § 1° Considerando o parecer da PFE, a superintendência tomará as providências que +> considerar cabíveis, podendo, inclusive, arquivar o processo, adequar o rito processual ou realizar +> eventuais ajustes no termo de acusação. + +**`ICVM-607/2019::art-21`** + +> Art. 21. Considera-se instaurado o processo administrativo sancionador com a citação dos +> acusados para apresentação de defesa. +> § 1º A citação conterá: +> I – a identificação do acusado; +> II – a indicação dos fatos imputados ao acusado; +> III – a finalidade da citação; +> IV – o prazo para a apresentação de defesa; +> V – a informação da continuidade do processo, independentemente de seu comparecimento; +> VI – o dever do acusado, ou de procurador por ele constituído, de se cadastrar no sistema de +> processo eletrônico existente na página da CVM na rede mundial de computadores para fins de +> acesso aos autos e posterior acompanhamento do andamento do processo; e +> VII – o aviso de que o acusado poderá propor a celebração de termo de compromisso, em +> conformidade com o disposto no Capítulo IV desta Instrução. +> COMISSÃO DE VALORES MOBILIÁRIOS +> Rua Sete de Setembro, 111/2-5º e 23-34º Andares, Centro, Rio de Janeiro/RJ – CEP: 20050-901 – Brasil - Tel.: (21) 3554-8686 +> Rua Cincinato Braga, 340/2º, 3º e 4º Andares, Bela Vista, São Paulo/ SP – CEP: 01333-010 – Brasil - Tel.: (11) 2146-2000 +> SCN Q.02 – Bl. A – Ed. Corporate Financial Center, S.404/4º Andar, Brasília/DF – CEP: 70712-900 – Brasil -Tel.: (61) 3327-2030/2031 +> +> INSTRUÇÃO CVM Nº 607, DE 17 DE JUNHO DE 2019 +> 10 +> § 2º O requisito de que trata o inciso II do § 1º poderá ser atendido por meio da juntada do +> termo ou da peça de acusação. +> § 3º Quando se tratar de processo em meio físico, a citação deverá conter, além dos requisitos +> previstos no § 1º, o termo de acusação ou a peça acusatória, a depender do caso. +> § 4º O acusado que, embora citado, não apresentar defesa será considerado revel. + +**`ICVM-607/2019::art-21::par-1`** + +> § 1º A citação conterá: +> I – a identificação do acusado; +> II – a indicação dos fatos imputados ao acusado; +> III – a finalidade da citação; +> IV – o prazo para a apresentação de defesa; +> V – a informação da continuidade do processo, independentemente de seu comparecimento; +> VI – o dever do acusado, ou de procurador por ele constituído, de se cadastrar no sistema de +> processo eletrônico existente na página da CVM na rede mundial de computadores para fins de +> acesso aos autos e posterior acompanhamento do andamento do processo; e +> VII – o aviso de que o acusado poderá propor a celebração de termo de compromisso, em +> conformidade com o disposto no Capítulo IV desta Instrução. +> COMISSÃO DE VALORES MOBILIÁRIOS +> Rua Sete de Setembro, 111/2-5º e 23-34º Andares, Centro, Rio de Janeiro/RJ – CEP: 20050-901 – Brasil - Tel.: (21) 3554-8686 +> Rua Cincinato Braga, 340/2º, 3º e 4º Andares, Bela Vista, São Paulo/ SP – CEP: 01333-010 – Brasil - Tel.: (11) 2146-2000 +> SCN Q.02 – Bl. A – Ed. Corporate Financial Center, S.404/4º Andar, Brasília/DF – CEP: 70712-900 – Brasil -Tel.: (61) 3327-2030/2031 +> +> INSTRUÇÃO CVM Nº 607, DE 17 DE JUNHO DE 2019 +> 10 + +**`ICVM-607/2019::art-29`** + +> Art. 29. O acusado deverá apresentar sua defesa por escrito no prazo de 30 (trinta) dias após a +> citação, oportunidade em que deverá juntar os documentos destinados a provar suas alegações e +> especificar as demais provas que pretenda produzir, observado o disposto nos arts. 42 e 43 desta +> Instrução. +> § 1º O interessado deverá manifestar sua intenção de celebrar termo de compromisso até o +> término do prazo para a apresentação de defesa, e sem prejuízo do ônus de apresentação desta. +> § 2º A manifestação de intenção ou a apresentação de proposta de termo de compromisso não +> suspende nem interrompe o prazo para apresentação da defesa. +> COMISSÃO DE VALORES MOBILIÁRIOS +> Rua Sete de Setembro, 111/2-5º e 23-34º Andares, Centro, Rio de Janeiro/RJ – CEP: 20050-901 – Brasil - Tel.: (21) 3554-8686 +> Rua Cincinato Braga, 340/2º, 3º e 4º Andares, Bela Vista, São Paulo/ SP – CEP: 01333-010 – Brasil - Tel.: (11) 2146-2000 +> SCN Q.02 – Bl. A – Ed. Corporate Financial Center, S.404/4º Andar, Brasília/DF – CEP: 70712-900 – Brasil -Tel.: (61) 3327-2030/2031 +> +> INSTRUÇÃO CVM Nº 607, DE 17 DE JUNHO DE 2019 +> 14 +> § 3º Serão computados individualmente os prazos para todas as manifestações dos acusados, +> sendo admitida uma única prorrogação pelo mesmo prazo, diante de pedido devidamente +> fundamentado. +> § 4º Os acusados que constituírem o mesmo procurador e apresentarem defesa conjunta terão +> o mesmo prazo para se manifestarem nos autos, contado da citação que for efetivada por último, nos +> termos do art. 29, § 3º, desta Instrução. +> § 5º Nos processos sancionadores instaurados em desfavor de múltiplos acusados, as defesas +> serão consideradas sigilosas e não serão fornecidas a terceiros ou a outros acusados até o +> encerramento do último prazo de apresentação de defesa. + +**`ICVM-607/2019::art-21::par-4`** + +> § 4º O acusado que, embora citado, não apresentar defesa será considerado revel. + +### Generated answer + +De acordo com a Instrução CVM nº 607/2019, as etapas do rito processual sancionador até a apresentação da defesa são: + +1. **Parecer da PFE:** Antes da citação, a Procuradoria Federal Especializada (PFE) deve emitir um parecer sobre o termo de acusação no prazo de 30 dias, examinando o cumprimento de requisitos legais e a adequação do rito [ICVM-607/2019::art-7]. Este parecer não é obrigatório em processos submetidos ao rito simplificado [ICVM-607/2019::art-7::par-3]. +2. **Providências da Superintendência:** Com base no parecer da PFE, a superintendência pode arquivar o processo, adequar o rito ou realizar ajustes no termo de acusação [ICVM-607/2019::art-7::par-1]. +3. **Citação:** O processo administrativo sancionador é considerado instaurado com a citação dos acusados [ICVM-607/2019::art-21]. A citação deve conter informações como a identificação do acusado, os fatos imputados, o prazo para defesa e o aviso sobre a possibilidade de propor termo de compromisso [ICVM-607/2019::art-21::par-1]. +4. **Apresentação de Defesa:** O acusado deve apresentar sua defesa por escrito no prazo de 30 dias após a citação, juntando os documentos probatórios e especificando as provas que pretende produzir [ICVM-607/2019::art-29]. Caso o acusado não apresente defesa, será considerado revel [ICVM-607/2019::art-21::par-4]. + +### Your scores + +| `q129-contextual` | 0.0 / 0.5 / 1.0 | notes | +| --- | --- | --- | +| faithfulness | | | +| answer_relevancy | | | + +--- + +## 24. `q190-parent_child` + +- Class: **unanswerable** · **UNANSWERABLE** +- Strategy: `parent_child` + +### Question + +Qual é o percentual médio de propostas de Acordo de Supervisão aceitas pela CVM desde a edição da ICVM 607/2019? + +### Reference answer (golden set) + +A ICVM 607/2019 estabelece as regras procedimentais para o Acordo de Supervisão, mas não contém dados estatísticos sobre a taxa de aceitação de propostas. + +### Cited authoritative text + +_The answer cites nothing._ + +### Generated answer + +As informações fornecidas não contêm dados estatísticos ou históricos sobre o percentual de propostas de Acordo de Supervisão aceitas pela CVM desde a edição da Instrução CVM nº 607/2019. O contexto limita-se a descrever os critérios, procedimentos e requisitos formais para a celebração e o julgamento desses acordos. + +### Your scores + +| `q190-parent_child` | 0.0 / 0.5 / 1.0 | notes | +| --- | --- | --- | +| faithfulness | | | +| answer_relevancy | | | +| abstention | | | + +--- + +## 25. `q228-sac_contextual` + +- Class: **multi_hop** +- Strategy: `sac_contextual` + +### Question + +Como o adiamento de sessão de julgamento por motivo de força maior (art. 50, § 4º) se relaciona com a exigência de presença mínima de membros do Colegiado (art. 50, caput) na ICVM 607/2019? + +### Reference answer (golden set) + +O art. 50, caput, exige a presença de no mínimo 3 membros do Colegiado para a sessão se realizar; se isso não ocorrer por motivo de força maior, o art. 50, § 4º, permite que a sessão seja transferida para o primeiro dia útil seguinte, sem necessidade de nova convocação. + +### Cited authoritative text + +**`ICVM-607/2019::art-50`** + +> Art. 50. A sessão será presidida pelo Presidente da CVM ou, na sua ausência ou +> impedimento, por seu substituto eventual e somente será realizada com a presença de no mínimo 3 +> (três) membros do Colegiado. +> § 1º A participação dos membros do Colegiado nas sessões de julgamento poderá ocorrer por +> videoconferência. +> COMISSÃO DE VALORES MOBILIÁRIOS +> Rua Sete de Setembro, 111/2-5º e 23-34º Andares, Centro, Rio de Janeiro/RJ – CEP: 20050-901 – Brasil - Tel.: (21) 3554-8686 +> Rua Cincinato Braga, 340/2º, 3º e 4º Andares, Bela Vista, São Paulo/ SP – CEP: 01333-010 – Brasil - Tel.: (11) 2146-2000 +> SCN Q.02 – Bl. A – Ed. Corporate Financial Center, S.404/4º Andar, Brasília/DF – CEP: 70712-900 – Brasil -Tel.: (61) 3327-2030/2031 +> +> INSTRUÇÃO CVM Nº 607, DE 17 DE JUNHO DE 2019 +> 21 +> § 2º No julgamento dos processos administrativos sancionadores em que não comparecer +> nenhum acusado ou nenhum de seus respectivos procuradores constituídos nos autos, a sessão +> poderá realizar-se por meio eletrônico. +> § 3º Considerando o andamento dos trabalhos da sessão, fica facultado ao Presidente +> suspendê-la e reiniciá-la no dia útil subsequente, independente de nova convocação e publicação. +> § 4º A sessão que não se realizar, por motivo de força maior, poderá ser transferida para o +> primeiro dia útil seguinte, na hora anteriormente marcada, independentemente de nova convocação +> e publicação. + +**`ICVM-607/2019::art-50::par-4`** + +> § 4º A sessão que não se realizar, por motivo de força maior, poderá ser transferida para o +> primeiro dia útil seguinte, na hora anteriormente marcada, independentemente de nova convocação +> e publicação. + +### Generated answer + +A Instrução CVM 607/2019 estabelece que a sessão de julgamento só pode ser realizada com a presença de, no mínimo, 3 (três) membros do Colegiado [ICVM-607/2019::art-50]. Caso a sessão não ocorra por motivo de força maior, ela poderá ser transferida para o primeiro dia útil seguinte, no mesmo horário, sem a necessidade de nova convocação ou publicação [ICVM-607/2019::art-50::par-4]. + +Embora o texto não explicite uma relação direta de dependência entre o quórum mínimo e o motivo de força maior, a regra do art. 50, § 4º, funciona como uma exceção procedimental que permite a continuidade dos trabalhos em data próxima quando a sessão é impedida de ocorrer, mantendo-se a validade da pauta original sem a necessidade de novos trâmites de convocação [ICVM-607/2019::art-50::par-4]. + +### Your scores + +| `q228-sac_contextual` | 0.0 / 0.5 / 1.0 | notes | +| --- | --- | --- | +| faithfulness | | | +| answer_relevancy | | | + +--- + +## 26. `q011-dense` + +- Class: **section_comparative** +- Strategy: `dense` + +### Question + +Compare as regras de fornecimento de informações sigilosas ao Poder Judiciário (art. 3º) e ao Poder Legislativo Federal (art. 4º) na LC 105/2001. + +### Reference answer (golden set) + +Ao Poder Judiciário, as informações ordenadas são prestadas preservando o caráter sigiloso mediante acesso restrito às partes do processo (art. 3º). Ao Poder Legislativo Federal, as informações e documentos sigilosos são fornecidos quando fundamentadamente necessários ao exercício de competências constitucionais e legais, sendo que, no caso de comissões parlamentares de inquérito, as solicitações devem ser previamente aprovadas pelo plenário da respectiva Casa ou comissão (art. 4º). + +### Cited authoritative text + +**`LC-105/2001::art-3`** + +> Art. 3o Serão prestadas pelo Banco Central do Brasil, pela Comissão de Valores Mobiliários e pelas instituições financeiras as informações ordenadas pelo Poder Judiciário, preservado o seu caráter sigiloso mediante acesso restrito às partes, que delas não poderão servir-se para fins estranhos à lide. +> § 1o Dependem de prévia autorização do Poder Judiciário a prestação de informações e o fornecimento de documentos sigilosos solicitados por comissão de inquérito administrativo destinada a apurar responsabilidade de servidor público por infração praticada no exercício de suas atribuições, ou que tenha relação com as atribuições do cargo em que se encontre investido. +> § 2o Nas hipóteses do § 1o, o requerimento de quebra de sigilo independe da existência de processo judicial em curso. +> § 3o Além dos casos previstos neste artigo o Banco Central do Brasil e a Comissão de Valores Mobiliários fornecerão à Advocacia-Geral da União as informações e os documentos necessários à defesa da União nas ações em que seja parte. + +**`LC-105/2001::art-4`** + +> Art. 4o O Banco Central do Brasil e a Comissão de Valores Mobiliários, nas áreas de suas atribuições, e as instituições financeiras fornecerão ao Poder Legislativo Federal as informações e os documentos sigilosos que, fundamentadamente, se fizerem necessários ao exercício de suas respectivas competências constitucionais e legais. +> § 1o As comissões parlamentares de inquérito, no exercício de sua competência constitucional e legal de ampla investigação, obterão as informações e documentos sigilosos de que necessitarem, diretamente das instituições financeiras, ou por intermédio do Banco Central do Brasil ou da Comissão de Valores Mobiliários. +> § 2o As solicitações de que trata este artigo deverão ser previamente aprovadas pelo Plenário da Câmara dos Deputados, do Senado Federal, ou do plenário de suas respectivas comissões parlamentares de inquérito. + +**`LC-105/2001::art-4::par-1`** + +> § 1o As comissões parlamentares de inquérito, no exercício de sua competência constitucional e legal de ampla investigação, obterão as informações e documentos sigilosos de que necessitarem, diretamente das instituições financeiras, ou por intermédio do Banco Central do Brasil ou da Comissão de Valores Mobiliários. + +**`LC-105/2001::art-4::par-2`** + +> § 2o As solicitações de que trata este artigo deverão ser previamente aprovadas pelo Plenário da Câmara dos Deputados, do Senado Federal, ou do plenário de suas respectivas comissões parlamentares de inquérito. + +### Generated answer + +As regras para o fornecimento de informações sigilosas pelo Banco Central do Brasil, pela Comissão de Valores Mobiliários (CVM) e pelas instituições financeiras diferem conforme o Poder solicitante, conforme estabelecido na Lei Complementar nº 105/2001: + +**Fornecimento ao Poder Judiciário (Art. 3º):** + +- **Obrigatoriedade:** As instituições devem prestar as informações ordenadas pelo Poder Judiciário [LC-105/2001::art-3]. +- **Preservação do sigilo:** O caráter sigiloso deve ser preservado mediante acesso restrito às partes, que não podem utilizar as informações para fins estranhos à lide [LC-105/2001::art-3]. +- **Comissões de inquérito administrativo:** Caso a solicitação venha de uma comissão de inquérito administrativo (para apurar responsabilidade de servidor público), é necessária a prévia autorização do Poder Judiciário, independentemente da existência de processo judicial em curso [LC-105/2001::art-3::par-1, LC-105/2001::art-3::par-2]. + +**Fornecimento ao Poder Legislativo Federal (Art. 4º):** + +- **Fundamentação:** As informações e documentos sigilosos devem ser fornecidos quando, fundamentadamente, se fizerem necessários ao exercício das competências constitucionais e legais do Poder Legislativo [LC-105/2001::art-4]. +- **Comissões Parlamentares de Inquérito (CPIs):** As CPIs podem obter as informações diretamente das instituições financeiras ou por intermédio do Banco Central ou da CVM, no exercício de sua competência de ampla investigação [LC-105/2001::art-4::par-1]. +- **Aprovação prévia:** Diferente do Judiciário, as solicitações feitas ao Legislativo exigem aprovação prévia pelo Plenário da Câmara dos Deputados, do Senado Federal ou pelo plenário das respectivas comissões parlamentares de inquérito [LC-105/2001::art-4::par-2]. + +### Your scores + +| `q011-dense` | 0.0 / 0.5 / 1.0 | notes | +| --- | --- | --- | +| faithfulness | | | +| answer_relevancy | | | + +--- + +## 27. `q129-raptor` + +- Class: **global** +- Strategy: `raptor` + +### Question + +De modo geral, quais são as etapas do rito processual sancionador estabelecido pela ICVM 607/2019 até a apresentação de defesa? + +### Reference answer (golden set) + +O processo se inicia com a lavratura de termo de acusação (art. 6º), podendo ser precedido de inquérito administrativo (art. 8º); instaura-se com a citação dos acusados (art. 21); o acusado apresenta defesa em até 30 dias (art. 29); e após a defesa, é designado Relator por sorteio (art. 31). + +### Cited authoritative text + +**`ICVM-607/2019::art-5`** + +> Art. 5º Previamente à formulação da acusação, as superintendências deverão diligenciar no +> sentido de obter diretamente do investigado esclarecimentos sobre os fatos que podem ser a ele +> imputados. +> Parágrafo único. Considera-se atendido o disposto no caput sempre que o investigado: +> I – tenha prestado depoimento pessoal ou se manifestado voluntariamente acerca dos fatos +> que podem ser a ele imputados; ou +> II – tenha sido oficiado para prestar esclarecimentos sobre os fatos que podem ser a ele +> imputados, ainda que não o faça. + +**`ICVM-607/2019::art-7`** + +> Art. 7º. Antes da citação dos acusados para apresentação de defesa, a PFE emitirá parecer +> sobre o termo de acusação, no prazo de 30 (trinta) dias contados da data de recebimento do termo +> de acusação, com o seguinte escopo: +> I – exame do cumprimento do art. 5º; +> II – análise objetiva da observância dos requisitos do art. 6º; e +> III – exame da adequação do rito adotado para o processo administrativo sancionador. +> § 1° Considerando o parecer da PFE, a superintendência tomará as providências que +> considerar cabíveis, podendo, inclusive, arquivar o processo, adequar o rito processual ou realizar +> eventuais ajustes no termo de acusação. +> § 2° O superintendente deverá justificar a não adoção de eventuais providências +> recomendadas pelo parecer. +> § 3º O parecer da PFE não será obrigatório nos processos administrativos sancionadores +> submetidos ao rito simplificado de que trata o art. 73 desta Instrução. +> § 4º Sem prejuízo da emissão do parecer de que trata este artigo, as superintendências +> poderão solicitar assessoramento jurídico direto à PFE ainda na fase de instrução. +> COMISSÃO DE VALORES MOBILIÁRIOS +> Rua Sete de Setembro, 111/2-5º e 23-34º Andares, Centro, Rio de Janeiro/RJ – CEP: 20050-901 – Brasil - Tel.: (21) 3554-8686 +> Rua Cincinato Braga, 340/2º, 3º e 4º Andares, Bela Vista, São Paulo/ SP – CEP: 01333-010 – Brasil - Tel.: (11) 2146-2000 +> SCN Q.02 – Bl. A – Ed. Corporate Financial Center, S.404/4º Andar, Brasília/DF – CEP: 70712-900 – Brasil -Tel.: (61) 3327-2030/2031 +> +> INSTRUÇÃO CVM Nº 607, DE 17 DE JUNHO DE 2019 +> 6 + +**`ICVM-607/2019::art-21`** + +> Art. 21. Considera-se instaurado o processo administrativo sancionador com a citação dos +> acusados para apresentação de defesa. +> § 1º A citação conterá: +> I – a identificação do acusado; +> II – a indicação dos fatos imputados ao acusado; +> III – a finalidade da citação; +> IV – o prazo para a apresentação de defesa; +> V – a informação da continuidade do processo, independentemente de seu comparecimento; +> VI – o dever do acusado, ou de procurador por ele constituído, de se cadastrar no sistema de +> processo eletrônico existente na página da CVM na rede mundial de computadores para fins de +> acesso aos autos e posterior acompanhamento do andamento do processo; e +> VII – o aviso de que o acusado poderá propor a celebração de termo de compromisso, em +> conformidade com o disposto no Capítulo IV desta Instrução. +> COMISSÃO DE VALORES MOBILIÁRIOS +> Rua Sete de Setembro, 111/2-5º e 23-34º Andares, Centro, Rio de Janeiro/RJ – CEP: 20050-901 – Brasil - Tel.: (21) 3554-8686 +> Rua Cincinato Braga, 340/2º, 3º e 4º Andares, Bela Vista, São Paulo/ SP – CEP: 01333-010 – Brasil - Tel.: (11) 2146-2000 +> SCN Q.02 – Bl. A – Ed. Corporate Financial Center, S.404/4º Andar, Brasília/DF – CEP: 70712-900 – Brasil -Tel.: (61) 3327-2030/2031 +> +> INSTRUÇÃO CVM Nº 607, DE 17 DE JUNHO DE 2019 +> 10 +> § 2º O requisito de que trata o inciso II do § 1º poderá ser atendido por meio da juntada do +> termo ou da peça de acusação. +> § 3º Quando se tratar de processo em meio físico, a citação deverá conter, além dos requisitos +> previstos no § 1º, o termo de acusação ou a peça acusatória, a depender do caso. +> § 4º O acusado que, embora citado, não apresentar defesa será considerado revel. + +**`ICVM-607/2019::art-21, par-1`** + +> _(not resolvable - the cited ID does not exist in the parsed corpus)_ + +**`ICVM-607/2019::art-21, ICVM-607/2019::art-23`** + +> _(not resolvable - the cited ID does not exist in the parsed corpus)_ + +**`ICVM-607/2019::art-26, ICVM-607/2019::art-30`** + +> _(not resolvable - the cited ID does not exist in the parsed corpus)_ + +### Generated answer + +De acordo com a Instrução CVM nº 607/2019, o rito processual sancionador até a apresentação da defesa segue, de modo geral, as seguintes etapas: + +1. **Investigação e Esclarecimentos Prévios:** As superintendências investigam as condutas e podem buscar esclarecimentos prévios do investigado [ICVM-607/2019::art-5]. +2. **Decisão sobre o Procedimento:** Com base na avaliação da conduta (considerando critérios como boa-fé, ressarcimento e impacto no mercado), a superintendência decide entre a lavratura de termo de acusação, a proposta de inquérito administrativo ou a adoção de medidas de supervisão [ICVM-607/2019::art-4, ICVM-607/2019::art-6, ICVM-607/2019::art-8]. +3. **Submissão à PFE:** Havendo elementos de autoria e materialidade, o termo de acusação é submetido à Procuradoria Federal Especializada (PFE) [ICVM-607/2019::art-7]. +4. **Instauração e Citação:** O processo administrativo sancionador é instaurado com a citação do acusado [ICVM-607/2019::art-21]. A citação deve conter a identificação, os fatos imputados, o prazo de defesa, o dever de cadastro no sistema eletrônico e o aviso sobre a possibilidade de termo de compromisso [ICVM-607/2019::art-21, par-1]. +5. **Comunicação:** A citação é realizada preferencialmente por meio eletrônico, utilizando-se a via postal ou edital no "Diário Eletrônico" de forma subsidiária [ICVM-607/2019::art-21, ICVM-607/2019::art-23]. +6. **Apresentação de Defesa:** O acusado possui o prazo de 30 dias úteis para apresentar sua defesa escrita, sendo obrigatória a regularização da representação processual em até 15 dias, sob pena de desconsideração da peça defensiva [ICVM-607/2019::art-26, ICVM-607/2019::art-30]. + +### Your scores + +| `q129-raptor` | 0.0 / 0.5 / 1.0 | notes | +| --- | --- | --- | +| faithfulness | | | +| answer_relevancy | | | + +--- + +## 28. `q017-raptor` + +- Class: **unanswerable** · **UNANSWERABLE** +- Strategy: `raptor` + +### Question + +Qual é o valor da multa pecuniária prevista na RES-CMN-5274/2025 para o descumprimento do prazo de adaptação até março de 2026? + +### Reference answer (golden set) + +A RES-CMN-5274/2025 não estabelece um valor de multa pecuniária para o descumprimento desse prazo; o texto da resolução não trata dessa questão. + +### Cited authoritative text + +**`RES-CMN-5274/2025::art-2`** + +> Art. 2º As instituições em funcionamento na data da entrada em vigor desta Resolução devem promover as adaptações necessárias à adequação ao disposto nesta Resolução até 1º de março de 2026. + +### Generated answer + +A Resolução CMN nº 5.274/2025 não contém informações sobre o valor de multas pecuniárias para o descumprimento do prazo de adaptação. O texto normativo estabelece apenas que as instituições em funcionamento devem promover as adaptações necessárias até 1º de março de 2026 [RES-CMN-5274/2025::art-2]. + +### Your scores + +| `q017-raptor` | 0.0 / 0.5 / 1.0 | notes | +| --- | --- | --- | +| faithfulness | | | +| answer_relevancy | | | +| abstention | | | + +--- + +## 29. `q024-contextual` + +- Class: **exact_factual** +- Strategy: `contextual` + +### Question + +Quem deve aprovar a política de segurança cibernética e o plano de ação e resposta a incidentes, segundo o art. 9º da RES-CMN-4893/2021? + +### Reference answer (golden set) + +Devem ser aprovados pelo conselho de administração ou, na sua inexistência, pela diretoria da instituição (art. 9º). + +### Cited authoritative text + +**`RES-CMN-4893/2021::art-9`** + +> Art. 9º  A política de segurança cibernética referida no art. 2º e o plano de ação e de resposta a incidentes mencionado no art. 6º devem ser +> aprovados pelo conselho de administração ou, na sua inexistência, pela diretoria da instituição. + +### Generated answer + +Segundo o art. 9º da Resolução CMN nº 4.893/2021, a política de segurança cibernética e o plano de ação e de resposta a incidentes devem ser aprovados pelo conselho de administração ou, na sua inexistência, pela diretoria da instituição [RES-CMN-4893/2021::art-9]. + +### Your scores + +| `q024-contextual` | 0.0 / 0.5 / 1.0 | notes | +| --- | --- | --- | +| faithfulness | | | +| answer_relevancy | | | + +--- + +## 30. `q193-raptor` + +- Class: **exact_factual** +- Strategy: `raptor` + +### Question + +A participação do investidor lesado na análise da proposta de termo de compromisso lhe confere a condição de parte no processo, segundo o art. 85, § 1º da ICVM 607/2019? + +### Reference answer (golden set) + +Não, a participação do investidor lesado não lhe confere a condição de parte no processo administrativo (art. 85, § 1º). + +### Cited authoritative text + +**`ICVM-607/2019::art-85::par-1`** + +> § 1º A participação do investidor lesado não lhe confere a condição de parte no processo +> administrativo. + +### Generated answer + +Não. Segundo o art. 85, § 1º, da Instrução CVM nº 607/2019, a participação do investidor lesado na análise da proposta de termo de compromisso não lhe confere a condição de parte no processo administrativo [ICVM-607/2019::art-85::par-1]. + +### Your scores + +| `q193-raptor` | 0.0 / 0.5 / 1.0 | notes | +| --- | --- | --- | +| faithfulness | | | +| answer_relevancy | | | + +--- + +## 31. `q123-hybrid_rrf` + +- Class: **numeric_tabular** +- Strategy: `hybrid_rrf` + +### Question + +Em quantos dias o instrumento de mandato de um procurador não constituído nos autos deve ser apresentado à CVM, segundo o art. 30, § 1º da ICVM 607/2019? + +### Reference answer (golden set) + +Nos 15 (quinze) dias subsequentes à apresentação da defesa (art. 30, § 1º). + +### Cited authoritative text + +**`ICVM-607/2019::art-30::par-1`** + +> § 1º Será admitida defesa firmada por procurador que não esteja constituído nos autos desde +> que o respectivo instrumento de mandato seja apresentado à CVM nos 15 (quinze) dias +> subsequentes à apresentação da defesa. + +### Generated answer + +Segundo o art. 30, § 1º da Instrução CVM nº 607/2019, o instrumento de mandato deve ser apresentado à CVM nos 15 (quinze) dias subsequentes à apresentação da defesa [ICVM-607/2019::art-30::par-1]. + +### Your scores + +| `q123-hybrid_rrf` | 0.0 / 0.5 / 1.0 | notes | +| --- | --- | --- | +| faithfulness | | | +| answer_relevancy | | | + +--- + +## 32. `q205-sac_contextual` + +- Class: **numeric_tabular** +- Strategy: `sac_contextual` + +### Question + +De quanto é o benefício exclusivo para o signatário que não for o primeiro a se qualificar em relação à infração noticiada, segundo o art. 107, § 1º da ICVM 607/2019? + +### Reference answer (golden set) + +Poderá beneficiar-se exclusivamente da redução de 1/3 (um terço) da penalidade a ela aplicável (art. 107, § 1º). + +### Cited authoritative text + +**`ICVM-607/2019::art-107::par-1`** + +> § 1º A pessoa natural ou jurídica que não for a primeira a se qualificar com respeito à +> infração noticiada ou sob investigação poderá beneficiar-se exclusivamente da redução de 1/3 (um +> terço) da penalidade a ela aplicável. + +### Generated answer + +De acordo com o art. 107, § 1º da Instrução CVM nº 607/2019, a pessoa natural ou jurídica que não for a primeira a se qualificar com respeito à infração noticiada ou sob investigação pode beneficiar-se exclusivamente da redução de 1/3 (um terço) da penalidade a ela aplicável [ICVM-607/2019::art-107::par-1]. + +### Your scores + +| `q205-sac_contextual` | 0.0 / 0.5 / 1.0 | notes | +| --- | --- | --- | +| faithfulness | | | +| answer_relevancy | | | + +--- + +## 33. `q093-hybrid_rrf` + +- Class: **semantic** +- Strategy: `hybrid_rrf` + +### Question + +O que o controlador deve levar em consideração ao estabelecer regras de boas práticas, segundo o art. 50, § 1º da LGPD? + +### Reference answer (golden set) + +Deve levar em consideração, em relação ao tratamento e aos dados, a natureza, o escopo, a finalidade e a probabilidade e a gravidade dos riscos e dos benefícios decorrentes do tratamento de dados do titular (art. 50, § 1º). + +### Cited authoritative text + +**`LEI-13709/2018::art-50::par-1`** + +> § 1º Ao estabelecer regras de boas práticas, o controlador e o operador levarão em consideração, em relação ao tratamento e aos dados, a natureza, o escopo, a finalidade e a probabilidade e a gravidade dos riscos e dos benefícios decorrentes de tratamento de dados do titular. + +### Generated answer + +Ao estabelecer regras de boas práticas, o controlador deve levar em consideração, em relação ao tratamento e aos dados, a natureza, o escopo, a finalidade e a probabilidade e a gravidade dos riscos e dos benefícios decorrentes do tratamento de dados do titular [LEI-13709/2018::art-50::par-1]. + +### Your scores + +| `q093-hybrid_rrf` | 0.0 / 0.5 / 1.0 | notes | +| --- | --- | --- | +| faithfulness | | | +| answer_relevancy | | | + +--- + +## 34. `q187-graphrag` + +- Class: **multi_hop** +- Strategy: `graphrag` + +### Question + +Como o prazo de manifestação de intenção de celebrar termo de compromisso do art. 82, § 1º, se relaciona com o prazo de apresentação de defesa do art. 29 da ICVM 607/2019? + +### Reference answer (golden set) + +O art. 29 estabelece o prazo de 30 dias após a citação para apresentação de defesa; o art. 82, § 1º, exige que a intenção de celebrar termo de compromisso seja manifestada dentro desse mesmo prazo de defesa. + +### Cited authoritative text + +_The answer cites nothing._ + +### Generated answer + +O interessado deve manifestar sua intenção de celebrar o termo de compromisso dentro do prazo estabelecido para a apresentação de defesa [ICVM-607/2019::art-82::par-1, ICVM-607/2019::art-29::par-1]. + +Essa manifestação de intenção, ou mesmo a apresentação da proposta de termo de compromisso, não suspende nem interrompe o prazo de 30 dias para a apresentação da defesa, sendo que o interessado mantém o ônus de apresentá-la [ICVM-607/2019::art-29, ICVM-607/2019::art-29::par-1, ICVM-607/2019::art-29::par-2]. + +### Your scores + +| `q187-graphrag` | 0.0 / 0.5 / 1.0 | notes | +| --- | --- | --- | +| faithfulness | | | +| answer_relevancy | | | + +--- + +## 35. `q128-hybrid_rrf` + +- Class: **section_comparative** +- Strategy: `hybrid_rrf` + +### Question + +Compare o prazo para conclusão do inquérito administrativo (art. 10) com o prazo para apresentação de defesa (art. 29) na ICVM 607/2019. + +### Reference answer (golden set) + +O inquérito administrativo deve ser concluído em 120 dias, prorrogáveis mediante pedido motivado (art. 10); já a apresentação de defesa pelo acusado, após a citação no processo sancionador, tem prazo de apenas 30 dias (art. 29) - um prazo bem mais curto, pois já parte de acusação formalizada. + +### Cited authoritative text + +**`ICVM-607/2019::art-10`** + +> Art. 10. Os trabalhos de investigação deverão ser concluídos em 120 (cento e vinte) dias +> contados da data de instauração do inquérito administrativo, podendo tal prazo ser prorrogado, mais +> de uma vez, por meio de pedido motivado encaminhado à Superintendência Geral, com indicação +> de novo prazo. +> Parágrafo único. Caberá à Superintendência Geral, com base na motivação que lhe for +> apresentada, apreciar o pedido de prorrogação de prazo, podendo, em sendo o caso, fixar prazo +> inferior ao solicitado. + +**`ICVM-607/2019::art-29`** + +> Art. 29. O acusado deverá apresentar sua defesa por escrito no prazo de 30 (trinta) dias após a +> citação, oportunidade em que deverá juntar os documentos destinados a provar suas alegações e +> especificar as demais provas que pretenda produzir, observado o disposto nos arts. 42 e 43 desta +> Instrução. +> § 1º O interessado deverá manifestar sua intenção de celebrar termo de compromisso até o +> término do prazo para a apresentação de defesa, e sem prejuízo do ônus de apresentação desta. +> § 2º A manifestação de intenção ou a apresentação de proposta de termo de compromisso não +> suspende nem interrompe o prazo para apresentação da defesa. +> COMISSÃO DE VALORES MOBILIÁRIOS +> Rua Sete de Setembro, 111/2-5º e 23-34º Andares, Centro, Rio de Janeiro/RJ – CEP: 20050-901 – Brasil - Tel.: (21) 3554-8686 +> Rua Cincinato Braga, 340/2º, 3º e 4º Andares, Bela Vista, São Paulo/ SP – CEP: 01333-010 – Brasil - Tel.: (11) 2146-2000 +> SCN Q.02 – Bl. A – Ed. Corporate Financial Center, S.404/4º Andar, Brasília/DF – CEP: 70712-900 – Brasil -Tel.: (61) 3327-2030/2031 +> +> INSTRUÇÃO CVM Nº 607, DE 17 DE JUNHO DE 2019 +> 14 +> § 3º Serão computados individualmente os prazos para todas as manifestações dos acusados, +> sendo admitida uma única prorrogação pelo mesmo prazo, diante de pedido devidamente +> fundamentado. +> § 4º Os acusados que constituírem o mesmo procurador e apresentarem defesa conjunta terão +> o mesmo prazo para se manifestarem nos autos, contado da citação que for efetivada por último, nos +> termos do art. 29, § 3º, desta Instrução. +> § 5º Nos processos sancionadores instaurados em desfavor de múltiplos acusados, as defesas +> serão consideradas sigilosas e não serão fornecidas a terceiros ou a outros acusados até o +> encerramento do último prazo de apresentação de defesa. + +**`ICVM-607/2019::art-29::par-3`** + +> § 3º Serão computados individualmente os prazos para todas as manifestações dos acusados, +> sendo admitida uma única prorrogação pelo mesmo prazo, diante de pedido devidamente +> fundamentado. + +### Generated answer + +De acordo com a Instrução CVM nº 607/2019, os prazos comparados são: + +- **Inquérito Administrativo:** Os trabalhos de investigação devem ser concluídos no prazo de 120 dias, contados a partir da data de instauração do inquérito [ICVM-607/2019::art-10]. Este prazo pode ser prorrogado mais de uma vez, mediante pedido motivado encaminhado à Superintendência Geral [ICVM-607/2019::art-10]. +- **Apresentação de Defesa:** O acusado possui o prazo de 30 dias após a citação para apresentar sua defesa por escrito [ICVM-607/2019::art-29]. Este prazo é computado individualmente para cada acusado e admite uma única prorrogação pelo mesmo período, desde que haja pedido devidamente fundamentado [ICVM-607/2019::art-29::par-3]. + +### Your scores + +| `q128-hybrid_rrf` | 0.0 / 0.5 / 1.0 | notes | +| --- | --- | --- | +| faithfulness | | | +| answer_relevancy | | | + +--- + +## 36. `q107-dense` + +- Class: **semantic** +- Strategy: `dense` + +### Question + +O que é considerado 'dado anonimizado' para os fins da LGPD, segundo o art. 5º, inciso III? + +### Reference answer (golden set) + +É o dado relativo a um titular que não possa ser identificado, considerando a utilização de meios técnicos razoáveis e disponíveis na ocasião de seu tratamento (art. 5º, III). + +### Cited authoritative text + +**`LEI-13709/2018::art-5::inc-iii`** + +> III - dado anonimizado: dado relativo a titular que não possa ser identificado, considerando a utilização de meios técnicos razoáveis e disponíveis na ocasião de seu tratamento; + +### Generated answer + +Segundo o art. 5º, inciso III, da LGPD, dado anonimizado é aquele relativo a um titular que não possa ser identificado, considerando a utilização de meios técnicos razoáveis e disponíveis na ocasião de seu tratamento [LEI-13709/2018::art-5::inc-iii]. + +### Your scores + +| `q107-dense` | 0.0 / 0.5 / 1.0 | notes | +| --- | --- | --- | +| faithfulness | | | +| answer_relevancy | | | + +--- diff --git a/docs/LLM-JUDGE-DECISION.md b/docs/LLM-JUDGE-DECISION.md index bee6a0e..0e09b70 100644 --- a/docs/LLM-JUDGE-DECISION.md +++ b/docs/LLM-JUDGE-DECISION.md @@ -29,6 +29,21 @@ Provider-free experiment: - only after exact weight/runtime pinning and human calibration; - not canonical merely because it runs locally. +Calibration workflow: + +```bash +uv run python scripts/build_calibration_worksheet.py +# Fill datasets/regrag-br/calibration/labels.json without opening .judge-sealed.json +uv run python scripts/finalize_calibration.py --show-disagreements +``` + +The builder requires evidence schema v1, which persists the exact ordered +contexts seen by the judge. A legacy run without `judge_contexts` must be rerun; +citation text is intentionally not accepted as a substitute. Rebuilding the +same workspace preserves completed human scores, while a different run/sample +fails closed. Finalization validates the three-value human scale, reports +overall and per-dimension agreement, and exits non-zero if the gate fails. + Sources consulted: - https://developers.openai.com/api/docs/models/gpt-5.4-mini diff --git a/docs/PRIVACY.md b/docs/PRIVACY.md index e552d39..e30d319 100644 --- a/docs/PRIVACY.md +++ b/docs/PRIVACY.md @@ -12,7 +12,7 @@ This document records that assessment and the controls that keep it true. | Corpus text (CMN/BCB, CVM norms, federal laws) | Official public sources, versioned snapshot under `datasets/corpus/` | Indexing, retrieval, benchmark evaluation | Official acts; not copyright-protected (art. 8, I, Law 9,610/1998); no personal data intended | Local stores (Postgres+pgvector, OpenSearch, LightRAG local storage); hosted LLM/embedding APIs (Google Gemini, OpenAI) during live runs | Indefinite (versioned snapshot is the benchmark's ground truth) | Git history rewrite + store re-index (not expected) | | RegRAG-BR golden set (questions, judgments, reference answers) | Hand-authored by the maintainer | Ground truth for evaluation | Original work, published CC BY 4.0 | Same as corpus; question text is sent to hosted LLM APIs in live runs | Indefinite (published dataset) | New dataset version | | LLM request/response payloads | Live benchmark runs | Generation, enrichment, judging; write-through call cache | Provider terms (Google, OpenAI); content is corpus/golden-set text only | `experiments//llm-cache/`, provider-side per their retention policies | Versioned with the run | Delete run directory + new run identity | -| Run evidence (manifests, events, per-question records) | Benchmark runner (ADR-0017) | Reproducibility and audit | Legitimate interest in scientific integrity; contains no personal data | `artifacts/runs/`, `experiments/` (public repo) | Indefinite (published evidence) | Remove run from `published-runs.json` + delete directories | +| Run evidence (manifests, events, per-question records, exact local judge contexts) | Benchmark runner (ADR-0017) | Reproducibility, human judge calibration, and audit | Legitimate interest in scientific integrity; contains no personal data in the current public corpus | `artifacts/runs/`, `experiments/` (public repo) | Indefinite (published evidence) | Remove run from `published-runs.json` + delete directories | | Observability traces | Optional Langfuse extra | Latency/cost telemetry | Opt-in; **metadata-only** (no prompt/completion content) per `docs/LLM_OBSERVABILITY.md` | Configured Langfuse backend | Backend policy | Backend deletion API | | Personal data | — | — | — | — | — | None processed by design | diff --git a/docs/adr/0017-auditable-evidence-lineage.md b/docs/adr/0017-auditable-evidence-lineage.md index 6939394..e3a9793 100644 --- a/docs/adr/0017-auditable-evidence-lineage.md +++ b/docs/adr/0017-auditable-evidence-lineage.md @@ -150,6 +150,7 @@ prompt-template hash generation parameters input chunk IDs input source hashes +exact ordered judge-context texts (full_local) or separately controlled content snapshots answer hash parsed citations token usage @@ -263,6 +264,10 @@ public_benchmark Private institutional runs default to hashes and metrics plus separately controlled encrypted content storage. +Judge calibration is available only when the exact ordered judge contexts are +retained locally. Hash-only records can prove identity but cannot support a +human comparison of the evidence, and citations are not a valid reconstruction. + ### Verification Provide: diff --git a/docs/adr/0018-independent-llm-judge-provider.md b/docs/adr/0018-independent-llm-judge-provider.md index ada6063..a823bb9 100644 --- a/docs/adr/0018-independent-llm-judge-provider.md +++ b/docs/adr/0018-independent-llm-judge-provider.md @@ -151,6 +151,14 @@ ADR-0007 remains mandatory. The calibration dataset SHALL contain at least 30 manually labeled samples and SHOULD grow to 50 before a public benchmark release. +For Faithfulness, the human worksheet SHALL contain the exact ordered context +texts passed to the judge for that answer. Reconstructing evidence from parsed +citations or structural IDs is not equivalent: generated summaries and malformed +or missing citations can change the material being evaluated. Citation-source +resolution remains a separate diagnostic section and SHALL NOT replace judge +contexts. Runs that did not persist exact judge contexts are ineligible for +retrospective calibration and must be rerun. + Stratify by: - all query classes; @@ -171,6 +179,11 @@ Measure: - false-unsupported rate; - abstention agreement. +Reports SHALL publish overall agreement and a breakdown per dimension. The +minimum gate applies to the overall result and independently to Faithfulness +and Answer Relevancy, so strong performance in one dimension cannot conceal a +failure in another. + Minimum acceptance: ```text diff --git a/scripts/build_calibration_worksheet.py b/scripts/build_calibration_worksheet.py new file mode 100644 index 0000000..19e08a8 --- /dev/null +++ b/scripts/build_calibration_worksheet.py @@ -0,0 +1,157 @@ +#!/usr/bin/env python3 +"""Build a blind human-labeling worksheet for judge calibration. + +Usage: + uv run python scripts/build_calibration_worksheet.py 20260726T185553Z + uv run python scripts/build_calibration_worksheet.py 20260726T185553Z --size 40 + +The run must contain ``judge_contexts`` persisted by the answer harness. +Citation text cannot reconstruct the evidence that RAGAS Faithfulness saw, +so runs created before evidence schema v1 fail closed and must be rerun. +""" + +import argparse +import json +import sys +from collections.abc import Callable +from pathlib import Path +from typing import Protocol + +ROOT = Path(__file__).resolve().parents[1] +sys.path.insert(0, str(ROOT / "src")) + +from ragforge.chunking.legal_parser import parse_norm # noqa: E402 +from ragforge.evaluation.artifact_writer import write_atomic # noqa: E402 +from ragforge.evaluation.calibration_workflow import ( # noqa: E402 + build_human_labels, + build_sealed_calibration, + calibration_feature_coverage, + load_human_labels, + load_sealed_calibration, + merge_existing_human_labels, + render_calibration_worksheet, + select_calibration_records, +) +from ragforge.evaluation.judgments import load_judgments # noqa: E402 +from ragforge.evaluation.manifest import load_corpus_manifest # noqa: E402 +from ragforge.evaluation.records import read_records_jsonl # noqa: E402 +from ragforge.ingestion.html_extractor import HtmlTextExtractor # noqa: E402 +from ragforge.ingestion.pymupdf_extractor import PyMuPdfExtractor # noqa: E402 + +OUT_DIR = ROOT / "datasets" / "regrag-br" / "calibration" + + +class _TextExtractor(Protocol): + def extract(self, path: Path) -> str: + """Extract normalized text from ``path``.""" + + +_EXTRACTOR_FACTORIES: dict[str, Callable[[], _TextExtractor]] = { + "html": HtmlTextExtractor, + "pymupdf": PyMuPdfExtractor, +} + + +def load_corpus_text() -> dict[str, dict[str, str]]: + """Resolve canonical structural IDs for citation-audit display only.""" + manifest = load_corpus_manifest(ROOT / "datasets/regrag-br/corpus_manifest.yaml") + resolved: dict[str, dict[str, str]] = {} + for document in manifest.enabled_documents: + try: + extractor_factory = _EXTRACTOR_FACTORIES[document.extractor] + text = extractor_factory().extract(ROOT / document.source_path) + tree = parse_norm(document.norm_id, text) + except Exception as exc: + print( + f" ! {document.norm_id}: {type(exc).__name__} - citation audit will show IDs only" + ) + resolved[document.norm_id] = {} + continue + + by_id: dict[str, str] = {} + for article in tree.articles: + by_id[tree.structural_id(article)] = article.full_text + stack = [(child, (child,)) for child in article.children] + while stack: + node, path = stack.pop() + by_id[tree.structural_id(article, path)] = node.full_text + stack.extend((child, (*path, child)) for child in node.children) + resolved[document.norm_id] = by_id + print(f" {document.norm_id}: {len(by_id)} structural IDs resolved") + return resolved + + +def _parse_args() -> argparse.Namespace: + parser = argparse.ArgumentParser(description=__doc__) + parser.add_argument("run_id") + parser.add_argument("--size", type=int, default=36) + return parser.parse_args() + + +def main() -> None: + """Select records and atomically publish a blind calibration workspace.""" + args = _parse_args() + records_path = ROOT / "experiments" / args.run_id / "records.jsonl" + if not records_path.exists(): + raise SystemExit(f"No such run: {records_path}") + + records = read_records_jsonl(records_path) + judgments = { + judgment.question_id: judgment + for judgment in load_judgments(ROOT / "datasets/regrag-br/judgments.json") + } + try: + sample = select_calibration_records(records, judgments, args.size) + except ValueError as exc: + raise SystemExit(str(exc)) from exc + + print("Resolving citation-audit text (judge contexts already come from the run)...") + corpus = load_corpus_text() + worksheet = render_calibration_worksheet(sample, judgments, corpus, args.run_id) + expected_labels = build_human_labels(sample) + sealed = build_sealed_calibration(sample, args.run_id) + + labels_path = OUT_DIR / "labels.json" + sealed_path = OUT_DIR / ".judge-sealed.json" + if labels_path.exists() != sealed_path.exists(): + raise SystemExit( + "calibration workspace is incomplete; labels and sealed scores must coexist" + ) + labels = expected_labels + if labels_path.exists(): + try: + existing_labels = load_human_labels(labels_path) + existing_sealed = load_sealed_calibration(sealed_path) + if existing_sealed != sealed: + raise ValueError( + "existing sealed scores belong to a different run or sample; archive the " + "calibration directory before rebuilding" + ) + labels = merge_existing_human_labels(expected_labels, existing_labels) + except ValueError as exc: + raise SystemExit(str(exc)) from exc + + write_atomic(OUT_DIR / "worksheet.md", worksheet) + write_atomic( + labels_path, + json.dumps( + [label.model_dump() for label in labels], + indent=2, + ensure_ascii=False, + allow_nan=False, + ), + ) + write_atomic( + sealed_path, + json.dumps(sealed.model_dump(), indent=2, ensure_ascii=False, allow_nan=False), + ) + + coverage = calibration_feature_coverage(sample, judgments) + print(f"Selected {len(sample)} samples; validated {len(coverage)} coverage features.") + print(f"Worksheet: {OUT_DIR / 'worksheet.md'}") + print(f"Fill in: {labels_path} ({len(labels)} scores; existing scores preserved)") + print(f"Sealed: {sealed_path} (do not open until labeling is complete)") + + +if __name__ == "__main__": + main() diff --git a/scripts/finalize_calibration.py b/scripts/finalize_calibration.py new file mode 100644 index 0000000..0cfc4be --- /dev/null +++ b/scripts/finalize_calibration.py @@ -0,0 +1,80 @@ +#!/usr/bin/env python3 +"""Validate human labels, publish a calibration report, and enforce its gate. + +Usage: + uv run python scripts/finalize_calibration.py + uv run python scripts/finalize_calibration.py --show-disagreements +""" + +import argparse +import json +import sys +from pathlib import Path + +ROOT = Path(__file__).resolve().parents[1] +sys.path.insert(0, str(ROOT / "src")) + +from ragforge.evaluation.artifact_writer import write_atomic # noqa: E402 +from ragforge.evaluation.calibration_workflow import ( # noqa: E402 + KAPPA_TARGET, + build_calibration_report, + build_calibration_samples, + calibration_gate_passed, + load_human_labels, + load_sealed_calibration, + scores_have_ordinal_disagreement, +) + +CAL_DIR = ROOT / "datasets" / "regrag-br" / "calibration" + + +def _parse_args() -> argparse.Namespace: + parser = argparse.ArgumentParser(description=__doc__) + parser.add_argument( + "--show-disagreements", + action="store_true", + help="list samples where judge and human land in different ordinal bins", + ) + return parser.parse_args() + + +def main() -> None: + """Compute the report and return failure when any required kappa misses the floor.""" + args = _parse_args() + try: + labels = load_human_labels(CAL_DIR / "labels.json") + sealed = load_sealed_calibration(CAL_DIR / ".judge-sealed.json") + samples = build_calibration_samples(labels, sealed) + report = build_calibration_report(samples, sealed.run_id) + except (OSError, ValueError) as exc: + raise SystemExit(f"invalid calibration workspace: {exc}") from exc + + write_atomic( + CAL_DIR / "report.json", + json.dumps(report, indent=2, ensure_ascii=False, allow_nan=False), + ) + print(json.dumps(report, indent=2, ensure_ascii=False, allow_nan=False)) + + if args.show_disagreements: + print("\nDisagreements (different ordinal bins):\n") + for sample in samples: + if scores_have_ordinal_disagreement(sample): + print( + f" {sample.sample_id:44s} judge={sample.judge_score:.2f} " + f"human={sample.human_score:.2f}" + ) + + if not calibration_gate_passed(report): + print("\nCalibration gate failed; judge metrics are not validated for publication.") + raise SystemExit(1) + + overall = report["overall"] + if isinstance(overall, dict) and overall.get("weighted_kappa", 0.0) >= KAPPA_TARGET: + print(f"\nCalibration passed and meets the {KAPPA_TARGET:.2f} publication target.") + else: + print("\nCalibration passed the floor but remains below the publication target.") + print(f"Report written to {CAL_DIR / 'report.json'}") + + +if __name__ == "__main__": + main() diff --git a/scripts/judge_calibration_report.py b/scripts/judge_calibration_report.py deleted file mode 100644 index 53616a8..0000000 --- a/scripts/judge_calibration_report.py +++ /dev/null @@ -1,57 +0,0 @@ -#!/usr/bin/env python3 -"""Print a judge calibration report from a human-labeled sample file (ADR-0007/ADR-0018). - -Usage: uv run python scripts/judge_calibration_report.py - -No calibration file ships with this repository: the samples it must contain -(~30+, stratified by query class, answerable/unanswerable, strong/weak -strategies, negation, exceptions, cross-references, numerical claims) are -genuine human curation work - see -src/ragforge/evaluation/judge_calibration.py for the exact expected schema -and why this script cannot generate that file itself. -""" - -import argparse -import sys -from pathlib import Path - -from ragforge.evaluation.judge_calibration import ( - compute_calibration_report, - load_calibration_samples, -) - - -def parse_args() -> argparse.Namespace: - """Parse this script's command-line options.""" - parser = argparse.ArgumentParser(description=__doc__) - parser.add_argument("calibration_file", type=Path) - return parser.parse_args() - - -def main() -> None: - """Load the calibration file and print its aggregate agreement report.""" - args = parse_args() - if not args.calibration_file.exists(): - raise SystemExit(f"calibration file not found: {args.calibration_file}") - - samples = load_calibration_samples(args.calibration_file) - report = compute_calibration_report(samples) - - print(f"Calibration report for {args.calibration_file} ({int(report['n'])} samples):\n") - for key, value in sorted(report.items()): - if key == "n": - continue - print(f" {key}: {value:.3f}") - - kappa = report["weighted_kappa"] - if kappa < 0.60: - print( - f"\nweighted_kappa={kappa:.3f} is below the ADR-0007/ADR-0018 acceptance " - "threshold (0.60) - judge scores must be reported with this limitation, " - "not as validated ground truth." - ) - sys.exit(1) - - -if __name__ == "__main__": - main() diff --git a/src/ragforge/evaluation/answer_harness.py b/src/ragforge/evaluation/answer_harness.py index 094ddf7..66bafe5 100644 --- a/src/ragforge/evaluation/answer_harness.py +++ b/src/ragforge/evaluation/answer_harness.py @@ -85,6 +85,7 @@ def evaluate_answer_quality( status="skipped", answer_text=None, answer_citations=(), + judge_contexts=(), metrics={}, error="not attempted: strategy aborted after consecutive failures", ) @@ -101,6 +102,7 @@ def evaluate_answer_quality( status="failed", answer_text=None, answer_citations=(), + judge_contexts=(), metrics={}, error=str(exc), ) @@ -193,6 +195,7 @@ def _on_scoring_result( status=status, answer_text=None, answer_citations=(), + judge_contexts=(), metrics={}, error=str(outcome) or outcome.__class__.__name__, ) @@ -210,6 +213,7 @@ def _on_scoring_result( status="succeeded", answer_text=answer.text, answer_citations=answer.citations, + judge_contexts=tuple(result.chunk.source_text for result in _results), metrics=question_metrics, ) ) diff --git a/src/ragforge/evaluation/calibration_workflow.py b/src/ragforge/evaluation/calibration_workflow.py new file mode 100644 index 0000000..bbfe16a --- /dev/null +++ b/src/ragforge/evaluation/calibration_workflow.py @@ -0,0 +1,603 @@ +"""Human-calibration workflow for the answer-quality judge (ADR-0007/ADR-0018). + +The human reviewer must evaluate the same evidence that RAGAS Faithfulness +received. This module therefore treats ``QuestionRecord.judge_contexts`` as +the calibration evidence and keeps answer citations in a separate audit-only +section. +""" + +import hashlib +import json +import math +import re +from collections import defaultdict +from pathlib import Path +from typing import Literal + +from pydantic import BaseModel, ConfigDict, field_validator, model_validator + +from ragforge.domain.models import Judgment, QueryClass +from ragforge.evaluation.judge_calibration import ( + CalibrationSample, + compute_calibration_report, +) +from ragforge.evaluation.records import QuestionRecord +from ragforge.generation.citation_parsing import ( + extract_citation_candidates, + extract_citations, +) + +CalibrationDimension = Literal["faithfulness", "answer_relevancy", "abstention"] +BASE_DIMENSIONS: tuple[CalibrationDimension, ...] = ("faithfulness", "answer_relevancy") +METRIC_KEYS: dict[CalibrationDimension, str] = { + "faithfulness": "faithfulness", + "answer_relevancy": "answer_relevancy", + "abstention": "abstention_appropriate", +} +SELECTION_SEED = "regrag-br-calibration-v2" +SEALED_SCHEMA_VERSION = 1 +EVIDENCE_SCHEMA_VERSION = 1 +MINIMUM_ANSWER_SAMPLES = 30 +KAPPA_FLOOR = 0.60 +KAPPA_TARGET = 0.70 + +_STRONG_STRATEGIES = frozenset({"sac", "sac_contextual", "raptor", "dense"}) +_CONCEPT_FEATURES = frozenset( + { + "answer_quality:complete", + "answer_quality:partial", + "citation:unsupported", + "language:negation", + "language:exception", + "reasoning:cross_reference", + "claim:numerical", + } +) +_NEGATION_RE = re.compile(r"\b(?:não|nunca|sem|veda(?:do|da)?|proibi(?:do|da))\b", re.IGNORECASE) +_EXCEPTION_RE = re.compile( + r"\b(?:salvo|exceto|ressalvad\w*|desde que|a menos que)\b", re.IGNORECASE +) +_NUMERICAL_RE = re.compile(r"(?:\d|%|R\$)") + + +class HumanLabel(BaseModel): + """Validated human score for one answer-quality dimension.""" + + model_config = ConfigDict(extra="forbid", frozen=True) + + sample_id: str + dimension: CalibrationDimension + human_score: float | None + + @field_validator("human_score", mode="before") + @classmethod + def validate_human_score(cls, value: object) -> float | None: + """Accept only the three documented ordinal values or null.""" + if value is None: + return None + if isinstance(value, bool) or not isinstance(value, (int, float)): + raise ValueError("human_score must be numeric or null") + score = float(value) + if not math.isfinite(score) or score not in {0.0, 0.5, 1.0}: + raise ValueError("human_score must be one of 0.0, 0.5, or 1.0") + return score + + @model_validator(mode="after") + def validate_sample_suffix(self) -> "HumanLabel": + """Require the sample identity to end in its declared dimension.""" + if not self.sample_id.endswith(f"-{self.dimension}"): + raise ValueError("sample_id suffix must match dimension") + return self + + @property + def answer_sample_id(self) -> str: + """Return the question/strategy identity shared by all dimensions.""" + return self.sample_id.removesuffix(f"-{self.dimension}") + + +class SealedCalibration(BaseModel): + """Judge scores hidden from the reviewer until human labeling is complete.""" + + model_config = ConfigDict(extra="forbid", frozen=True) + + schema_version: Literal[1] + evidence_schema_version: Literal[1] + run_id: str + judge_scores: dict[str, float] + + @field_validator("judge_scores", mode="before") + @classmethod + def validate_judge_scores(cls, value: object) -> dict[str, float]: + """Reject non-numeric, non-finite, and out-of-range sealed scores.""" + if not isinstance(value, dict): + raise ValueError("judge_scores must be a JSON object") + scores: dict[str, float] = {} + for raw_key, raw_score in value.items(): + if not isinstance(raw_key, str) or not raw_key: + raise ValueError("judge score keys must be non-empty strings") + if isinstance(raw_score, bool) or not isinstance(raw_score, (int, float)): + raise ValueError(f"judge score {raw_key!r} must be numeric") + score = float(raw_score) + if not math.isfinite(score) or not 0.0 <= score <= 1.0: + raise ValueError(f"judge score {raw_key!r} must be finite and between 0 and 1") + scores[raw_key] = score + return scores + + +def dimensions_for(record: QuestionRecord) -> tuple[CalibrationDimension, ...]: + """Return the dimensions a reviewer must label for ``record``.""" + return (*BASE_DIMENSIONS, "abstention") if record.unanswerable else BASE_DIMENSIONS + + +def load_human_labels(path: Path) -> list[HumanLabel]: + """Load and validate a reviewer-edited labels JSON array.""" + payload: object = json.loads(path.read_text(encoding="utf-8")) + if not isinstance(payload, list): + raise ValueError("labels.json must contain a JSON array") + labels = [HumanLabel.model_validate(entry) for entry in payload] + _require_unique_label_ids(labels) + return labels + + +def load_sealed_calibration(path: Path) -> SealedCalibration: + """Load and validate the sealed judge-score document.""" + payload: object = json.loads(path.read_text(encoding="utf-8")) + return SealedCalibration.model_validate(payload) + + +def _require_unique_label_ids(labels: list[HumanLabel]) -> None: + seen: set[str] = set() + duplicates: set[str] = set() + for label in labels: + if label.sample_id in seen: + duplicates.add(label.sample_id) + seen.add(label.sample_id) + if duplicates: + raise ValueError(f"duplicate label sample_id values: {', '.join(sorted(duplicates))}") + + +def merge_existing_human_labels( + expected: list[HumanLabel], existing: list[HumanLabel] +) -> list[HumanLabel]: + """Preserve scores when rebuilding the exact same calibration sample. + + Raises: + ValueError: If the existing label identities or dimensions differ. + """ + if not existing: + return expected + _require_unique_label_ids(expected) + _require_unique_label_ids(existing) + expected_by_id = {label.sample_id: label for label in expected} + existing_by_id = {label.sample_id: label for label in existing} + if expected_by_id.keys() != existing_by_id.keys(): + raise ValueError( + "existing labels belong to a different calibration sample; archive the calibration " + "directory before building another run" + ) + merged = [] + for label in expected: + previous = existing_by_id[label.sample_id] + if previous.dimension != label.dimension: + raise ValueError(f"dimension changed for existing label {label.sample_id!r}") + merged.append(label.model_copy(update={"human_score": previous.human_score})) + return merged + + +def build_human_labels(sample: list[QuestionRecord]) -> list[HumanLabel]: + """Create empty human labels for every selected record dimension.""" + return [ + HumanLabel( + sample_id=f"{record.question_id}-{record.strategy}-{dimension}", + dimension=dimension, + human_score=None, + ) + for record in sample + for dimension in dimensions_for(record) + ] + + +def build_sealed_calibration(sample: list[QuestionRecord], run_id: str) -> SealedCalibration: + """Create the hidden judge-score payload corresponding exactly to ``sample``.""" + scores = { + f"{record.question_id}-{record.strategy}-{dimension}": record.metrics[ + METRIC_KEYS[dimension] + ] + for record in sample + for dimension in dimensions_for(record) + } + return SealedCalibration( + schema_version=SEALED_SCHEMA_VERSION, + evidence_schema_version=EVIDENCE_SCHEMA_VERSION, + run_id=run_id, + judge_scores=scores, + ) + + +def _stratum_of(record: QuestionRecord) -> tuple[str, str, str]: + query_class = record.query_class or "unclassified" + answerability = "unanswerable" if record.unanswerable else "answerable" + strength = "strong" if record.strategy in _STRONG_STRATEGIES else "weak" + return query_class, answerability, strength + + +def _selection_features(record: QuestionRecord, judgment: Judgment) -> frozenset[str]: + query_class, answerability, strength = _stratum_of(record) + features = { + f"stratum:{query_class}:{answerability}:{strength}", + f"class:{query_class}", + f"answerability:{answerability}", + f"strategy:{strength}", + } + faithfulness = record.metrics["faithfulness"] + relevancy = record.metrics["answer_relevancy"] + if faithfulness >= 2 / 3 and relevancy >= 2 / 3: + features.add("answer_quality:complete") + else: + features.add("answer_quality:partial") + + candidates = extract_citation_candidates(record.answer_text or "") + parsed = extract_citations(record.answer_text or "") + citation_accuracy = record.metrics.get("citation_accuracy", 1.0) + if ( + citation_accuracy < 1.0 + or len(candidates) != len(parsed) + or any("," in candidate for candidate in candidates) + ): + features.add("citation:unsupported") + + combined_text = "\n".join( + part + for part in ( + judgment.query.text, + judgment.reference_answer or "", + record.answer_text or "", + ) + if part + ) + if _NEGATION_RE.search(combined_text): + features.add("language:negation") + if _EXCEPTION_RE.search(combined_text): + features.add("language:exception") + if ( + judgment.query.query_class in {QueryClass.MULTI_HOP, QueryClass.SECTION_COMPARATIVE} + or len(judgment.relevant_refs) > 1 + ): + features.add("reasoning:cross_reference") + if judgment.query.query_class is QueryClass.NUMERIC_TABULAR or _NUMERICAL_RE.search( + combined_text + ): + features.add("claim:numerical") + return frozenset(features) + + +def _is_finite_score(value: float | None) -> bool: + return value is not None and math.isfinite(value) and 0.0 <= value <= 1.0 + + +def _is_usable(record: QuestionRecord) -> bool: + if record.generation_status != "succeeded" or record.judge_status != "succeeded": + return False + if not record.answer_text or not record.judge_contexts: + return False + return all( + _is_finite_score(record.metrics.get(METRIC_KEYS[dimension])) + for dimension in dimensions_for(record) + ) + + +def _stable_selection_key(record: QuestionRecord) -> str: + identity = f"{SELECTION_SEED}\0{record.question_id}\0{record.strategy}" + return hashlib.sha256(identity.encode("utf-8")).hexdigest() + + +def select_calibration_records( + records: list[QuestionRecord], judgments: dict[str, Judgment], size: int +) -> list[QuestionRecord]: + """Select a deterministic sample covering every ADR-0018 calibration feature. + + The greedy first phase covers every available query/answerability/strength + stratum and every required conceptual feature. A deterministic + round-robin then fills the requested size without using a pseudo-random + generator or exposing judge-derived feature tags to the reviewer. + + Raises: + ValueError: If exact judge contexts, metrics, features, or sample count + are insufficient. + """ + if size < MINIMUM_ANSWER_SAMPLES: + raise ValueError(f"ADR-0018 requires at least {MINIMUM_ANSWER_SAMPLES} samples") + usable = [record for record in records if _is_usable(record)] + if len(usable) < size: + context_count = sum(bool(record.judge_contexts) for record in records) + raise ValueError( + f"only {len(usable)} usable records for {size} requested; exact judge contexts exist " + f"for {context_count} of {len(records)} records. Legacy runs must be rerun because " + "citation text cannot reconstruct the evidence seen by the judge" + ) + missing_judgments = sorted({record.question_id for record in usable} - judgments.keys()) + if missing_judgments: + raise ValueError(f"records missing golden judgments: {', '.join(missing_judgments[:3])}") + + features_by_key = { + (record.question_id, record.strategy): _selection_features( + record, judgments[record.question_id] + ) + for record in usable + } + all_features: set[str] = set().union(*features_by_key.values()) + missing_features = sorted(_CONCEPT_FEATURES - all_features) + if missing_features: + raise ValueError( + "no usable calibration candidate covers required features: " + + ", ".join(missing_features) + ) + required_features = { + feature + for feature in all_features + if feature.startswith(("stratum:", "class:", "answerability:", "strategy:")) + } + required_features.update(_CONCEPT_FEATURES) + + remaining = sorted(usable, key=_stable_selection_key) + selected: list[QuestionRecord] = [] + uncovered = set(required_features) + while uncovered: + best = min( + remaining, + key=lambda record: ( + -len(features_by_key[(record.question_id, record.strategy)] & uncovered), + _stable_selection_key(record), + ), + ) + gain = features_by_key[(best.question_id, best.strategy)] & uncovered + if not gain: + raise ValueError( + f"unable to cover calibration features: {', '.join(sorted(uncovered))}" + ) + if len(selected) >= size: + raise ValueError(f"sample size {size} is too small to cover every calibration stratum") + selected.append(best) + remaining.remove(best) + uncovered.difference_update(gain) + + selected_keys = {(record.question_id, record.strategy) for record in selected} + buckets: dict[tuple[str, str, str], list[QuestionRecord]] = defaultdict(list) + for record in remaining: + if (record.question_id, record.strategy) not in selected_keys: + buckets[_stratum_of(record)].append(record) + for bucket in buckets.values(): + bucket.sort(key=_stable_selection_key) + strata = sorted(buckets) + while len(selected) < size: + progressed = False + for stratum in strata: + if buckets[stratum] and len(selected) < size: + selected.append(buckets[stratum].pop()) + progressed = True + if not progressed: + raise ValueError(f"only {len(selected)} records available for {size} requested") + return selected + + +def calibration_feature_coverage( + sample: list[QuestionRecord], judgments: dict[str, Judgment] +) -> frozenset[str]: + """Return the hidden selection-feature coverage for audit logging.""" + return frozenset().union( + *(_selection_features(record, judgments[record.question_id]) for record in sample) + ) + + +def _blockquote(text: str) -> str: + return "> " + text.strip().replace("\n", "\n> ") + + +def render_calibration_worksheet( + sample: list[QuestionRecord], + judgments: dict[str, Judgment], + corpus: dict[str, dict[str, str]], + run_id: str, +) -> str: + """Render a blind worksheet using the exact evidence seen by the judge.""" + lines = [ + "# Judge calibration worksheet", + "", + f"Run `{run_id}` · {len(sample)} samples · selection seed `{SELECTION_SEED}`", + "", + "Score each sample in `labels.json`. Keep `.judge-sealed.json` closed until every", + "human score is complete; seeing judge scores first would anchor the review.", + "", + "## Scale", + "", + "Use only `0.0`, `0.5`, or `1.0`.", + "", + "**Faithfulness** — is every assertion supported by the exact judge contexts shown", + "below? These are the same ordered texts passed to RAGAS, not a reconstruction from", + "citations or structural IDs.", + "", + "- `1.0`: fully supported", + "- `0.5`: mostly supported, with a material overreach or omitted condition", + "- `0.0`: a central assertion contradicts or lacks support in the contexts", + "", + "**Answer Relevancy** — does the answer directly and completely address the question?", + "", + "For an **unanswerable** question, a correct abstention scores `1.0` on both.", + "", + "The citation-audit section is diagnostic only and is not the Faithfulness evidence.", + "", + "---", + "", + ] + for index, record in enumerate(sample, start=1): + judgment = judgments[record.question_id] + sample_id = f"{record.question_id}-{record.strategy}" + lines.extend( + [ + f"## {index}. `{sample_id}`", + "", + f"- Class: **{record.query_class}**" + + (" · **UNANSWERABLE**" if record.unanswerable else ""), + f"- Strategy: `{record.strategy}`", + "", + "### Question", + "", + judgment.query.text.strip(), + "", + ] + ) + if judgment.reference_answer: + lines.extend( + [ + "### Reference answer (golden set)", + "", + judgment.reference_answer.strip(), + "", + ] + ) + lines.extend(["### Exact judge contexts", ""]) + for context_index, context in enumerate(record.judge_contexts, start=1): + lines.extend([f"#### Context {context_index}", "", _blockquote(context), ""]) + + lines.extend(["### Citation audit (not judge evidence)", ""]) + candidates = extract_citation_candidates(record.answer_text or "") + if not candidates: + lines.extend(["_The answer contains no bracketed citation._", ""]) + parsed_citations = set(record.answer_citations) + for candidate in candidates: + lines.extend([f"**`{candidate}`**", ""]) + norm_id = candidate.split("::", maxsplit=1)[0] + resolved = (corpus.get(norm_id) or {}).get(candidate) + if candidate not in parsed_citations: + lines.extend( + [ + "> _(malformed or grouped citation; not parsed as one canonical ID)_", + "", + ] + ) + elif resolved is None: + lines.extend(["> _(parsed citation does not resolve in the canonical corpus)_", ""]) + else: + lines.extend([_blockquote(resolved), ""]) + + lines.extend( + [ + "### Generated answer", + "", + (record.answer_text or "").strip(), + "", + "### Your scores", + "", + f"| `{sample_id}` | 0.0 / 0.5 / 1.0 | notes |", + "|---|---|---|", + "| faithfulness | | |", + "| answer_relevancy | | |", + *(["| abstention | | |"] if record.unanswerable else []), + "", + "---", + "", + ] + ) + return "\n".join(lines) + + +def build_calibration_samples( + labels: list[HumanLabel], sealed: SealedCalibration +) -> list[CalibrationSample]: + """Validate exact label/score alignment and build computation inputs.""" + _require_unique_label_ids(labels) + label_ids = {label.sample_id for label in labels} + score_ids = set(sealed.judge_scores) + if label_ids != score_ids: + missing_scores = sorted(label_ids - score_ids) + missing_labels = sorted(score_ids - label_ids) + raise ValueError( + "labels and sealed scores differ; " + f"without scores: {missing_scores[:3]}, without labels: {missing_labels[:3]}" + ) + incomplete = [label.sample_id for label in labels if label.human_score is None] + if incomplete: + raise ValueError( + f"{len(incomplete)} of {len(labels)} labels are still empty; first: " + + ", ".join(incomplete[:3]) + ) + answer_sample_ids = {label.answer_sample_id for label in labels} + if len(answer_sample_ids) < MINIMUM_ANSWER_SAMPLES: + raise ValueError( + f"only {len(answer_sample_ids)} distinct answer samples; " + f"ADR-0018 requires {MINIMUM_ANSWER_SAMPLES}" + ) + for dimension in BASE_DIMENSIONS: + dimension_ids = {label.answer_sample_id for label in labels if label.dimension == dimension} + if dimension_ids != answer_sample_ids: + raise ValueError(f"dimension {dimension!r} does not cover every answer sample") + return [ + CalibrationSample( + sample_id=label.sample_id, + dimension=label.dimension, + judge_score=sealed.judge_scores[label.sample_id], + human_score=label.human_score, + ) + for label in labels + if label.human_score is not None + ] + + +def build_calibration_report(samples: list[CalibrationSample], run_id: str) -> dict[str, object]: + """Build overall and per-dimension agreement plus a fail-closed gate result.""" + overall = compute_calibration_report(samples) + by_dimension = { + dimension: compute_calibration_report( + [sample for sample in samples if sample.dimension == dimension] + ) + for dimension in sorted({sample.dimension for sample in samples}) + } + required_results: dict[str, dict[str, float]] = { + "overall": overall, + **{dimension: by_dimension[dimension] for dimension in BASE_DIMENSIONS}, + } + failed_dimensions = sorted( + name for name, result in required_results.items() if result["weighted_kappa"] < KAPPA_FLOOR + ) + answer_sample_count = len( + {sample.sample_id.removesuffix(f"-{sample.dimension}") for sample in samples} + ) + return { + "schema_version": 1, + "run_id": run_id, + "n_labels": len(samples), + "n_answer_samples": answer_sample_count, + "overall": overall, + "by_dimension": by_dimension, + "gate": { + "floor": KAPPA_FLOOR, + "publication_target": KAPPA_TARGET, + "required_results": list(required_results), + "failed_results": failed_dimensions, + "passed": not failed_dimensions, + }, + } + + +def calibration_gate_passed(report: dict[str, object]) -> bool: + """Return the validated boolean gate result from ``build_calibration_report``.""" + gate = report.get("gate") + if not isinstance(gate, dict): + raise ValueError("calibration report has no valid gate result") + passed = gate.get("passed") + if not isinstance(passed, bool): + raise ValueError("calibration report has no valid gate result") + return passed + + +def scores_have_ordinal_disagreement(sample: CalibrationSample) -> bool: + """Return whether judge and human scores land in different kappa bins.""" + + def ordinal(score: float) -> int: + if score < 1 / 3: + return 0 + if score < 2 / 3: + return 1 + return 2 + + return ordinal(sample.judge_score) != ordinal(sample.human_score) diff --git a/src/ragforge/evaluation/judge_calibration.py b/src/ragforge/evaluation/judge_calibration.py index 5726916..12bb564 100644 --- a/src/ragforge/evaluation/judge_calibration.py +++ b/src/ragforge/evaluation/judge_calibration.py @@ -1,19 +1,17 @@ """Judge calibration against human evaluation (ADR-0007/ADR-0018). -Computes judge-vs-human agreement (weighted Cohen's kappa >= 0.60 gate) -required before judge scores count as more than an unvalidated caveat. It -cannot produce the ~30+ hand-labeled, stratified samples the exercise needs - -that is human curation work; until a real calibration file goes through -``compute_calibration_report``, RagasJudge scores remain unvalidated. +Provides the low-level judge-vs-human agreement metrics required by the +calibration gate. Sample validation, minimum size, evidence provenance, and +per-dimension acceptance belong to ``calibration_workflow``; callers must use +that canonical workflow before treating RagasJudge scores as validated. Continuous judge scores (0.0-1.0) are binned by ``_to_ordinal`` into three categories (0/0.5/1.0), matching ``RelevanceGrade``'s existing ordinal scale. """ -import json import statistics +from contextlib import suppress from dataclasses import dataclass -from pathlib import Path _ORDINAL_CATEGORIES = 3 _BINARY_THRESHOLD = 0.5 @@ -149,9 +147,10 @@ def abstention_agreement(samples: list[CalibrationSample]) -> float: def compute_calibration_report(samples: list[CalibrationSample]) -> dict[str, float]: - """Aggregate every ADR-0007/ADR-0018 calibration metric across all dimensions. + """Aggregate ADR-0007/ADR-0018 metrics for an already validated sample group. - ``spearman_correlation`` is omitted (not raised) below 2 samples. + ``spearman_correlation`` is omitted when fewer than 2 samples are + available or either score sequence is constant. Raises: ValueError: If samples is empty. @@ -172,25 +171,8 @@ def compute_calibration_report(samples: list[CalibrationSample]) -> dict[str, fl if len(samples) >= 2: judge_scores = [sample.judge_score for sample in samples] human_scores = [sample.human_score for sample in samples] - report["spearman_correlation"] = spearman_correlation(judge_scores, human_scores) + # Undefined when either reviewer assigns one constant score; kappa and + # the error rates remain meaningful. + with suppress(statistics.StatisticsError): + report["spearman_correlation"] = spearman_correlation(judge_scores, human_scores) return report - - -def load_calibration_samples(path: Path) -> list[CalibrationSample]: - """Load calibration samples from a JSON file. - - Expects a JSON array of objects with ``sample_id``, ``dimension``, - ``judge_score``, ``human_score``. No such file ships with the repository - (see module docstring) - this loader is ready for the moment a human - curator produces one. - """ - payload = json.loads(path.read_text(encoding="utf-8")) - return [ - CalibrationSample( - sample_id=entry["sample_id"], - dimension=entry["dimension"], - judge_score=entry["judge_score"], - human_score=entry["human_score"], - ) - for entry in payload - ] diff --git a/src/ragforge/evaluation/records.py b/src/ragforge/evaluation/records.py index 94cacaa..88039d9 100644 --- a/src/ragforge/evaluation/records.py +++ b/src/ragforge/evaluation/records.py @@ -35,6 +35,7 @@ class AnswerRecord: status: str answer_text: str | None answer_citations: tuple[str, ...] + judge_contexts: tuple[str, ...] metrics: dict[str, float] error: str | None = None @@ -53,6 +54,7 @@ class QuestionRecord: retrieved_structural_ids: tuple[str, ...] answer_text: str | None answer_citations: tuple[str, ...] + judge_contexts: tuple[str, ...] metrics: dict[str, float] errors: tuple[str, ...] @@ -69,6 +71,7 @@ def to_json_dict(self) -> dict[str, object]: "retrieved_structural_ids": list(self.retrieved_structural_ids), "answer_text": self.answer_text, "answer_citations": list(self.answer_citations), + "judge_contexts": list(self.judge_contexts), "metrics": self.metrics, "errors": list(self.errors), } @@ -105,6 +108,7 @@ def merge_question_records( retrieved_structural_ids=retrieval.retrieved_structural_ids, answer_text=answer.answer_text if answer is not None else None, answer_citations=answer.answer_citations if answer is not None else (), + judge_contexts=answer.judge_contexts if answer is not None else (), metrics={**retrieval.metrics, **(answer.metrics if answer is not None else {})}, errors=tuple(errors), ) @@ -176,6 +180,9 @@ def read_records_jsonl(path: Path) -> list[QuestionRecord]: answer_citations=tuple( str(value) for value in cast(list[object], payload["answer_citations"]) ), + judge_contexts=tuple( + str(value) for value in cast(list[object], payload.get("judge_contexts", [])) + ), metrics=metrics, errors=tuple(str(value) for value in cast(list[object], payload["errors"])), ) diff --git a/tests/unit/test_answer_harness.py b/tests/unit/test_answer_harness.py index 3e7f4ee..9c610bc 100644 --- a/tests/unit/test_answer_harness.py +++ b/tests/unit/test_answer_harness.py @@ -184,6 +184,7 @@ def test_evaluate_answer_quality_averages_citation_accuracy_across_judgments() - assert result.metrics["answer_errors"] == 0.0 assert len(result.records) == 2 assert all(record.status == "succeeded" for record in result.records) + assert all(record.judge_contexts == ("chunk text",) for record in result.records) def test_evaluate_answer_quality_still_scores_unanswerable_questions() -> None: @@ -237,13 +238,14 @@ def test_evaluate_answer_quality_passes_retrieved_chunk_text_as_judge_contexts() generator = _FakeGenerator({"q1": Answer(text="answer", citations=(ART_1,))}) judge = _FakeJudge({"faithfulness": 1.0, "answer_relevancy": 1.0}) - evaluate_answer_quality( + result = evaluate_answer_quality( _FakeStrategy(), [_judgment("q1", ART_1)], generator, lambda: judge, k=5 ) assert judge.calls[0].question == "q1" assert judge.calls[0].contexts == ("chunk text",) assert judge.calls[0].answer == "answer" + assert result.records[0].judge_contexts == judge.calls[0].contexts def test_evaluate_answer_quality_raises_for_an_empty_judgment_list() -> None: diff --git a/tests/unit/test_calibration_workflow.py b/tests/unit/test_calibration_workflow.py new file mode 100644 index 0000000..0d399dd --- /dev/null +++ b/tests/unit/test_calibration_workflow.py @@ -0,0 +1,291 @@ +"""Tests for the blind judge-calibration workflow (ADR-0007/ADR-0018).""" + +from dataclasses import replace + +import pytest +from pydantic import ValidationError + +from ragforge.domain.models import ( + JudgedRef, + Judgment, + Query, + QueryClass, + RelevanceGrade, + StructuralRef, +) +from ragforge.evaluation.calibration_workflow import ( + HumanLabel, + SealedCalibration, + build_calibration_report, + build_calibration_samples, + build_human_labels, + build_sealed_calibration, + calibration_feature_coverage, + calibration_gate_passed, + merge_existing_human_labels, + render_calibration_worksheet, + scores_have_ordinal_disagreement, + select_calibration_records, +) +from ragforge.evaluation.judge_calibration import CalibrationSample +from ragforge.evaluation.records import QuestionRecord + + +def _judgment(question_id: str, query_class: QueryClass) -> Judgment: + refs = [ + JudgedRef(StructuralRef("NORM", "art-1"), RelevanceGrade.RELEVANT), + ] + if query_class in {QueryClass.MULTI_HOP, QueryClass.SECTION_COMPARATIVE}: + refs.append(JudgedRef(StructuralRef("NORM", "art-2"), RelevanceGrade.RELEVANT)) + return Judgment( + question_id=question_id, + query=Query( + text=f"A regra não se aplica, salvo exceção de 30% para {question_id}?", + query_class=query_class, + ), + relevant_refs=tuple(refs) if query_class is not QueryClass.UNANSWERABLE else (), + reference_answer="Resposta de referência com 30%.", + ) + + +def _record( + question_id: str, + query_class: QueryClass, + strategy: str, + *, + faithfulness: float = 1.0, + relevancy: float = 1.0, + citation_accuracy: float = 1.0, + judge_contexts: tuple[str, ...] = ("exact judge context",), +) -> QuestionRecord: + unanswerable = query_class is QueryClass.UNANSWERABLE + metrics = { + "faithfulness": faithfulness, + "answer_relevancy": relevancy, + "abstention_appropriate": 1.0, + } + if not unanswerable: + metrics["citation_accuracy"] = citation_accuracy + return QuestionRecord( + question_id=question_id, + query_class=query_class.value, + strategy=strategy, + unanswerable=unanswerable, + retrieval_status="succeeded", + generation_status="succeeded", + judge_status="succeeded", + retrieved_structural_ids=("NORM::art-1",), + answer_text="Resposta não aplicável, salvo 30% [NORM::art-1].", + answer_citations=("NORM::art-1",), + judge_contexts=judge_contexts, + metrics=metrics, + errors=(), + ) + + +def _candidate_set(count: int = 36) -> tuple[list[QuestionRecord], dict[str, Judgment]]: + query_classes = list(QueryClass) + strategies = ["dense", "graphrag"] + records = [] + judgments = {} + for index in range(count): + question_id = f"q{index:03d}" + query_class = query_classes[index % len(query_classes)] + judgment = _judgment(question_id, query_class) + record = _record(question_id, query_class, strategies[index % len(strategies)]) + if index == 1: + record = replace(record, metrics={**record.metrics, "answer_relevancy": 0.5}) + if index == 2 and not record.unanswerable: + record = replace(record, metrics={**record.metrics, "citation_accuracy": 0.0}) + judgments[question_id] = judgment + records.append(record) + return records, judgments + + +@pytest.mark.parametrize("score", [-1.0, 0.25, 1.5, float("inf"), float("nan"), "1.0"]) +def test_human_label_rejects_values_outside_the_documented_scale(score: object) -> None: + with pytest.raises(ValidationError, match="human_score"): + HumanLabel( + sample_id="q1-dense-faithfulness", + dimension="faithfulness", + human_score=score, + ) + + +def test_human_label_rejects_dimension_suffix_mismatch() -> None: + with pytest.raises(ValidationError, match="suffix"): + HumanLabel( + sample_id="q1-dense-faithfulness", + dimension="answer_relevancy", + human_score=1.0, + ) + + +@pytest.mark.parametrize("score", [-0.1, 1.1, float("inf"), float("nan"), "1.0"]) +def test_sealed_calibration_rejects_invalid_judge_scores(score: object) -> None: + with pytest.raises(ValidationError, match="judge score"): + SealedCalibration( + schema_version=1, + evidence_schema_version=1, + run_id="run-1", + judge_scores={"q1-dense-faithfulness": score}, + ) + + +def test_merge_existing_human_labels_preserves_completed_scores() -> None: + expected = [ + HumanLabel( + sample_id="q1-dense-faithfulness", + dimension="faithfulness", + human_score=None, + ) + ] + existing = [expected[0].model_copy(update={"human_score": 0.5})] + + merged = merge_existing_human_labels(expected, existing) + + assert merged[0].human_score == 0.5 + + +def test_merge_existing_human_labels_rejects_a_different_sample() -> None: + expected = [ + HumanLabel( + sample_id="q1-dense-faithfulness", + dimension="faithfulness", + human_score=None, + ) + ] + existing = [ + HumanLabel( + sample_id="q2-dense-faithfulness", + dimension="faithfulness", + human_score=1.0, + ) + ] + + with pytest.raises(ValueError, match="different calibration sample"): + merge_existing_human_labels(expected, existing) + + +def test_select_calibration_records_rejects_legacy_records_without_judge_contexts() -> None: + records, judgments = _candidate_set(30) + legacy = [replace(record, judge_contexts=()) for record in records] + + with pytest.raises(ValueError, match="Legacy runs must be rerun"): + select_calibration_records(legacy, judgments, 30) + + +def test_select_calibration_records_is_deterministic_and_covers_required_features() -> None: + records, judgments = _candidate_set() + + first = select_calibration_records(records, judgments, 30) + second = select_calibration_records(list(reversed(records)), judgments, 30) + + first_ids = [(record.question_id, record.strategy) for record in first] + second_ids = [(record.question_id, record.strategy) for record in second] + assert first_ids == second_ids + coverage = calibration_feature_coverage(first, judgments) + assert { + "answer_quality:complete", + "answer_quality:partial", + "citation:unsupported", + "language:negation", + "language:exception", + "reasoning:cross_reference", + "claim:numerical", + } <= coverage + + +def test_render_calibration_worksheet_uses_exact_context_and_separates_citation_audit() -> None: + record = replace( + _record("q1", QueryClass.EXACT_FACTUAL, "dense"), + answer_text="Resposta [NORM::art-1, NORM::art-2].", + answer_citations=(), + judge_contexts=("context the judge actually saw",), + ) + judgment = _judgment("q1", QueryClass.EXACT_FACTUAL) + + worksheet = render_calibration_worksheet( + [record], + {"q1": judgment}, + {"NORM": {"NORM::art-1": "canonical source"}}, + "run-1", + ) + + assert "### Exact judge contexts" in worksheet + assert "> context the judge actually saw" in worksheet + assert "### Citation audit (not judge evidence)" in worksheet + assert "malformed or grouped citation" in worksheet + + +def test_build_calibration_samples_requires_exact_label_score_alignment() -> None: + records, _ = _candidate_set(30) + labels = build_human_labels(records) + completed = [label.model_copy(update={"human_score": 1.0}) for label in labels] + sealed = build_sealed_calibration(records, "run-1") + truncated_scores = { + key: value for key, value in sealed.judge_scores.items() if key != labels[0].sample_id + } + misaligned = sealed.model_copy(update={"judge_scores": truncated_scores}) + + with pytest.raises(ValueError, match="labels and sealed scores differ"): + build_calibration_samples(completed, misaligned) + + +def test_build_calibration_samples_rejects_incomplete_labels() -> None: + records, _ = _candidate_set(30) + labels = build_human_labels(records) + sealed = build_sealed_calibration(records, "run-1") + + with pytest.raises(ValueError, match="labels are still empty"): + build_calibration_samples(labels, sealed) + + +def _agreement_samples(*, invert_faithfulness: bool) -> list[CalibrationSample]: + samples = [] + for index in range(30): + judge_score = float(index % 2) + faithfulness_human = 1.0 - judge_score if invert_faithfulness else judge_score + samples.extend( + [ + CalibrationSample( + sample_id=f"q{index}-dense-faithfulness", + dimension="faithfulness", + judge_score=judge_score, + human_score=faithfulness_human, + ), + CalibrationSample( + sample_id=f"q{index}-dense-answer_relevancy", + dimension="answer_relevancy", + judge_score=judge_score, + human_score=judge_score, + ), + ] + ) + return samples + + +def test_build_calibration_report_fails_when_one_required_dimension_misses_floor() -> None: + report = build_calibration_report(_agreement_samples(invert_faithfulness=True), "run-1") + + assert calibration_gate_passed(report) is False + gate = report["gate"] + assert isinstance(gate, dict) + assert "faithfulness" in gate["failed_results"] + + +def test_build_calibration_report_passes_for_perfect_dimension_agreement() -> None: + report = build_calibration_report(_agreement_samples(invert_faithfulness=False), "run-1") + + assert calibration_gate_passed(report) is True + + +def test_scores_have_ordinal_disagreement_uses_kappa_thirds() -> None: + sample = CalibrationSample( + sample_id="q1-dense-faithfulness", + dimension="faithfulness", + judge_score=0.66, + human_score=0.67, + ) + + assert scores_have_ordinal_disagreement(sample) is True diff --git a/tests/unit/test_finalize_calibration.py b/tests/unit/test_finalize_calibration.py new file mode 100644 index 0000000..0c5e2d8 --- /dev/null +++ b/tests/unit/test_finalize_calibration.py @@ -0,0 +1,122 @@ +"""Behavior tests for the canonical calibration finalizer entrypoint.""" + +import json +import sys +from pathlib import Path + +import pytest +import scripts.finalize_calibration as finalize_calibration + +_ANSWER_SAMPLE_COUNT = 30 + + +def _write_workspace( + calibration_dir: Path, + *, + incomplete: bool = False, + invert_faithfulness: bool = False, +) -> None: + labels: list[dict[str, object]] = [] + judge_scores: dict[str, float] = {} + for index in range(_ANSWER_SAMPLE_COUNT): + judge_score = float(index % 2) + for dimension in ("faithfulness", "answer_relevancy"): + sample_id = f"q{index}-dense-{dimension}" + human_score = judge_score + if dimension == "faithfulness" and invert_faithfulness: + human_score = 1.0 - judge_score + labels.append( + { + "sample_id": sample_id, + "dimension": dimension, + "human_score": ( + None + if incomplete and index == 0 and dimension == "faithfulness" + else human_score + ), + } + ) + judge_scores[sample_id] = judge_score + + calibration_dir.mkdir() + (calibration_dir / "labels.json").write_text( + json.dumps(labels, ensure_ascii=False), + encoding="utf-8", + ) + (calibration_dir / ".judge-sealed.json").write_text( + json.dumps( + { + "schema_version": 1, + "evidence_schema_version": 1, + "run_id": "run-test", + "judge_scores": judge_scores, + }, + ensure_ascii=False, + ), + encoding="utf-8", + ) + + +def _invoke_finalizer(monkeypatch: pytest.MonkeyPatch, calibration_dir: Path) -> None: + monkeypatch.setattr(finalize_calibration, "CAL_DIR", calibration_dir) + monkeypatch.setattr(sys, "argv", ["finalize_calibration.py"]) + finalize_calibration.main() + + +def _read_report(calibration_dir: Path) -> dict[str, object]: + payload: object = json.loads((calibration_dir / "report.json").read_text(encoding="utf-8")) + assert isinstance(payload, dict) + return payload + + +def test_finalizer_publishes_report_when_workspace_passes( + tmp_path: Path, + monkeypatch: pytest.MonkeyPatch, + capsys: pytest.CaptureFixture[str], +) -> None: + calibration_dir = tmp_path / "calibration" + _write_workspace(calibration_dir) + + _invoke_finalizer(monkeypatch, calibration_dir) + + report = _read_report(calibration_dir) + gate = report["gate"] + assert isinstance(gate, dict) + assert gate["passed"] is True + assert report["run_id"] == "run-test" + assert "Calibration passed" in capsys.readouterr().out + + +def test_finalizer_rejects_incomplete_human_labels( + tmp_path: Path, + monkeypatch: pytest.MonkeyPatch, +) -> None: + calibration_dir = tmp_path / "calibration" + _write_workspace(calibration_dir, incomplete=True) + + with pytest.raises(SystemExit, match="labels are still empty"): + _invoke_finalizer(monkeypatch, calibration_dir) + + assert not (calibration_dir / "report.json").exists() + + +def test_finalizer_returns_failure_when_one_required_dimension_misses_floor( + tmp_path: Path, + monkeypatch: pytest.MonkeyPatch, + capsys: pytest.CaptureFixture[str], +) -> None: + calibration_dir = tmp_path / "calibration" + _write_workspace(calibration_dir, invert_faithfulness=True) + + with pytest.raises(SystemExit) as exc_info: + _invoke_finalizer(monkeypatch, calibration_dir) + + assert exc_info.value.code == 1 + report = _read_report(calibration_dir) + gate = report["gate"] + assert isinstance(gate, dict) + assert gate["passed"] is False + failed_results = gate["failed_results"] + assert isinstance(failed_results, list) + assert "faithfulness" in failed_results + assert "Calibration gate failed" in capsys.readouterr().out diff --git a/tests/unit/test_judge_calibration.py b/tests/unit/test_judge_calibration.py index 52c46cf..56d5314 100644 --- a/tests/unit/test_judge_calibration.py +++ b/tests/unit/test_judge_calibration.py @@ -1,8 +1,5 @@ """Tests for judge calibration metrics (ADR-0007/ADR-0018).""" -import json -from pathlib import Path - import pytest from ragforge.evaluation.judge_calibration import ( @@ -11,7 +8,6 @@ compute_calibration_report, false_supported_rate, false_unsupported_rate, - load_calibration_samples, spearman_correlation, weighted_cohens_kappa, ) @@ -150,37 +146,19 @@ def test_omits_spearman_for_a_single_sample(self) -> None: assert "spearman_correlation" not in report assert report["n"] == 1.0 + def test_omits_spearman_when_one_score_sequence_is_constant(self) -> None: + """A constant reviewer sequence has undefined correlation but valid kappa.""" + report = compute_calibration_report( + [ + _sample("q1", "faithfulness", judge_score=0.0, human_score=1.0), + _sample("q2", "faithfulness", judge_score=1.0, human_score=1.0), + ] + ) + + assert "spearman_correlation" not in report + assert "weighted_kappa" in report + def test_raises_for_an_empty_sample_list(self) -> None: """An empty calibration file is a caller error, not a silently meaningless report.""" with pytest.raises(ValueError, match="must not be empty"): compute_calibration_report([]) - - -class TestLoadCalibrationSamples: - def test_loads_every_sample_from_a_json_file(self, tmp_path: Path) -> None: - """Every field in the documented JSON schema round-trips into a CalibrationSample.""" - path = tmp_path / "calibration.json" - path.write_text( - json.dumps( - [ - { - "sample_id": "q1-faithfulness", - "dimension": "faithfulness", - "judge_score": 0.8, - "human_score": 1.0, - } - ] - ), - encoding="utf-8", - ) - - samples = load_calibration_samples(path) - - assert samples == [ - CalibrationSample( - sample_id="q1-faithfulness", - dimension="faithfulness", - judge_score=0.8, - human_score=1.0, - ) - ] diff --git a/tests/unit/test_records.py b/tests/unit/test_records.py index b5cb3ce..83ff010 100644 --- a/tests/unit/test_records.py +++ b/tests/unit/test_records.py @@ -34,6 +34,7 @@ def _answer(question_id: str, **overrides: Any) -> AnswerRecord: status="succeeded", answer_text="the answer", answer_citations=("NORM::art-1",), + judge_contexts=("authoritative context",), metrics={"citation_accuracy": 1.0}, error=None, ) @@ -52,6 +53,7 @@ def test_merge_joins_retrieval_and_answer_records_by_question_id() -> None: assert record.generation_status == "succeeded" assert record.judge_status == "succeeded" assert record.answer_text == "the answer" + assert record.judge_contexts == ("authoritative context",) assert record.metrics == {"recall_at_k": 1.0, "citation_accuracy": 1.0} assert record.errors == () @@ -67,6 +69,7 @@ def test_merge_marks_generation_and_judge_not_applicable_when_no_answer_record_e assert record.judge_status == "not_applicable" assert record.answer_text is None assert record.answer_citations == () + assert record.judge_contexts == () assert record.metrics == {} @@ -95,9 +98,23 @@ def test_append_records_jsonl_writes_one_json_line_per_record(tmp_path: Path) -> parsed = [json.loads(line) for line in lines] assert parsed[0]["strategy"] == "dense" assert parsed[1]["strategy"] == "sparse_bm25" + assert parsed[0]["judge_contexts"] == ["authoritative context"] assert parsed[0]["metrics"] == {"recall_at_k": 1.0, "citation_accuracy": 1.0} +def test_read_records_jsonl_defaults_legacy_judge_contexts_to_empty(tmp_path: Path) -> None: + """Records written before exact judge-context persistence remain readable.""" + path = tmp_path / "records.jsonl" + record = merge_question_records("dense", [_retrieval("q1")], [_answer("q1")])[0] + payload = record.to_json_dict() + del payload["judge_contexts"] + path.write_text(json.dumps(payload) + "\n", encoding="utf-8") + + loaded = read_records_jsonl(path) + + assert loaded[0].judge_contexts == () + + def test_append_records_jsonl_is_idempotent_for_a_resumed_strategy(tmp_path: Path) -> None: """Resume cannot duplicate an already persisted strategy/question record.""" path = tmp_path / "records.jsonl" diff --git a/tests/unit/test_run_reporting_breakdowns.py b/tests/unit/test_run_reporting_breakdowns.py index c51bfa2..4a0ed0a 100644 --- a/tests/unit/test_run_reporting_breakdowns.py +++ b/tests/unit/test_run_reporting_breakdowns.py @@ -28,6 +28,7 @@ def _record(question_id: str, query_class: str, score: float) -> QuestionRecord: retrieved_structural_ids=(), answer_text="answer", answer_citations=(), + judge_contexts=("context",), metrics={"recall_at_k": score}, errors=(), )