Fábrica de corpus legislativo: fetch + parsers + ingest + UI de curación + dueño del schema PostgreSQL. La fuente de verdad operativa es PostgreSQL 16 (ADR-018: Supabase remoto sobre TLS; docker local como espejo read-only); los archivos JSON en data/ son input/fixtures de la ingesta, organizados en una jerarquía que refleja la pirámide normativa (data/<pais>/<nivel>_<tier>/<id>.json; el path se calcula desde TIER_PROFILES en hierarchy.ts).
El serving MCP vive en otro repo: palermo-legal (ADR-021) es el servidor MCP de solo lectura que consume este corpus con el rol argleg_reader (SELECT-only). El server interno de este repo fue retirado en ADR-022, con paridad verificada. El contrato entre ambos repos es el schema de PostgreSQL (src/db/schema-postgres.sql), que este repo aplica y migra.
La mayoría de los MCPs y los RAG legales devuelven texto sin proveniencia explícita — el modelo recibe un fragmento que no sabe distinguir entre fuente oficial firmada, scrape sin revisión humana o un draft no consolidado. En el campo jurídico esa indistinción es tóxica: un abogado no puede citar el output directamente sin verificar contra fuente.
argleg invierte ese default. Toda fila de corpus — sea un artículo, un fallo, un tratado, una relación convencional o una sección estructural — lleva un trust signal tipado, que esta fábrica escribe en el ingest y el server (palermo-legal) emite en cada output:
| Campo | Qué expresa |
|---|---|
source_tier |
oficial_consolidado (1.0) · curado_humano (0.9) · oficial_no_consolidado (0.7) · auto_extraido (0.5) |
confidence_score |
escalar [0.0, 1.0] (v1 derivado deterministicamente del tier; v2 incorporará señales del parser + edad + coherencia estructural) |
status_doctrinario |
dominante / minoritaria / obsoleta / controvertida — sólo en jurisprudencia y doctrina |
Esto le permite a un asistente IA decidir, por cada fragmento que recibe, si puede citar directo (oficial_consolidado / curado_humano) o necesita disclaimer ("según texto editorial no firmado", "según extracción automática sin revisión humana") o verificación adicional contra fuente. La columna confidence_score está desacoplada del source_tier para que un cálculo multi-señal futuro escriba directamente sin migración.
Detalle de implementación: src/laws/trust.ts (vocabulario, asignación en ingest) · docs/adr/009-trust-layer-transversal.md. La emisión per-output (markdown **Trust:** + structuredContent.trust) vive en palermo-legal.
El modelo es multi-país: cada tier de la pirámide normativa lleva prefijo de país (ar_* hoy; Chile próximo). Listo para hospedar México, Colombia, Perú sin migración de schema.
Desarrollado por Guido Barosio en el IA Lab de Palermo E-Law, Universidad de Palermo.
Aviso legal: Esta herramienta es orientativa. El contenido proviene exclusivamente de la base local de argleg y no sustituye el asesoramiento de un abogado matriculado.
- 2026-06-08 — Endurecimiento del parser universal + batch federal (lote 1): la ingesta de leyes muy reformadas expuso 11 clases de corrupción silenciosa del parser (pérdida de artículos, fantasmas "de la ley", quotes-de-sustitución como artículos, firmas/decreto de promulgación/Antecedentes sangrados). 12 fixes con auditoría estructural independiente como gate (no solo conteo). Retro de causa raíz en
docs/engineering/. +10 leyes federales (23.592 + 9 del lote 1: 26.854, 25.065, 26.682, 27.423, 27.348, 25.323, 25.013, 23.546, 14.546). Gate de detectores: 0/0/0/0. - 2026-06-05 (ADR-022) — Retiro del server MCP interno: el serving vive en
palermo-legal(paridad verificada); este repo queda como fábrica de corpus + dueño del schema + UI de curación. −4 deps de runtime, −19 tests de serving (viven en el repo del server). - v0.2.9 (2026-05-22) — Cobertura procesal atómica de Río Negro: 33 normas ingestadas desde el Digesto Jurídico provincial (
web.legisrn.gov.ar) en un único PR. 7 códigos nucleares (CPCC Ley 4142, CPP Ley 5020, CPL Ley 5631, CPF Ley 5396, CCA Ley 5106, LOPJ Ley 5190, Proc. Adm. Ley 2938) + 3 predecesores subsistentes + 23 leyes procesales especiales (MARC, Amicus Curiae, Mediación Penal, Expediente Electrónico, Testigos Protegidos, REPROCOINS, Ejecuciones Hipotecarias, Beneficio de Litigar, Bien de Familia, inembargabilidades, etc.). Total: 2.822 artículos. Pipelineingest-rio-negro-normas.tscon post-processing de patrón "ley aprobatoria + anexo" + sanitización de bleed estructural. Gate de detectores: 0/0/0/0. - v0.2.3 (2026-05-19) — Código Procesal Penal de la Provincia de Buenos Aires (Ley 11922) incorporado al corpus (572 arts, 108 nodos). Refactor del ingest PBA a registry pattern (
npm run ingest:pba). Post-processpatchDerogatedFromHtmlpara artículos formalmente derogados con body vacío. PR #132. - v0.2.2 (2026-05-19) — Código Procesal Civil y Comercial de la Provincia de Buenos Aires (Decreto-Ley 7425/68) incorporado al corpus (875 arts, 152 nodos: 9 libros + 31 títulos + 86 capítulos + 26 secciones). Universal-parser reconoce
SECCIÓN Na(ordinal abreviado español). PR #131. - v0.2.1 (2026-05-18) — Fix bloqueante (HU-BUG-001):
NormaSchemayJurisprudenciaInternacionalRowSchemadeclaraban menos campos que los handlers emitían; clientes MCP estrictos (protocolVersion2025-11-25) rechazaban 4 tools con "Tool execution failed". Soporte de Postgres remoto sobre TLS (Supabase Session Pooler) con CA pinneado +.envauto-load. PR #130. - v0.2.0 (2026-05-18) — FTS sobre PostgreSQL 16 + observabilidad mínima. Baseline de performance validado:
search_articlesejecuta en <4 ms sobre 14.304 artículos con GIN index sobretsvector(Spanish dict + unaccent). EXPLAIN ANALYZE archivado en PR #128.
git clone https://github.com/gubaros/argleg.git
cd argleg
npm install
npm run db:up # docker compose up -d Postgres 16 + pg_trgm + unaccent
npm run db:init && npm run db:import
npm run ui # UI de curación + detectores de errores del corpusLas env vars ARGLEG_* (ver tabla en CLAUDE.md) se levantan automáticamente de un archivo .env en la raíz del repo si existe — útil para apuntar el ingest a Supabase u otro PG remoto sin exportar variables a mano. El shell env siempre gana sobre .env, y .env está gitignored.
Para consultar el corpus desde un cliente MCP (Claude Desktop, Cursor, etc.), usar el server palermo-legal — este repo no sirve MCP (ADR-022). Guías históricas: docs/guia.md · docs/guide.md.
133 normas · 19.124 artículos + 16 tratados internacionales · 13 casos Corte IDH · 4 fallos CSJN doctrinarios · 57 relaciones convencionales · 0 errores en detectores de calidad
Pirámide normativa (19 tiers: 16 argentinos + 3 internacionales, todos prefijados por país o internacional_*):
| # | Tier | Ámbito | Ejemplos |
|---|---|---|---|
| 1 | Constitución + tratados constitucionales | federal | CN; DDHH del art. 75.22 |
| 2 | Tratados internacionales | federal | Supralegal infraconstitucional |
| 3 | Códigos de fondo + procesales + leyes federales | federal | CCyC, Penal, CPCCN, CPPF, leyes |
| 4-5 | DNU, decretos delegados, decretos PEN | federal | art. 76 / 99 CN |
| 6 | Resoluciones, disposiciones | federal | actos administrativos |
| 7 | Constituciones provinciales + CABA | provincial | 23 provincias + CABA |
| 8-9 | Leyes y decretos provinciales | provincial | |
| 10 | Ordenanzas municipales | municipal | |
| — | internacional_jerarquia_constitucional |
internacional | art. 75 inc. 22 CN |
| — | internacional_supralegal |
internacional | Belém do Pará, Protocolo San Salvador |
| — | internacional_legal |
internacional | tratados con jerarquía de ley |
Definición completa: src/laws/hierarchy.ts.
Detalle exhaustivo del corpus (58 normas federales + 24 constituciones + 16 tratados internacionales + 2 códigos provinciales Buenos Aires): docs/corpus/.
Capa de inteligencia jurídica (8 ramas, 17 principios, 10 entradas de doctrina, 15 vínculos norma↔rama): docs/legal/.
Capa de control de convencionalidad (ADR-013): 16 tratados internacionales — constitucionales (art. 75 inc. 22): CADH, PIDCP, Declaración Universal de DDHH, CAT (Convención contra la Tortura), CDN (Convención sobre los Derechos del Niño, ratificada por Ley 23.849), CRPD (Convención sobre los Derechos de las Personas con Discapacidad, elevada por Ley 27.044); supralegales: Belém do Pará, Protocolo San Salvador, Conv. Civiles de la Mujer, Conv. Interamericana contra el Terrorismo, Conv. de Protección de Personas Mayores, OIT 87 (Libertad Sindical), OIT 98 (Negociación Colectiva), OIT 138 (Edad Mínima de Admisión al Empleo), OIT 169 (Pueblos Indígenas), OIT 182 (Peores Formas de Trabajo Infantil). Plus 13 casos doctrinarios de la Corte IDH, 4 fallos CSJN sobre convencionalidad (Ekmekdjian c/ Sofovich 1992, Giroldi 1995, Mazzeo 2007, Fontevecchia CSJN 2017) y 57 relaciones convencionales curadas entre artículos argentinos y artículos de tratados / casos — entre ellas las 10 del batch 2026-05-16 que cierran el loop con las leyes Tier 1 DDHH ingestadas: Ley 26.485 (Protección Integral Mujeres) ↔ Belém do Pará; Ley 24.660 (Ejecución Penal) ↔ CADH art. 5; Ley 26.378 (aprobación CRPD) ↔ CRPD art. 1 (reanclada a la base canónica tras ingesta del tratado); Ley 26.827 (MNPT) ↔ CADH art. 5; Ley 26.390 (Trabajo Infantil) ↔ OIT 182 art. 3 (peores formas) + OIT 138 art. 2 (edad mínima general); CCyC art. 31 (reglas de capacidad jurídica restringida) ↔ CRPD art. 12 (igual reconocimiento como persona ante la ley); y las 2 del alta CDN 2026-06-05: Ley 26.061 art. 3 (interés superior) ↔ CDN art. 3 + Ley 26.061 art. 24 (derecho a ser oído) ↔ CDN art. 12.
Versionado temporal del corpus (ADR-014, issue #57): cada normas y articulos lleva version_hash SHA-256 reproducible + captured_at ISO timestamp, escritos por esta fábrica en cada ingest. v1 solo modela la versión actual; snapshots históricos son v2.
Los JSON se organizan en una jerarquía que refleja la pirámide normativa. El path es calculado por tierRelDir/normaRelDir en src/laws/hierarchy.ts — no hay catálogo paralelo de paths.
data/
├── ar/
│ ├── 1_constitucion_nacional/
│ ├── 3_codigo_fondo/
│ ├── 3_codigo_procesal_federal/
│ ├── 3_ley_federal/
│ ├── 5_decreto_pen/
│ ├── 7_constitucion_caba/
│ ├── 7_constitucion_provincial/
│ └── 8_ley_provincial/
├── int/
│ ├── 1_jerarquia_constitucional/
│ └── 2_supralegal/
├── _seeds/ (jurisprudencia_seed.json, relaciones_convencionales_seed.json, etc.)
├── saij/ (cache de jurisprudencia SAIJ, por año/FAID)
└── _reocr/ (scratch OCR, gitignored)
Las fuentes originales (*-source.pdf/html, gitignored) quedan junto a su JSON parseado en el mismo subdirectorio. Si un tier cambia de nivel o nombre, el directorio esperado se mueve automáticamente — hay que git mv el JSON; un olvido aparece como norma faltante en db:reset.
Vía palermo-legal (ADR-021/022), el server MCP de solo lectura: 14 tools (búsqueda FTS, artículos con bloque de convencionalidad, tratados, jurisprudencia internacional, ramas), resources law://… y prompts. Lee Supabase con el rol argleg_reader (SELECT-only) y valida el schema al boot — un rename o cambio de tipo en este repo lo hace fallar ruidosamente, por diseño.
Todo lo que el server emite (trust signal, convencionalidad, version_hash) se origina en columnas que esta fábrica escribe: la correctitud del output downstream se cura acá.
argleg se distribuye en dos SKUs bifurcados (ver ADR-010). Este repo es Free.
Free (argleg-core) |
Premium (argleg-pro) |
|
|---|---|---|
| Audiencia | Académica / personal · contribuidores OSS | Estudios, legaltechs, IA Lab Palermo E-Law |
| Paquete | este repo (fábrica) + palermo-legal (serving) | privado, bajo contrato |
| Transport | stdio MCP (palermo-legal) | HTTP MCP + REST (OpenAPI) |
| Auth | ninguna | API keys + per-tenant + rate limits |
| Storage | Supabase (source-of-truth) + Postgres 16 local espejo | Postgres managed (Neon/Supabase/RDS) + adapters Drive / OneDrive / S3 |
| Audit log | — | inmutable + cold-storage (Glacier) |
| Trust signals (ADR-009) | sí (transversal) | hereda Free, agrega session traceability |
| Corpus + parser + intelligence | source-of-truth | compone Free, no clona (constraint duro) |
| Licencia | LICENSE — no comercial restringida | comercial, partnership |
Issues clasificados con labels tier:free / tier:premium / tier:both en Project ArLeg #5. Item tier:both = base en core, extensión en pro.
ADRs: ADR-024 (ingest data-driven) · ADR-026 (alta de tribunales)
El tab Ingreso de la UI de curación (Stilus) es el hub único de alta de todo el corpus, pensado para operadores que conocen la fuente legal pero no el codebase. Un rail a la izquierda elige qué dar de alta; los demás tabs son de lectura/edición.
npm run ui # http://localhost:4001 (UI_PORT para cambiar el puerto)| Entidad | Alta |
|---|---|
| Norma | URL de InfoLEG → propuesta → revisar → promover (ver abajo). |
| Artículo | Alta manual en una norma existente dentro de una tx verificada por el gate (orphan/vacío/bleed): si rompería el corpus, se rechaza y no toca nada. |
| Estructura | Nodo del árbol normativo (libro/título/capítulo/sección). |
| Inteligencia | Rama · principio · doctrina · vínculo norma↔rama. |
| Convencionalidad | Relación artículo↔tratado / Corte IDH (ADR-013): en disputa, las dos posiciones con status='controversia'. |
| Tribunal | Alta en el catálogo, auditada por operador (ADR-026). |
- Ingresar (
POST /api/propuestas): pegás la URL de InfoLEG +norma_id+ tier. Sólo se parsea si la norma no existe: la identidad real es la fuente (fuente_url), no el id tipeado — si esa URL ya está en el corpus (aunque sea bajo otro id), corta antes del parse con un mensaje claro. El parser universal deja la propuesta en estadoparseada. - Revisar y decidir (
GET /api/propuestas/:id): leés el articulado parseado + los warnings del parser, y promovés o la dejás pendiente. - Promover (
POST /api/propuestas/:id/promover): importa la norma al SoT (PostgreSQL) en una transacción verificada — corre los 4 detectores del gate escopeados a la norma y sólo commitea si está limpia (si algo dispara, rollback + 422, nada toca el corpus). Exigevigencia(vigente/derogada), nuncadesconocido.source_tier = curado_humano(0.9).
Pendientes (paso 3) tiene acciones masivas: seleccionar varias propuestas y eliminarlas en bloque o cambiarles el estado (limpieza de la cola — nunca toca el corpus).
Gate NON-NEGOTIABLE: antes de commitear, el tab Errores debe mostrar 0 errores. Quórum actual = 1 (el mismo operador que parsea puede promover; el mecanismo para quórum 3 está previsto).
El camino CLI clásico (3 gatekeepers de código + npm run fetch) sigue siendo el canónico para releases y para normas que requieren parser por ley. Ver docs/engineering/adding-a-norm.md.
Pipeline batch separado del ingest normativo. Diseño en ADR-012, schema en ADR-011.
# Listar fallos CSJN 2026 (dry-run, sin ingestar)
npm run fetch-saij -- --tribunal csjn --year 2026 --list
# Ingest batch
npm run fetch-saij -- --tribunal csjn --year 2026 --limit 10
# Reingest de un fallo único (fuerza refresh)
npm run fetch-saij -- --id FA26000054 --force
# Replay del cache local (sin VPN argentina ni Playwright)
npm run fetch-saij -- --from-cache
npm run fetch-saij -- --from-cache --tribunal csjn --year 2026Pipeline two-phase: listado JSON contra /busqueda (barato, sin browser) + detalle vía Playwright headless (SPA JS-rendered). Rate limit ≤1 req/seg. Cache local en data/saij/<año>/<id>/. Cuando aparece un apellido no catalogado en jueces, el ingest NO se completa: escribe en jueces_pendientes para revisión humana. v1 sólo soporta CSJN; el resto del catálogo de tribunales se habilita por entry en src/scripts/parsers/saij-tribunal-mapper.ts.
Modo replay (--from-cache / --replay): los parsed.json del cache están commiteados al repo, así que cualquier máquina sin acceso a SAIJ puede reconstituir la DB completa corriendo npm run db:reset && npm run fetch-saij -- --from-cache. Reusa el mismo insertJurisprudencia que el flow online, así que reconciliación de jueces, idempotencia y trust signal son idénticos.
- Proponer una norma nueva: abrir issue con label
epic:lcp. - Implementar el ingest: ver docs/engineering/adding-a-norm.md.
- Backlog operativo: Project ArLeg #5 — filtrar por
tier:freepara ver lo que se desarrolla acá. - Reglas para agentes IA: CLAUDE.md.
- Decisiones arquitectónicas: docs/adr/.
Palermo E-Law es el Centro de Estudios de Derecho Digital de la Facultad de Derecho de la Universidad de Palermo. Promueve el estudio de las implicancias de la tecnología en el campo jurídico, ofreciendo un espacio de formación, debate, cooperación interinstitucional e investigación.
Este proyecto forma parte del IA Lab, orientado a explorar el uso de IA como herramienta de apoyo a la práctica e investigación jurídica. Palermo E-Law está liderado por los abogados Anibal Ramirez y Hernán Quadri.
Copyright © 2026 Guido Barosio.
Código de fuente abierta. Queda prohibido el uso comercial y la integración en otros sistemas sin autorización expresa del autor. Toda modificación debe canalizarse mediante pull request en el repositorio oficial. Ver LICENSE para el texto completo.
Consultas: gbarosio@gmail.com