Compare commits
3
Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
938950038d | ||
|
|
f874326812 | ||
|
|
57c2ce8575 |
@@ -1,78 +1,50 @@
|
|||||||
# Pet16704 — Análise do Processo
|
# Pet16704 — Análise do Processo
|
||||||
|
|
||||||
Visualização interativa da linha do tempo dos autos vinculados **Pet16704** (STF) — um ponto por
|
Uma linha do tempo navegável de tudo que está nos autos da **Pet16704**, no STF — o processo que reúne
|
||||||
documento, agrupado pela instituição de origem (Relatoria, PGR, Polícia Federal, Partes e Defesas,
|
a investigação do colapso do Banco Master (Operação Compliance Zero). São **3.437 documentos**, de
|
||||||
Secretaria e Cartório) e posicionado pela data real de juntada.
|
2018 a 2026, organizados por data e por quem os produziu (STF, PGR, Polícia Federal, partes/defesas,
|
||||||
|
cartório).
|
||||||
|
|
||||||
**Ver a página publicada:** (preencha aqui o link do GitHub Pages depois do primeiro deploy)
|

|
||||||
|
|
||||||
## Como os dados foram montados
|
## O que dá pra fazer aqui
|
||||||
|
|
||||||
1. **`docs.json`** — cruzamento de duas fontes do dump original (uma com a instituição de cada
|
- **Ver cada documento no tempo**, agrupado por quem o produziu, com busca por texto ou nº do
|
||||||
documento, outra com data/texto completo/arquivo-fonte). Ver `pipeline/extract.py`.
|
documento e filtro por tipo de documento ou por pessoa citada.
|
||||||
|
- **Clicar em qualquer ponto** para ler o resumo daquele documento e abrir o texto original completo
|
||||||
|
(extraído por OCR dos autos).
|
||||||
|
- **Ver o resumo do processo conexo** ao qual aquele documento pertence — são **53 processos
|
||||||
|
apensados** à Pet16704 (outros inquéritos e petições), cada um com um resumo em linguagem corrente
|
||||||
|
de quem é investigado, quem são os advogados e o que aconteceu.
|
||||||
|
- **Consultar quem é citado**: **292 pessoas** identificadas automaticamente nos textos, com o papel
|
||||||
|
de cada uma (investigado, advogado, autoridade, testemunha etc.) sempre que dava pra inferir com
|
||||||
|
segurança — sem forçar uma classificação quando o texto não dava sinal suficiente.
|
||||||
|
- Alternar para uma **visão em tabela**, pesquisável, como atalho para quem prefere não navegar pelo
|
||||||
|
gráfico.
|
||||||
|
|
||||||
2. **Tipo de documento** — extraído do nome do arquivo-fonte de cada documento (ex.: "Despacho",
|
## De onde vêm os dados
|
||||||
"Petição", "Procuração", "Certidão"), normalizado com acentuação correta.
|
|
||||||
|
|
||||||
3. **Pessoas mencionadas (`people.json` / `PESSOAS.md`)** — reconhecimento de entidades feito
|
Os documentos originais (PDFs digitalizados dos autos) foram convertidos em texto por OCR com o
|
||||||
**localmente, sem usar o Claude para o texto em si**, com o modelo
|
[liteparse](https://github.com/run-llama/liteparse). Os resumos de cada documento e de cada processo
|
||||||
[`pierreguillou/ner-bert-base-cased-pt-lenerbr`](https://huggingface.co/pierreguillou/ner-bert-base-cased-pt-lenerbr)
|
conexo foram escritos por modelos de IA gratuitos rodados via [opencode](https://opencode.ai). O
|
||||||
(BERT treinado no corpus **LeNER-Br**, de textos jurídicos brasileiros). Rodado sobre os 3.437
|
reconhecimento de pessoas citadas nos textos usou um modelo especializado em português jurídico
|
||||||
textos via `pipeline/run_ner.py`.
|
(código e detalhes técnicos em `pipeline/`, para quem quiser conferir).
|
||||||
|
|
||||||
Depois da extração bruta (435 nomes distintos), foi feita uma limpeza:
|
Nada disso substitui a leitura dos autos originais — é um ponto de partida para localizar e cruzar
|
||||||
- separação de nomes que o modelo juntou erroneamente com "e" (ex. "Fulano e Beltrano" → duas
|
informação, não uma fonte verificada. OCR erra, resumo automático simplifica, e reconhecimento de
|
||||||
pessoas), preservando sobrenomes compostos legítimos ("Castro e Silva");
|
nomes automático pode juntar ou deixar de reconhecer alguém. Sempre que algo parecer relevante,
|
||||||
- remoção de nomes de escritórios de advocacia reconhecidos como pessoa por engano;
|
confira no documento original (tem um link pra ele em cada ponto da linha do tempo).
|
||||||
- descarte de fragmentos de um único token (nomes incompletos, ex. só o primeiro nome);
|
|
||||||
- junção de variações do mesmo nome por contenção de tokens (ex. "Daniel Vorcaro" →
|
|
||||||
"Daniel Bueno Vorcaro").
|
|
||||||
|
|
||||||
Resultado: **292 pessoas distintas**, listadas em `people.json` (formato bruto, usado pela
|
|
||||||
página) e em `PESSOAS.md` (tabelas legíveis, agrupadas por papel). O papel processual de cada
|
|
||||||
pessoa (Relator/Ministro, Outorgante/Parte, Peticionante, Advogado(a), Investigado(a),
|
|
||||||
Delegado(a) PF, Senador(a), Deputado(a), Alvo de diligência, Perito(a), Testemunha) foi inferido
|
|
||||||
por frases-gatilho perto de cada menção (ex. "Despacho do Relator X", "Procuração de X
|
|
||||||
constituindo Y", "em desfavor de X"). **63% das pessoas (185 de 292) ficaram sem papel
|
|
||||||
classificado** ("Mencionado(a)") por falta de um sinal textual próximo confiável — isso é
|
|
||||||
esperado e fica visível na própria listagem, não escondido.
|
|
||||||
|
|
||||||
**Limitações conhecidas:** isso é reconhecimento automático de entidades em texto livre, não uma
|
|
||||||
base curada. Pode haver nomes não reconhecidos, variações da mesma pessoa não unificadas, e
|
|
||||||
classificações de papel aproximadas. Trate como um ponto de partida para busca, não como fonte
|
|
||||||
definitiva de identidade ou qualificação processual.
|
|
||||||
|
|
||||||
4. **Recuperação de datas (`pipeline/recover_dates.py`)** — dos 615 documentos sem data de juntada
|
|
||||||
identificada no dump original, 366 tiveram uma data recuperada lendo o texto original do próprio documento em
|
|
||||||
busca da sua linha de fechamento no padrão "Cidade/UF, DD de mês de YYYY." (ex. "Brasília, 10 de
|
|
||||||
abril de 2026."). Esses casos ficam marcados com `dateInferred: true` em `docs.json` e aparecem
|
|
||||||
no resumo do documento como "data lida no texto do documento, não da juntada nos autos" — é uma
|
|
||||||
data real do documento, mas não necessariamente a data em que foi juntado ao processo. Os 249
|
|
||||||
restantes seguem sem data (fora do gráfico, só na tabela). Duas versões mais permissivas foram
|
|
||||||
tentadas e descartadas por amostragem manual antes desta: buscar qualquer "DD de mês de YYYY" no
|
|
||||||
texto pegava datas de citação de leis/decretos ("da Lei 11.419, de 19 de dezembro de 2006") e
|
|
||||||
prazos de normas citadas ("será exigido a partir de 1º de janeiro de 2017") como se fossem a data
|
|
||||||
do documento; e um fallback numérico (`dd.mm.aaaa`) pegava números soltos de anexos técnicos
|
|
||||||
longos (um laudo de vistoria, a validade de um CRECI) sem relação com a data real. Exigir uma
|
|
||||||
cidade e vírgula imediatamente antes da data eliminou os falsos positivos encontrados.
|
|
||||||
|
|
||||||
5. **Autos vinculados (`resumos/parte1/`, `resumos/parte2/`)** — resumos em markdown dos processos conexos citados
|
|
||||||
ao longo da Pet16704 (Inq 5026, Inq 5035, Inq 5050, Inq 5070, Rcl 88121 e diversas Petições —
|
|
||||||
PET 15198, 15375, 15478 etc.), um arquivo por processo mais um `INDEX.md` consolidado em cada
|
|
||||||
pasta. Cobrem partes/investigados, advogados, autoridades e linha do tempo resumida de cada
|
|
||||||
procedimento. Na página, o resumo de qualquer documento da linha do tempo tem um botão "Ver
|
|
||||||
resumo do processo" que busca e mostra o arquivo correspondente aqui.
|
|
||||||
|
|
||||||
## Projeto relacionado
|
## Projeto relacionado
|
||||||
|
|
||||||
[**vorcaros**](https://rafapolo.github.io/vorcaros/) — visualização em grafo da rede societária
|
[**vorcaros**](https://rafapolo.github.io/vorcaros/) — o mesmo caso visto pelo outro lado: um grafo da
|
||||||
(empresas e sócios) ligada às mesmas pessoas que aparecem nesta linha do tempo processual. Os dois
|
rede societária (empresas e sócios) das mesmas pessoas que aparecem aqui.
|
||||||
projetos olham o mesmo caso por ângulos diferentes: um pela rede de negócios, este pelo andamento
|
|
||||||
processual.
|
|
||||||
|
|
||||||
## Aviso
|
## Aviso — leia antes de usar
|
||||||
|
|
||||||
Este projeto reúne informações de um processo público em curso no STF. Nomes, datas e descrições
|
Este material está **sob sigilo nos autos originais**; o que está aqui é uma organização não oficial
|
||||||
refletem o conteúdo dos autos tal como disponibilizado; erros de extração automática (OCR, NER,
|
de conteúdo público do processo, para fins de apuração jornalística e pesquisa. Nomes, datas e
|
||||||
digitação no material de origem) podem existir. Não constitui manifestação jurídica sobre culpa,
|
descrições refletem o conteúdo dos autos tal como disponibilizado, com os erros de extração
|
||||||
inocência ou qualquer qualificação processual das pessoas mencionadas.
|
automática (OCR, IA, digitação no material de origem) que isso pode carregar. Nada aqui constitui
|
||||||
|
manifestação jurídica sobre culpa, inocência ou qualquer qualificação processual das pessoas
|
||||||
|
mencionadas.
|
||||||
|
|||||||
Binary file not shown.
|
After Width: | Height: | Size: 231 KiB |
+33
-9
@@ -267,6 +267,8 @@
|
|||||||
border-radius:999px; padding:2px 9px;
|
border-radius:999px; padding:2px 9px;
|
||||||
}
|
}
|
||||||
.resumo-file{ font-size:10.5px; color:var(--ink-3); line-height:1.5; overflow-wrap:anywhere; }
|
.resumo-file{ font-size:10.5px; color:var(--ink-3); line-height:1.5; overflow-wrap:anywhere; }
|
||||||
|
.resumo-file a{ color:inherit; text-decoration:none; }
|
||||||
|
.resumo-file a:hover{ color:var(--accent); text-decoration:underline; }
|
||||||
|
|
||||||
.resumo-processo-btn{
|
.resumo-processo-btn{
|
||||||
width:100%; text-align:center; font:inherit; font-size:12.5px; font-weight:600; color:var(--accent);
|
width:100%; text-align:center; font:inherit; font-size:12.5px; font-weight:600; color:var(--accent);
|
||||||
@@ -357,6 +359,7 @@
|
|||||||
thead th:hover{ color:var(--ink); }
|
thead th:hover{ color:var(--ink); }
|
||||||
thead th .arrow{ opacity:.5; margin-left:3px; }
|
thead th .arrow{ opacity:.5; margin-left:3px; }
|
||||||
tbody td{ padding:9px 12px; border-bottom:1px solid var(--grid); vertical-align:top; color:var(--ink-2); }
|
tbody td{ padding:9px 12px; border-bottom:1px solid var(--grid); vertical-align:top; color:var(--ink-2); }
|
||||||
|
tbody tr{ cursor:pointer; }
|
||||||
tbody tr:hover td{ background:var(--accent-wash); }
|
tbody tr:hover td{ background:var(--accent-wash); }
|
||||||
td.date{ font-family:"IBM Plex Mono",monospace; font-size:12px; white-space:nowrap; color:var(--ink); }
|
td.date{ font-family:"IBM Plex Mono",monospace; font-size:12px; white-space:nowrap; color:var(--ink); }
|
||||||
td.lane{ white-space:nowrap; }
|
td.lane{ white-space:nowrap; }
|
||||||
@@ -367,9 +370,10 @@
|
|||||||
td.text{ color:var(--ink); max-width:520px; }
|
td.text{ color:var(--ink); max-width:520px; }
|
||||||
td.file{
|
td.file{
|
||||||
font-family:"IBM Plex Mono",monospace; font-size:10.5px; color:var(--ink-3); max-width:220px;
|
font-family:"IBM Plex Mono",monospace; font-size:10.5px; color:var(--ink-3); max-width:220px;
|
||||||
overflow-wrap:anywhere; cursor:pointer;
|
overflow-wrap:anywhere;
|
||||||
}
|
}
|
||||||
td.file:hover{ color:var(--accent); text-decoration:underline; }
|
td.file a{ color:inherit; text-decoration:none; }
|
||||||
|
td.file a:hover{ color:var(--accent); text-decoration:underline; }
|
||||||
.table-foot{ display:flex; align-items:center; justify-content:center; gap:12px; padding:14px; }
|
.table-foot{ display:flex; align-items:center; justify-content:center; gap:12px; padding:14px; }
|
||||||
.table-foot button{
|
.table-foot button{
|
||||||
border:1px solid var(--border); background:var(--page); color:var(--ink);
|
border:1px solid var(--border); background:var(--page); color:var(--ink);
|
||||||
@@ -1309,7 +1313,13 @@
|
|||||||
document.getElementById("resumoId").textContent = p.id;
|
document.getElementById("resumoId").textContent = p.id;
|
||||||
document.getElementById("resumoType").textContent = p.type;
|
document.getElementById("resumoType").textContent = p.type;
|
||||||
document.getElementById("resumoText").textContent = p.text;
|
document.getElementById("resumoText").textContent = p.text;
|
||||||
document.getElementById("resumoFile").textContent = p.file;
|
var fileEl = document.getElementById("resumoFile");
|
||||||
|
fileEl.innerHTML = "";
|
||||||
|
var fileLink = document.createElement("a");
|
||||||
|
fileLink.href = originalMdUrl(p.file);
|
||||||
|
fileLink.target = "_blank"; fileLink.rel = "noopener noreferrer";
|
||||||
|
fileLink.textContent = p.file;
|
||||||
|
fileEl.appendChild(fileLink);
|
||||||
|
|
||||||
var peopleBlock = document.getElementById("resumoPeopleBlock");
|
var peopleBlock = document.getElementById("resumoPeopleBlock");
|
||||||
var peopleWrap = document.getElementById("resumoPeople");
|
var peopleWrap = document.getElementById("resumoPeople");
|
||||||
@@ -1410,6 +1420,13 @@
|
|||||||
return out.join("\n");
|
return out.join("\n");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// r.file (docs.json) is always a path under originals/Parte2/ — every lane
|
||||||
|
// in docs.json has a matching folder there (verified: no lane needs Parte1).
|
||||||
|
function originalMdUrl(file){
|
||||||
|
return "https://git.rodado.xyz/rodado/pet16704/src/branch/main/originals/Parte2/"
|
||||||
|
+ file.split("/").map(encodeURIComponent).join("/");
|
||||||
|
}
|
||||||
|
|
||||||
var processoCache = {}; // process number -> rendered HTML, or null if not found
|
var processoCache = {}; // process number -> rendered HTML, or null if not found
|
||||||
// resumos/parte1/ and resumos/parte2/ live one level above web/ in the
|
// resumos/parte1/ and resumos/parte2/ live one level above web/ in the
|
||||||
// intended (repo-root) deployment, but a local server started from inside
|
// intended (repo-root) deployment, but a local server started from inside
|
||||||
@@ -1668,6 +1685,11 @@
|
|||||||
slice.forEach(function(r){
|
slice.forEach(function(r){
|
||||||
var lane = LANES[laneIndex[r.lane]];
|
var lane = LANES[laneIndex[r.lane]];
|
||||||
var tr = document.createElement("tr");
|
var tr = document.createElement("tr");
|
||||||
|
tr.title = "Ver resumo deste documento";
|
||||||
|
tr.addEventListener("click", function(){
|
||||||
|
setView("chart");
|
||||||
|
openResumo(r, laneIndex[r.lane]);
|
||||||
|
});
|
||||||
|
|
||||||
var tdDate = document.createElement("td");
|
var tdDate = document.createElement("td");
|
||||||
tdDate.className = "date";
|
tdDate.className = "date";
|
||||||
@@ -1694,12 +1716,14 @@
|
|||||||
tdPeople.textContent = (r.people && r.people.length) ? r.people.join(", ") : "—";
|
tdPeople.textContent = (r.people && r.people.length) ? r.people.join(", ") : "—";
|
||||||
tr.appendChild(tdPeople);
|
tr.appendChild(tdPeople);
|
||||||
|
|
||||||
var tdFile = document.createElement("td"); tdFile.className="file"; tdFile.textContent = r.file;
|
var tdFile = document.createElement("td"); tdFile.className="file";
|
||||||
tdFile.title = "Ver resumo deste documento";
|
tdFile.title = "Abrir o documento original";
|
||||||
tdFile.addEventListener("click", function(){
|
var fileLink = document.createElement("a");
|
||||||
setView("chart");
|
fileLink.href = originalMdUrl(r.file);
|
||||||
openResumo(r, laneIndex[r.lane]);
|
fileLink.target = "_blank"; fileLink.rel = "noopener noreferrer";
|
||||||
});
|
fileLink.textContent = r.file;
|
||||||
|
fileLink.addEventListener("click", function(e){ e.stopPropagation(); });
|
||||||
|
tdFile.appendChild(fileLink);
|
||||||
tr.appendChild(tdFile);
|
tr.appendChild(tdFile);
|
||||||
|
|
||||||
frag.appendChild(tr);
|
frag.appendChild(tr);
|
||||||
|
|||||||
+2
-2
@@ -156,8 +156,8 @@
|
|||||||
}
|
}
|
||||||
.cast-list{ display:grid; grid-template-columns:1fr 1fr; gap:8px 20px; }
|
.cast-list{ display:grid; grid-template-columns:1fr 1fr; gap:8px 20px; }
|
||||||
@media (max-width:560px){ .cast-list{ grid-template-columns:1fr; } }
|
@media (max-width:560px){ .cast-list{ grid-template-columns:1fr; } }
|
||||||
.cast{ display:flex; gap:9px; align-items:baseline; border-top:1px solid var(--line-soft); padding-top:7px; }
|
.cast{ display:flex; flex-direction:column; gap:2px; border-top:1px solid var(--line-soft); padding-top:7px; }
|
||||||
.cast b{ font-size:14px; font-weight:600; white-space:nowrap; }
|
.cast b{ font-size:14px; font-weight:600; }
|
||||||
.cast span{ font-size:12.5px; color:var(--ink-3); }
|
.cast span{ font-size:12.5px; color:var(--ink-3); }
|
||||||
|
|
||||||
/* ---------- footer ---------- */
|
/* ---------- footer ---------- */
|
||||||
|
|||||||
Reference in New Issue
Block a user