Skip to content

gubaros/argleg

Repository files navigation

Arg Leg MCP

Node.js CI Licencia

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.

El diferenciador: trust signal verificable en cada output (ADR-009)

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.

Multi-país, multi-tier

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.


Hitos

  • 2026-06-08Endurecimiento 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. Pipeline ingest-rio-negro-normas.ts con 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-process patchDerogatedFromHtml para 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): NormaSchema y JurisprudenciaInternacionalRowSchema declaraban menos campos que los handlers emitían; clientes MCP estrictos (protocolVersion 2025-11-25) rechazaban 4 tools con "Tool execution failed". Soporte de Postgres remoto sobre TLS (Supabase Session Pooler) con CA pinneado + .env auto-load. PR #130.
  • v0.2.0 (2026-05-18) — FTS sobre PostgreSQL 16 + observabilidad mínima. Baseline de performance validado: search_articles ejecuta en <4 ms sobre 14.304 artículos con GIN index sobre tsvector (Spanish dict + unaccent). EXPLAIN ANALYZE archivado en PR #128.

Quick start

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 corpus

Las 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.


Lo que contiene el corpus

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.

Layout de data/

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.


Cómo se consume el corpus

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á.


SKUs — Free vs Premium

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.


Ingreso al corpus desde la UI (hub de alta)

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).

Flujo de una norma (3 pasos)

  1. 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 estado parseada.
  2. Revisar y decidir (GET /api/propuestas/:id): leés el articulado parseado + los warnings del parser, y promovés o la dejás pendiente.
  3. 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). Exige vigencia (vigente/derogada), nunca desconocido. 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).

Camino CLI (sin cambios)

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.


Ingest de jurisprudencia (SAIJ)

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 2026

Pipeline 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.


Cómo contribuir


Sobre Palermo E-Law

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.


Licencia

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

About

Servidor MCP que expone la legislación argentina (CCyC, Código Penal, Constitución, CPCCN, Ley de Defensa del Consumidor y más) como herramientas consultables — busca artículos por palabra clave, recupera el texto completo y comparé disposiciones en paralelo.

Topics

Resources

License

Security policy

Stars

0 stars

Watchers

0 watching

Forks

Packages

 
 
 

Contributors