diff --git a/.gitignore b/.gitignore index 836353b..e456e6f 100644 --- a/.gitignore +++ b/.gitignore @@ -215,3 +215,7 @@ dist vite.config.js.timestamp-* vite.config.ts.timestamp-* .vite/ + +# LOCAL-ONLY (no commitear): artefactos de sesión, no se versionan (decisión PO 2026-06-22) +examples/ied-presentacion/ +examples/pensamiento-complejo-grafo/ diff --git a/docs/API.md b/docs/API.md index c5f3887..72fcd32 100644 --- a/docs/API.md +++ b/docs/API.md @@ -3,7 +3,7 @@ > Contratos de las costuras y del núcleo: el "producto" que ve quien la integra o la extiende. > Son **bocetos de interfaz** (firmas + docstrings), no la implementación: el código es la fuente de > verdad última y este doc describe el contrato que ese código cumple. Diseño de fondo en -> [`ARCHITECTURE.md`](ARCHITECTURE.md); método en [`Notas/metodología.md`](Notas/metodología.md). +> [`ARCHITECTURE.md`](ARCHITECTURE.md); método en `Notas/metodología.md`. > > El `Corpus` es una **tabla Arrow validada con Pydantic v2** (ADR > [0006](decisiones/0006-tabla-canonica-y-networkspec.md)) respaldada por un **`TabularBackend`** diff --git a/docs/ARCHITECTURE.md b/docs/ARCHITECTURE.md index 92cfe26..69dbfe3 100644 --- a/docs/ARCHITECTURE.md +++ b/docs/ARCHITECTURE.md @@ -6,7 +6,7 @@ > bibliométrica determinista** (*information scent*), sin LLM ni embeddings. El desarrollo sí es > asistido por IA; el producto no. El "porqué" de cada decisión vive en los ADR de > [`decisiones/`](decisiones/) (linkeados en cada sección); el método en -> [`Notas/metodología.md`](Notas/metodología.md); los contratos públicos en [`API.md`](API.md). +> `Notas/metodología.md`; los contratos públicos en [`API.md`](API.md). ## 1. Idea en un párrafo @@ -130,7 +130,7 @@ Funciones puras sobre `networkx.Graph`: **métricas** (densidad, componentes, cl fuerte si falta—, propagación, modularidad voraz), **asortatividad** (por un **atributo categórico configurable** —p. ej. región— y por grado, más la **composición de cada comunidad**; las métricas sobre un **proxy** se reportan con su disclaimer; el atributo es config del usuario, no hardcodeado) e -**informe de calidad** de la co-citación ([`metodología.md`](Notas/metodología.md) §4, umbrales +**informe de calidad** de la co-citación (`metodología.md` §4, umbrales configurables). ### 3.4 `Exporter` — resultados → archivos @@ -248,7 +248,7 @@ expone `CycleState` (`SEEDED/FORAGED/FILTERED/BUILT/MONITORED`), `apply_transiti round) → (state, round)`, `available_transitions(state)` y `CURATION_ACTIONS`. El backend persiste el estado y la **ronda** en `loop_state_log`. -FSM **cíclico** fiel a la [Nota 05](Notas/05-ciclo-investigacion-humano.md): +FSM **cíclico** fiel a la Nota 05: ``` SEEDED ──chain──► FORAGED ──filter──► FILTERED ──build──► BUILT ──monitor──► MONITORED diff --git a/docs/Notas/29-jubilar-notas-debate-a-discussions.md b/docs/Notas/29-jubilar-notas-debate-a-discussions.md new file mode 100644 index 0000000..7d9326c --- /dev/null +++ b/docs/Notas/29-jubilar-notas-debate-a-discussions.md @@ -0,0 +1,279 @@ +# 29 — Jubilar `docs/Notas/`: debate a Discussions, histórico a Wiki, contrato queda en el repo + +> **Estado:** propuesta, pendiente de revisión del PO (2026-07-01). +> **Naturaleza:** Nota de propuesta. **No es ADR todavía** — el ADR baja después de +> revisarla. Esta nota documenta el cambio **antes** de ejecutarse porque rompe una +> convención del repo (la existencia misma de `docs/Notas/` como superficie viva). +> +> ⚠️ **BREAKING CHANGE.** Aunque no toca código, cambia: +> - la convención de género (Notas-archivo jubilan, debate va a Discussions); +> - el estado de ADRs vigentes (0032/0033 → Rechazadas; 0035 → Aceptada en el índice); +> - la ruta de `docs/metodologia.md` (sale de `docs/Notas/`, vive en `docs/`); +> - la existencia de 6 archivos (`NO-HACER-COMMIT-*` se borran); +> - la creación de 4 Discussions y 3 categorías de Wiki que no existían. +> +> Por todo esto se documenta como breaking en el commit (`BREAKING CHANGE:` en el footer +> del commit o `feat!:`), independientemente de que no toque código. + +## 1. El problema + +`docs/Notas/` acumula **31 Notas + 6 borradores + 3 documentos de glosario/método**. +Para un investigador o desarrollador nuevo en el repo: + +- No sabe **cuál es contrato, cuál es debate, cuál es histórico, cuál es borrador**. +- Están mezcladas con la doc viva (`docs/API.md`, `docs/ARCHITECTURE.md`, `docs/PRD.md`). +- Algunas son densas y narrativas (`Nota 18 — flujo canónico de biblioteca`, + `Nota 28 — marco de software`), pensadas para que el PO debata consigo mismo, no para + que un dev nuevo las lea. +- Las más viejas (07, 08, 10, 12, 16) son de la era GUI local — ya **supersedidas por + ADR 0040 (retiro de la GUI)** — pero siguen vivas en disco. + +Sumado a eso: + +- Hay **4 ADRs en estado Propuesta** (0032, 0033, 0034) que perdieron su consumidor con + el retiro de la GUI local (0040). Zombies. +- Hay **2 ADRs perdidos del filesystem** (0042, 0044) que existen en git pero no están + en el árbol actual. Drift. +- Hay **5 Notas que encierran debates vivos** (22 frontera, 25 multi-proveedor, + 27 recibo de demo, 28 posicionamiento, 23 retroalimentación agente) que merecen un + hogar mejor que `docs/Notas/`. + +## 2. La dirección + +Reencuadre de la partición de géneros (que hoy está implícita en la skill `flujo` y se +vuelve explícita acá): + +| Género | Dónde vive hoy | Dónde vive mañana | Por qué | +|---|---|---|---| +| Contrato del producto (qué hace) | `docs/API.md`, `docs/ARCHITECTURE.md`, `docs/PRD.md` | igual | Se mueve en lockstep con el código; PR + CI obligatorio | +| Decisión (por qué) | `docs/decisiones/0001–0043` | igual | Inmutable, citado desde código y otros docs | +| Plan / roadmap | `docs/ROADMAP/` | igual | Cambia con cada hito | +| Reglas del repo | `CONTRIBUTING.md`, `AGENTS.md` | igual | Cómo se trabaja; cómo contribuyen humanos y agentes | +| **Debate vivo (tensión, propuesta)** | **`docs/Notas/` (mezclado)** | **GitHub Discussions (con encabezado estándar)** | Las Discussions viven en el lugar donde realmente se debate; pueden cerrarse sin dejar basura en el repo | +| **Mapa / onboarding / glosario / historia** | **`docs/Notas/` (mezclado)** | **GitHub Wiki** | Estable, narrativo, no requiere PR | +| **Historial / rastro muerto** | **`docs/Notas/` (mezclado)** | **`docs/_archivo/` con `.no-commit`** (no versionado) | Cosas que el PO ya no quiere vivas pero no quiere borrar | +| Borradores del PO | `docs/Notas/NO-HACER-COMMIT-*` | **borrar** | No son notas; son work-in-progress | + +**La regla "no se crean Notas-archivo nuevas" se mantiene — pero la práctica de crearlas +se jubila.** Las que existen, se mueven. + +## 3. Lo que cambia + +### 3.1. Estructura de carpetas del repo + +``` +docs/ +├── PRD.md (sin cambios) +├── ARCHITECTURE.md (sin cambios) +├── API.md (sin cambios) +├── ROADMAP/ (sin cambios) +├── decisiones/ (sin cambios en estructura) +│ ├── README.md (3 filas actualizadas: 0032/0033 Rechazadas, 0035 Aceptada) +│ ├── 0001–0043.md (0032 y 0033 marcados como Rechazada — Supersedida por 0040) +│ └── 0034-etiquetado-tabla-tags-lateral.md (nota de estado agregada: "referencia técnica reusable") +├── metodologia.md (movido desde docs/Notas/, vive en docs/ como autoridad de método) +├── Notas/ (jubilada — ver §3.2) +└── _archivo/ (NUEVO — ver §3.2) + ├── .no-commit (sentinel: explica que esto no se versiona) + └── notas/ (todo el contenido de docs/Notas/ movido acá, sin selección) +``` + +### 3.2. Destino de `docs/Notas/` — todo se mueve, la selección se hace después + +`docs/Notas/` se mueve **completo** a `docs/_archivo/notas/` con `mv` (preservando historia +via git). Esto incluye las 31 notas, los 6 borradores `NO-HACER-COMMIT-*`, los subdirectorios +`02-exploracion/` y `03-referencia/`, y los 3 docs sueltos (`critica-base.md`, +`metodología.md`, `referentes.md`). + +**No se hace selección manual acá.** El criterio rector es: si el PO (o quien revise) +quiere resurrectar algo, está en `_archivo/`. La selección fina de qué sube al Wiki o a +Discussions se hace en una segunda pasada, con tiempo, no en bloque. + +Después del movimiento: + +- `docs/metodologia.md` se **extrae de `_archivo/notas/`** y se mueve a `docs/metodologia.md` + como documento vivo (autoridad de método). Es la única Nota que vive en el repo porque + su rol es ser referencia de método, no contrato ni debate. +- Las **reglas duras** de la `Nota 01 — lecciones de v0` se **extraen** a `CONTRIBUTING.md` + y `AGENTS.md` (ya están citadas en ambos; la nota se borra de `_archivo/notas/` si su + contenido ya vive en otra parte). +- Los **6 borradores `NO-HACER-COMMIT-*`** se **borran** de `_archivo/notas/`. No eran + notas, eran work-in-progress del PO. + +### 3.3. ADRs zombies + +Los ADRs 0032, 0033, 0034 son Propuesta de la era GUI y perdieron su consumidor con el +retiro de la GUI local (0040): + +- **0032 (`capa-servicios-duena-del-flujo`)** → estado cambia a **"Rechazada — Supersedida + por 0040"**. Encabezado: 1 línea. Cuerpo: 1 bloque de Enmienda fechado (3 líneas) + explicando que la GUI murió y `service/` se conserva parcialmente. +- **0033 (`producto-library-centric-grafo-proyeccion`)** → mismo tratamiento. La idea + "BIBFRAME fuera" sobrevive como decisión implícita; se anota en `docs/metodologia.md` + si el PO lo decide (no requiere ADR propio). +- **0034 (`etiquetado-tabla-tags-lateral`)** → se queda como **Propuesta-referencia + técnica**. Una línea en el bloque de estado: "Referencia técnica para tablas laterales + (`referenced_but_not_fetched`, `loop_state_log`); no se promueve porque el consumidor + (GUI) murió. BUG-2 (extensibilidad del schema) queda como decisión abierta del PO." + +El `docs/decisiones/README.md` se actualiza con 3 líneas: 0032 → Rechazada, 0033 → +Rechazada, 0035 → Aceptada (drift menor del índice). + +### 3.4. ADRs perdidos del filesystem (0042, 0044) + +- **0042 (Semantic Scholar como 2º motor)** — existe en commit `a27aa09`, no está en el + árbol actual, README sí lo lista. **Decisión propuesta: dejarlo así.** El código + existe, los issues referencian el número. Si alguien reporta fricción, se recupera en + una PR de hygiene aparte. **No incluir en este cambio** (sería inflar el breaking + change). +- **0044 (precedencia de inclusión manual en curate)** — existe en commit `3417c68`, + mismo caso. Misma decisión: dejar así. + +### 3.5. Discussions nuevas — el nuevo hogar del debate vivo + +Se abren **4 Discussions** con un encabezado estándar que las haga útiles como referencia +futura: + +```markdown +## Pregunta + +[Una pregunta concreta, no un resumen de la Nota] + +## Contexto + +Esta discusión nace de `docs/Notas/NN-titulo.md` (archivado en `docs/_archivo/notas/`). +[5–10 líneas de la tensión] + +## Si esta discusión converge, qué cambia + +- ADR nuevo (¿#XXXX?) con la decisión formal, O +- Cerrar como "no resuelve" sin ADR + +## Estado + +- [ ] Discusión abierta +``` + +Las 4 Discussions que se abren: + +1. **"Frontera de producto: ¿qué entra y qué no en bib2graph?"** — origen `Nota 22`. + Tensión: bib2graph como herramienta vs como suite. Cierra el hueco que ningún ADR + fija con esa claridad (0022 cubre "sin IA"; 0008 cubre forrajeo; "no interpreta, no + gestiona investigación" no está). +2. **"Multi-proveedor: cómo priorizar el 2º motor y la capa Sur-global"** — origen + `Nota 25`. Tensión: S2 vs DOAJ vs SciELO vs CrossRef; el probe empírico ya hizo la + criba pero el orden de implementación no está. +3. **"Extensión de `maturity`: `crossed_red` / `assumed_judgment` / `orphans`"** — + origen `Nota 27`. Tensión: el bloque `maturity` actual (`curated`, `scope`, + `saturated`, `empty_networks`) ya está documentado en `docs/API.md`;该不该 extenderlo + con recibos de juicio humano. +4. **"Posicionamiento de bib2graph: ¿qué tradiciones reivindicamos?"** — origen + `Nota 28`. Tensión: 5 pilares (FCIS, Hexagonal, build hermético, Unix-for-agents, + tools-for-thought determinista); §2-bis de calibración honesta (build hermético = + solo dirección por contenido, no cache-hit; hash plano no Merkle; CLI fail-open + advisory). + +### 3.6. Wiki — el nuevo hogar de lo narrativo + +Se crean **3 categorías** en el Wiki del repo (la Wiki está habilitada): + +- **Wiki / Historia** — `Nota 04` (dirección IA-in-the-loop), `Nota 06` (red-team v0.2), + `Nota 07/08/10/12/16` (era GUI), `Nota 13/14/15/17/19` (QA/sesión). Son rastros del + proceso. +- **Wiki / Papers en progreso** — `Nota 20_ciclo_investigacion_hallazgos_teoricos`, + `Nota 24_referente-snowballing-comparacion`. Son insumos del paper que el PO está + escribiendo. +- **Wiki / QA / footguns** — tabla consolidada de bugs footgun-invisible encontrados en + sesiones (extraídos de las Notas de QA). + +## 4. Por qué es BREAKING (aunque sea docs) + +- **Cambia la convención de género.** Cualquier nota o debate futuro que se hubiera + puesto en `docs/Notas/` ahora va a Discussions. Es un cambio de flujo de trabajo, no + solo de archivos. +- **Borra 6 archivos** (`NO-HACER-COMMIT-*`). Aunque sean borradores, son archivos que + existían en disco. +- **Mueve archivos a una carpeta no versionada** (`docs/_archivo/`). Un dev que espera + encontrar todo en git se va a sorprender. +- **Cambia el estado de ADRs vigentes** (0032, 0033 → Rechazadas; 0035 → Aceptada en el + índice). Quien referencie estos ADRs por nombre debe saber que ya no son propuestas + activas. +- **Abre 4 Discussions y crea 3 categorías de Wiki** que no existían. La fricción para + el PO es administrativa (crear las Discussions manualmente o vía API). + +Por todo esto **debe documentarse como breaking en el commit** (`BREAKING CHANGE:` en +el footer del commit o `feat!:`), independientemente de que no toque código. + +## 5. Lo que NO se hace (explícito) + +- **No se borra `docs/Notas/`** — se mueve a `_archivo/`. +- **No se borran los ADRs zombies** — se marcan como Rechazados. +- **No se crea** ADR 0045 (frontera) ni 0046 (posicionamiento). Esas ideas van a + Discussions; si convergen, recién bajan a ADR. +- **No se recuperan** los ADRs 0042 y 0044 perdidos del filesystem. Si alguien reporta + fricción, se hace en una PR aparte. +- **No se toca código.** Es 100% docs. +- **No se hace selección fina de qué sube a Wiki** en este pase. La selección se hace + en una segunda iteración, con tiempo. + +## 6. Plan de ejecución (cuando el PO apruebe esta Nota) + +5 PRs + apertura/cierre de Discussions, todos `docs/chore`, ninguno toca código: + +| # | PR | Archivos | Tipo | +|---|---|---|---| +| 1 | `chore(docs)!: jubilar docs/Notas/ → docs/_archivo/notas/` | ~37 movidos + 6 borrados + 1 sentinel | `chore!` (breaking) | +| 2 | `docs(adr)!: rechazar 0032/0033 (Supersedidas por 0040) + fix README 0035 + nota en 0034` | 4 archivos | `docs!` (breaking en docs vivos) | +| 3 | `docs(meta): tabla de géneros de documentación en AGENTS.md` | 1 archivo | `docs` | +| 4 | `docs(meta): extracto de reglas duras de la Nota 01 a CONTRIBUTING.md` | 1 archivo | `docs` | +| 5 | `docs!: extraer docs/metodologia.md desde _archivo/notas/` a `docs/metodologia.md` (autoridad de método)` | 1 archivo movido + refs actualizadas | `docs!` (cambio de path) | + +Y fuera de PRs: + +- 4 Discussions abiertas (vía `gh` o web UI). +- 3 categorías de Wiki creadas. + +**Orden sugerido:** PR 1 (mover Notas) → PR 2 (rechazar zombies) → PR 5 (`metodologia`) +→ PR 3 (AGENTS) → PR 4 (CONTRIBUTING). Cada PR es independiente en archivos, no hay +conflictos entre ellos. + +## 7. Riesgos y rollback + +- **Riesgo 1:** un dev nuevo busca una Nota específica y no la encuentra en + `docs/Notas/`. **Mitigación:** el README y `AGENTS.md` explican la nueva partición; el + `_archivo/` está local (no requiere red) para quien quiera consultar. +- **Riesgo 2:** los ADRs rechazados (0032/0033) se referencian desde código o docs como + si siguieran vigentes. **Mitigación:** buscar refs antes de cerrar el PR; actualizar + las refs para que apunten al ADR que sí está vigente. +- **Riesgo 3:** la Wiki está habilitada pero las categorías requieren crear páginas + manualmente. **Mitigación:** si crear las 3 categorías resulta engorroso, basta con + crear las páginas vacías con un índice que apunte a las Discussions. +- **Rollback:** todos los cambios son revertibles con `git revert`. `_archivo/` es local + pero el contenido sigue en git hasta el merge. + +## 8. Preguntas abiertas para el PO + +1. Las 4 Discussions se abren **antes** del movimiento de Notas (para que las Notas + referencien Discussions vivas) o **después** (para que las Discussions referencien + las Notas archivadas)? — **Decidido:** mantener 2 Discussions separadas (Frontera y + Posicionamiento son debates distintos, no se fusionan). +2. ¿Las categorías de Wiki se crean como páginas vacías con índice, o se sube el + contenido de las Notas relevantes directamente? — **Decidido:** Wiki habilitada, se + crean las 3 categorías. +3. La extracción de la `Nota 01` a `CONTRIBUTING.md` y `AGENTS.md` — ¿se hace como + parte de este breaking (PR 4) o se difiere a una PR aparte (menos superficie de + cambio)? — **Pendiente.** +4. ¿Se mantiene el número `29` para esta Nota (siguiente correlativo) o se usa otra + convención dado que la Nota se archiva a sí misma? — **Decidido:** `29`, siguiente + correlativo. Es la última Nota que se mueve. + +## 9. Meta + +Esta es la **última Nota-archivo que se escribe en `docs/Notas/`**. Después de aprobada +y ejecutada, la carpeta se mueve completa a `docs/_archivo/notas/` y la convención +cambia para siempre: cualquier debate futuro va a GitHub Discussions primero; si +converge en decisión firme, baja a ADR; si no, queda como Discussion cerrada. La +práctica de crear Notas-archivo se jubila junto con la regla que la prohíbe. + +La Nota en sí se archiva en `docs/_archivo/notas/29-…md` después de ejecutarse — meta: +una Nota que se archiva a sí misma. \ No newline at end of file diff --git a/docs/Notas/30-paper-joss-doi-citable.md b/docs/Notas/30-paper-joss-doi-citable.md new file mode 100644 index 0000000..fcd4c7f --- /dev/null +++ b/docs/Notas/30-paper-joss-doi-citable.md @@ -0,0 +1,88 @@ +# 30 — Paper citable con DOI (JOSS) + soporte first-class en español + +> **Género:** nota de dirección (nota primero; no es ADR ni doc canónico). +> **Origen:** charla PO ↔ agente: "quiero hacer un paper de bib2graph, con DOI, que se pueda +> citar en investigación" → ¿el paper debe ir en inglés? → si sí, ¿cómo dar soporte first-class +> a hispanohablantes sin sacrificar eso? +> **Para qué:** fijar el camino (JOSS + Zenodo) y dejar registrado, sin ejecutar todavía, qué le +> falta al repo para cumplir el checklist de revisión de JOSS. +> **Relacionadas:** `25-multiproveedor-requerimientos.md` (misión hispana), `28-marco-software-donde-nos-paramos.md` +> (insumo natural para el "Statement of Need" del paper), `docs-espanol-neutro-tuteo` (memoria: +> docs del sitio siempre en español neutro tuteando). + +--- + +## Decisión de rumbo + +- **Vía elegida: JOSS** (Journal of Open Source Software). Gratis, revisión pública en GitHub, + semanas no meses, da DOI vía Crossref al aceptar. Requiere `paper.md` corto (resumen + + statement of need) + `paper.bib`, apoyado en la documentación existente — no un paper largo + desde cero. +- **Idioma:** el `paper.md` de JOSS **debe ir en inglés** (idioma de revisión editorial e + indexación en Crossref). Eso **no** obliga a traducir el sitio: la documentación (mkdocs) sigue + en **español neutro** como hoy — ese es el soporte first-class a hispanohablantes. El paper es + un artefacto aparte y corto que enlaza a esa documentación. +- Único punto de fricción real: los revisores de JOSS instalan y prueban el software siguiendo + las instrucciones del README — conviene que el *quickstart* mínimo tenga versión en inglés (o + README bilingüe) para que puedan seguirlo sin traducir, aunque el resto del sitio quede en + español. + +--- + +## Checklist de JOSS — estado as-built (auditado 2026-07-01) + +| Requisito JOSS | Estado | Evidencia / gap | +|---|---|---| +| Licencia OSI-approved | ✅ | `LICENSE` = GPL-3.0-or-later, declarada en `pyproject.toml` | +| Repositorio público con control de versiones | ✅ | GitHub, 259 commits | +| Tests automatizados | ✅ | 66 archivos `test_*.py`, gate corre `pytest` | +| Instrucciones de instalación | ✅ | README §Instalación | +| Ejemplo de uso | ✅ | README §Quickstart | +| Documentación de API | ✅ | `docs/reference/python-api.md` | +| Guías de comunidad (contribuir/soporte/reportar) | ⚠️ parcial | `CONTRIBUTING.md` cubre setup/commits/tests/releases; falta sección explícita de "cómo pedir soporte" / "cómo reportar un bug" orientada a usuarxs externxs (hoy es más para contribuir código) | +| **Statement of Need** explícito | ⚠️ falta | README tiene "Qué hace" pero no un statement of need al estilo JOSS (a quién sirve, qué problema resuelve, comparación con alternativas). La Nota 28 (§3 "Prior art y huecos") ya tiene el material — falta destilarlo a inglés y forma de paper | +| Autoría nombrada con afiliación/ORCID | ❌ falta | `pyproject.toml` solo dice `"Equipo bib2graph"`; JOSS pide personas reales con afiliación (ORCID opcional pero recomendado) | +| Política de autoría IA | ⚠️ a decidir | `git log` tiene commits co-autorados por "Claude"; JOSS exige autores humanos — hay que decidir cómo se declara el uso de IA (acknowledgment, no autoría) antes de listar autores en el paper | +| `paper.md` + `paper.bib` | ❌ falta | no existen todavía | +| Archivo permanente con DOI (Zenodo / Software Heritage) | ❌ falta | no hay `.zenodo.json` ni integración GitHub↔Zenodo; JOSS exige un archivo depositado que matchee versión/título/autores antes de aceptar | +| `CITATION.cff` | ❌ falta | no existe; no es requisito duro de JOSS pero GitHub lo usa para "Cite this repository" y ayuda a la citabilidad general | +| Alcance ("substantial scholarly effort", no utilidad menor) | ✅ probable | 259 commits, arquitectura documentada en profundidad (Notas 20–29, ADRs); único matiz: el repo tiene ~2 semanas de historia calendario (2026-06-15 → 2026-06-30) — no es un requisito de JOSS pero puede salir en la revisión editorial | + +--- + +## Lo que falta hacer (no ejecutado — solo mapa) + +1. Decidir autoría real para el paper: nombres, afiliación, ORCID de quién corresponda; decidir + cómo declarar la contribución de IA (agradecimiento, no autoría). +2. Escribir sección explícita de soporte/reporte de bugs en `CONTRIBUTING.md` (o README) para + usuarxs, no solo contribuidores de código. +3. Destilar la Nota 28 (§3 prior art, §4 frases-ancla) a un **Statement of Need** en inglés, + corto y defendible. +4. Redactar `paper.md` (summary + statement of need + referencias) y `paper.bib`. +5. Agregar `CITATION.cff`. +6. Conectar el repo a Zenodo (GitHub integration) y archivar el release que se someta a JOSS, + con versión/título/autores idénticos al paper. + +Nota primero — esto es el mapa del checklist, no la ejecución. Próximo paso natural: decidir +autoría (punto 1) antes de tocar nada más, porque condiciona el resto. + +--- + +## Actualización (2026-07-01): esto es de mediano plazo, no ahora + +Dos cambios de rumbo que aplazan todo lo de arriba: + +- **Licencia:** GPL-3.0 no sirve si la idea es que una empresa pueda usar bib2graph sin + obligación de copyleft. Cambiar a **algo tipo Apache-2.0** (o MIT) — sigue siendo open source + (OSI-approved, no rompe el requisito de JOSS), pero permite uso comercial sin las restricciones + de la GPL. Pendiente: auditar si hay dependencias GPL que impidan el cambio de licencia antes + de ejecutarlo. +- **Timing:** el paper (JOSS) y el archivo con DOI **no tienen sentido todavía**. Hoy bib2graph + "abarca varias cosas" — falta que decante a una versión más estable y más **Unix** (que + resuelva bien **un** problema, filo con `frontera-bib2graph-vs-producto`) antes de intentar + publicarlo como paper citable. Publicar ahora sería citar una superficie que todavía se está + recortando. + +**Conclusión:** esta nota queda como mapa de mediano plazo. No es el próximo paso de esta +semana ni del próximo hito — se retoma cuando (a) el alcance esté recortado a algo más Unix y +(b) la licencia ya sea permisiva. diff --git a/docs/Notas/31-feedback_bib2graph.md b/docs/Notas/31-feedback_bib2graph.md new file mode 100644 index 0000000..b4f87dd --- /dev/null +++ b/docs/Notas/31-feedback_bib2graph.md @@ -0,0 +1,543 @@ +# Retroalimentación del uso de bib2graph + +_Informe de feedback sobre una sesión end-to-end de bib2graph v0.11.0 +(instalación → seed → chain → build → informe del estado del arte), con +dos voces diferenciadas: **👤 usuario no técnico** (quien opera) y +**🤖 agente IA** (quien asiste). El reporte secciona el flujo en cuatro +momentos: instalación, forrajeo (seed/chain/build), producción del +artefacto analítico y fricciones transversales del agente._ + +> Esta sesión fue escrita con ánimo constructivo. Los tiempos, errores y +> comandos citados son reales y verificables. La herramienta evoluciona +> rápido; lo que hoy es fricción puede no serlo mañana. El feedback está +> dirigido al mantenedor de bib2graph y a quien use el skill asociado. + +--- + +## 0. Resumen ejecutivo + +| momento | resultado | fricción principal | +|---|---|---| +| Instalación | ✅ limpia, dos comandos | ninguna significativa | +| Forrajeo (seed→chain→build) | ✅ corpus útil (293 papers) | 503 inicial + descubrimiento de la API key | +| Artefacto final (4 markdown + 5 plots) | ✅ entregable de calidad | el primer intento auto-generado fue **rechazado por el usuario**; el valor vino de la lectura real de abstracts por el LLM | +| Fricciones transversales del agente | — | mala lectura inicial, atributos faltantes en graphml, curvas de propagación de env vars | + +**Recomendación de una línea**: bib2graph es una herramienta sólida para +forrajeo bibliográfico agente-native. Su mayor oportunidad de mejora no +está en el core (que funciona), sino en (a) **documentar atributos del +artefacto** (qué hay y qué no en `network.graphml` vs `library.duckdb`), +(b) **hacer explícito el rol del LLM downstream** para análisis de +contenido, y (c) **endurecer el manejo de autenticación de OpenAlex** (api_key). + +--- + +## 1. Instalación + +### 👤 Usuario (no técnico) + +> "Instalé con uv y funcionó. El banner del CLI me llamó la atención: se +> autodefine como 'agente-native'. Eso me hizo pensar que estaba hecha +> para trabajar con un asistente IA, y la verdad es que sí, fue la +> sensación durante toda la sesión." + +**Lo que funcionó**: +- `uv tool install bib2graph` corrió sin fricción. +- `uv tool upgrade bib2graph` llevó de 0.10.0 a 0.11.0 sin + intervención. +- El binario `b2g` quedó disponible globalmente. + +**Lo que costó**: +- Nada material. Una duda menor: el binario adicional `bib2graph` que + quedó instalado junto a `b2g` — no está claro para qué sirve vs. el + canónico. ¿Es un shim? ¿Un entrypoint legacy? + +### 🤖 Agente IA + +> "La instalación fue trivial desde mi lado también. Una nota: confirmé +> el tagline 'CLI agente-native' leyéndolo del `--help`. Ese banner es +> útil: enuncia la promesa del producto y prepara al usuario sobre qué +> esperar." + +**Lo que funcionó**: +- Detección automática de la versión, binario y subcomandos. + +**Fricción observada**: +- **Binarios duplicados sin documentación**: `uv tool install` produjo + dos ejecutables (`b2g` y `bib2graph`). No hubo mensaje explicativo. + Recomiendo: o deprecar `bib2graph` con un mensaje al usarlo, o + documentar la diferencia en `--help`. + +--- + +## 2. Forrajeo: seed, chain, build + +### 2.1 La ecuación + +#### 👤 Usuario + +> "La primera ecuación era buena y ambiciosa: emergenciamás sistemas +> complejos más reduccionismo. Tuvo que ser simplificada porque OpenAlex +> devolvía 503 — algo que atribuimos inicialmente a un outage global pero +> luego descubrimos que era otra cosa." + +#### 🤖 Agente + +> "Cometí un error diagnóstico inicial. El primer 503 me hizo concluir +> 'OpenAlex está caído globalmente'. Era falso. La causa era rate limit +> desde una IP sin auth. Esa mala lectura consumió ~3 turnos de la +> sesión. Lo que me permitió corregir fue la intuición del usuario de +> probar con API key. **Aprendizaje para el skill**: cuando OpenAlex +> devuelve 503 persistente desde un entorno sin auth, **no asumas +> outage**; verificá con `curl` antes de pausar." + +### 2.2 La API key + +#### 👤 Usuario + +> "Yo tenía la key guardada de antes. Se la pasé al agente y dije 'usá +> mi API_KEY'. Pensé que el agente la iba a tomar y listo. No fue tan +> directo: hubo que descubrir que OpenAlex sí la acepta, que bib2graph la +> lee de una variable de entorno específica, y que la env var no se +> propagaba entre los shells del agente. Tardamos varios turnos en +> alinearnos." + +**Fricción reportada**: +- Documentación pública de OpenAlex sugiere que la key no es necesaria; + en la práctica, **sin key, una IP sin auth recibe 503 frecuente**. +- `OPENALEX_API_KEY` no está documentada en `b2g --help`. Tuve que + encontrar la variable buceando en el código de la herramienta. + +#### 🤖 Agente + +> "Cuando el usuario me pasó la key, mi primera respuesta fue 'OpenAlex +> no usa API keys' — **estaba equivocado**. Esa respuesta fue producto de +> lo que dice la doc pública y el `--help` de bib2graph (que no la +> menciona). Tuve que verificar con `curl ?api_key=...` (200 OK) y leer +> el código fuente (`openalex.py:413`) para descubrir: +> +> ```python +> self._api_key = api_key or os.environ.get('OPENALEX_API_KEY') +> ... +> headers['Authorization'] = f'Bearer {self._api_key}' +> ``` +> +> Esto significa dos cosas: +> +> 1. **bib2graph sí soporta api_key**, pero **no lo dice en ninguna +> parte visible al usuario**. Hay un flag `--email` (polite pool) y +> nada más. La variable de entorno `OPENALEX_API_KEY` está +> implementada pero no documentada. +> 2. **El agente tiene que leer el código fuente** para encontrar el +> path correcto. Eso es aceptable para un mantenedor; no lo es para +> un usuario (humano o IA) que solo quiere ejecutar el comando. +> +> **Recomendación concreta**: agregar a `b2g seed --help` una sección: +> +> ``` +> Authentication: +> --email TEXT Email for OpenAlex polite pool (recommended). +> OPENALEX_API_KEY env var improves rate limits (optional but +> recommended for unattended runs). See docs/auth.md. +> ```" + +### 2.3 Propagación de variables de entorno + +#### 🤖 Agente + +> "Otro punto que me costó trabajo: en mi entorno de ejecución, cada +> bash call es un shell nuevo. `set X=Y && comando` en CMD, o +> `export X=Y` en Bash, **no persiste entre invocaciones**. La solución +> que descubrí fue pasar la env var inline: +> +> ```bash +> OPENALEX_API_KEY=... b2g seed ... +> ``` +> +> Esto no es culpa de bib2graph — es del entorno. Pero el usuario +> humano, al ver que 'la env var no se propaga', puede pensar que la +> herramienta está rota. **Recomendación para el skill**: cuando el +> agente explique cómo setear una env var, debe especificar **inline** +> o **cómo exportar persistentemente en el shell del usuario**." + +### 2.4 Chaining costoso + +#### 👤 Usuario + +> "Tuve que esperar casi 5 minutos para el chaining. No fue un problema, +> pero si esto fuera un flujo iterativo de refinamiento sería molesto." + +#### 🤖 Agente + +> "El primer `b2g chain --depth 1` con defaults tardó >5 minutos y +> terminó en timeout (300s). Bajamos `--max-citing` de 50 a 25 y +> `--max-candidates` a 300 — terminó en ~4:43. Sugerencias: +> +> 1. **Documentar tiempos esperados** según tamaño del corpus. Una +> tabla heurística en docs/performance.md ayudaría. +> 2. **Considerar un modo preview más barato**: `--preview` ya existe y +> calcula estimaciones sin fetchear; promoverlo en el `--help` +> ('empezá por acá si tu corpus tiene >200 seeds'). +> 3. **Barra de progreso más informativa**: la actual muestra solo +> 'forward chaining N/M'. Detalle como 'batch X/Y · Z papers +> encontrados hasta ahora' ayudaría a decidir abortar." + +### 2.5 Build y la membresía de cluster + +#### 🤖 Agente + +> "El `b2g build` corrió sin problemas y produjo `clusters.csv` con 6 +> comunidades. Aquí vino la fricción más interesante: la membresía de +> cluster está en `clusters.csv` y en `.corpus_hash`, pero **no como +> atributo de nodo en `network.graphml`**. Esto significa que para +> reproducir el particionado de cluster, hay que correr el algoritmo +> (no es trivial — depende de `python-louvain` y del random_state +> derivado del hash) o leer el CSV. +> +> Mi primera implementación intentó asignar clusters re-corriendo +> Louvain con el mismo `random_state`. **Funcionó**, pero es un punto +> frágil: +> +> 1. Si bib2graph cambia de algoritmo de clustering (de Louvain a otro), +> mi código downstream se rompe silenciosamente. +> 2. Si el usuario cambia `resolution` o `random_state` en build, mi +> código downstream diverge del suyo. +> +> **Recomendación**: persistir el `cluster_id` como atributo de cada +> nodo en `network.graphml` (`N`). Es un +> cambio pequeño en el projector y elimina una clase entera de bugs." + +--- + +## 3. El artefacto final: 4 markdown + 5 plots + +Este es el corazón del reporte, porque es donde el "agente-native" +prometido por el banner se concreta — o se queda corto. + +### 3.1 Primer intento: auto-generación por reglas (rechazado) + +#### 👤 Usuario + +> "El primer informe que me entregó el agente era claramente mediocre. +> Detectaba tags con regex sobre keywords de OpenAlex, asignaba una +> 'idea nuclear' por paper sin leer el abstracto, y rellenaba una PID +> con números arbitrarios. Yo le dije: 'eso no es calidad, vos tenés +> que leer los abstracts'. Era una crítica directa a la confianza del +> agente en sus propias herramientas de reglas." + +#### 🤖 Agente + +> "El primer intento fue un **error estratégico** mío. Tenía Python +> potente (regex sobre texto, conteo de co-ocurrencias, gráficos con +> seaborn) y lo usé para **imitar** el trabajo analítico que solo el +> LLM puede hacer. El output parecía profesional pero era hueco: +> +> - Las 'ideas nucleares' eran inferidas por patrones en el título, no +> por lectura del abstracto. +> - Los 'tags' eran asignados por reglas que matcheaban keywords de +> OpenAlex, no por comprensión del paper. +> - La 'PID' calculaba números pero sin contenido interpretativo. +> +> **Esto fue el momento bisagra de la sesión**. La intervención del +> usuario fue correcta y necesaria. Sin ella, el informe habría sido +> exactamente el tipo de producto que el banner 'agente-native' parece +> prometer pero no puede cumplir si el agente no aprovecha sus +> propios pesos para razonar sobre el contenido. +> +> **Aprendizaje para el skill `bib2graph`**: el skill debería tener una +> sección explícita que diga: +> +> > **Detección automática de etiquetas y resúmenes de ideas es +> > complementaria al análisis del LLM, no sustituto.** Para informes +> > de calidad publicable, el LLM debe leer los abstracts y razonar +> > sobre ellos. Las herramientas de extracción (Python) deben +> > limitarse a entregar el contenido curado al LLM." + +### 3.2 Segundo intento: lectura real de abstracts + +#### 👤 Usuario + +> "El segundo informe fue muy distinto. El agente leyó 38 abstracts uno +> por uno, identificó los autores principales por cluster, caracterizó +> cada cluster con base en lo que los papers dicen (no en keywords +> automáticas), y produjo una discusión que suena a un humano que +> entendió el campo. **Esa es la versión que me sirve**." + +#### 🤖 Agente + +> "El segundo intento fue el que el banner 'agente-native' debería +> producir siempre. La diferencia fue metodológica: en lugar de +> generar texto por reglas, leí cada abstracto y razoné sobre qué dice, +> qué tesis sostiene, qué corriente representa. Las herramientas +> Python quedaron relegadas a su rol correcto: extraer dataset +> (`ideas_input.jsonl`), graficar (`plots.py`). +> +> El resultado fue un paper técnico con: +> +> - 6 comunidades interpretadas por contenido (no solo por tamaño). +> - 38 fichas con idea nuclear leída del abstracto. +> - 10 tensiones entre papers sostenidas en lo que cada uno dice. +> - Una discusión que cruza los clusters y propone líneas de trabajo. +> +> **Tiempo de lectura de abstracts**: ~15 minutos de mi lado. Para un +> usuario humano sería 2-3 horas. La diferencia de productividad es el +> valor real de 'agente-native'." + +### 3.3 Sobre el contenido del artefacto + +#### 👤 Usuario + +> "Lo que más me gustó fue la **caracterización real de los clusters**. +> Mi intuición inicial (que el campo era 'filósofos vs. emergentistas') +> se equivocaba. La red dice otra cosa: el campo se organiza por +> **aplicaciones disciplinares** (lenguaje, organizaciones) más que por +> líneas filosóficas. Esa reorientación me ahorró tiempo de lectura." + +> "La matriz T también me sirvió. Ver **qué papers están en tensión con +> cuáles** me permitió identificar gaps para mi propio trabajo. La zona +> sinérgica Mediano↔Sawyer, por ejemplo, no la había visto." + +#### 🤖 Agente + +> "Las tres cosas que más valor aportan al usuario final, en orden: +> +> 1. **Re-caracterización de clusters desde el contenido**. Mi primer +> intento había puesto C5 como 'información/medida' (siguiendo el +> sesgo del muestreo) cuando en realidad es 'organizaciones y +> liderazgo'. Solo leyendo los abstracts pude corregir esto. +> +> 2. **Identificación de tensiones reales**. No tensiones nominales +> ('Corning habla de emergencia, Lynch habla de biología') sino +> **posturas opuestas sobre el mismo punto** ('Corning dice que la +> sinergia es seleccionada; Lynch dice que la mayor parte de lo +> 'emergente' es subproducto no-adaptativo'). +> +> 3. **Recomendaciones de lectura**. El paper sugiere arrancar por +> Sawyer (2005) + Corning (2002) + Mediano et al. (2022) — tres +> papers que cubren el rango del campo. Sin esa sugerencia, el +> usuario habría tenido que adivinar. +> +> **Recomendación al skill**: explicitar que estos tres tipos de +> entrega (re-caracterización, tensiones, recomendaciones) son el +> **núcleo de valor** del modo 'agente-native' de bib2graph. El skill +> debería orientar al agente a producirlos siempre." + +### 3.4 Sobre los plots + +#### 👤 Usuario + +> "Los plots están bien para un paper, pero la fig5 (la red) sale muy +> densa. Se entiende que es un corpus apretado, pero como figura +> principal podría leerse mejor." + +#### 🤖 Agente + +> "La fig5 (red Louvain) sufre el problema típico de grafos densos: +> nodos centrales todos juntos. Algunas mejoras posibles: +> +> 1. **Layout alternativo**: usar `nx.kamada_kawai_layout` o +> `force_atlas_2` (vía `fa2`) que separa mejor los clusters. +> 2. **Subgrafo por comunidad**: una figura por cluster, no la red +> completa. +> 3. **Heatmap en lugar de grafo**: matriz de adyacencia agrupada por +> comunidad (clustered heatmap) comunica la estructura con menos +> ruido visual. +> +> No es bug de bib2graph — es elección de plot. Lo registro acá +> porque la red es el artefacto que el usuario más va a mirar." + +--- + +## 4. Fricciones transversales del agente + +Esta sección enumera problemas que **no son culpa de bib2graph** sino +de cómo el agente (yo) opera, y que el skill debería mitigar. + +### 4.1 Mala lectura inicial (outage global falso) + +> Ya cubierto en §2.1. Aprendizaje: cuando una API devuelve 503, **no +> asumas outage**; probá con y sin auth antes de pausar. + +### 4.2 Atributos faltantes en `network.graphml` + +> **Hecho**: el graphml tiene `title`, `year`, `doi`, `weight`, +> `is_seed`, `curation_status`, `cluster` (no, este último no está +> como atributo de nodo, solo en `clusters.csv`). **No tiene** +> `keywords`, `authors`, `abstract`. Esos están en `library.duckdb`. +> +> **Fricción**: mi primer código intentó leer keywords del graphml y +> falló silenciosamente (campos vacíos). Tuve que abrir duckdb directo. +> +> **Recomendación para docs**: incluir en `docs/build_artifacts.md` un +> diagrama claro de qué campo está dónde: +> +> ```yaml +> network.graphml: +> por nodo: [id, title, year, doi, weight, is_seed, curation_status] +> por arista: [weight] +> library.duckdb (tabla corpus): +> por paper: [title, abstract, authors_raw, keywords_raw, ...] +> clusters.csv: +> por cluster: [cluster_id, size, top_authors, top_keywords, ...] +> nodes.parquet (si existe): +> combinación de los anteriores +> ``` + +### 4.3 Duvinabilidad de la sincronización graphml ↔ clusters.csv + +> Cubierto en §2.5. **Recomendación**: persistir cluster_id en graphml. + +### 4.4 Sesgo del muestreo automático + +> **Hecho**: mi primer informe caracterizó mal los clusters. El sesgo +> venía de inferir tesis desde títulos y keywords, no desde abstracts. +> +> **Recomendación para el skill**: instruir al agente a **leer +> abstracts antes de caracterizar**, no después. Es decir: el orden +> correcto es +> +> 1. Detectar clusters (Python). +> 2. **Leer abstracts** (LLM). +> 3. Caracterizar clusters con base en lo leído (LLM). +> 4. Construir informe (LLM + Python para plots). +> +> Mi primer orden fue 1 → 3 → 2 (caracterizar antes de leer), lo que +> produjo una caracterización sesgada. + +### 4.5 Propagación de env vars y shelles del agente + +> Cubierto en §2.3. **Recomendación**: el skill debería tener un +> snippet copy-paste del shell del usuario, no del agente. + +### 4.6 El usuario no técnico como señal de calibración + +#### 👤 Usuario + +> "A veces el agente se va por las ramas: hace auto-detección de tags +> que no le pedí, produce plots redundantes, escribe párrafos donde +> pido bullets. **Cuando le digo 'eso no es lo que quiero', corrige**. +> Pero a veces no le digo porque no me doy cuenta hasta verlo +> terminado. Mejoraría la herramienta si el skill tuviera **checkpoints +> obvios** donde el usuario pueda decir 'seguí' o 'eso no, otra cosa'." + +#### 🤖 Agente + +> "Esto es valioso. La sesión fue lineal — yo produje el informe +> entero y el usuario lo aprobó al final. Pero el skill podría +> estructurarse en **fases con checkpoints**, donde después de cada +> artefacto intermedio (`descomposicion_ideas.md`, +> `enriched_ideas.md`, etc.) el usuario revise antes de continuar. +> +> El primer intento (auto-generado) **no tenía checkpoints** — yo +> corrí todo de una. El segundo intento tampoco, pero el usuario +> intervino verbalmente para corregir. +> +> **Recomendación para el skill**: +> +> ``` +> Fase 1: muestreo estratificado → CHECKPOINT al usuario +> Fase 2: lectura de abstracts → CHECKPOINT al usuario +> Fase 3: caracterización de clusters → CHECKPOINT al usuario +> Fase 4: PID y tensiones → CHECKPOINT al usuario +> Fase 5: informe final +> ``` +> +> Cada checkpoint es una pregunta corta: '¿Esto coincide con tu +> intuición del campo? Si no, ¿qué corregirías?'" + +--- + +## 5. Lo que funcionó muy bien (no olvidar) + +A riesgo de que el reporte suene solo a queja, registro lo que salió +bien: + +1. **Reproducibilidad**: el `corpus_hash` → seed Louvain es elegante. + Cambias la ecuación, regeneras, obtienes comunidades comparables. +2. **CLI estable**: `--help` consistente entre verbos; subcomandos + predecibles (`init`, `seed`, `chain`, `build`, `read`, `curate`, + `snapshot`). +3. **`clusters.csv`**: el archivo `.csv` con tamaño, autores + principales y keywords por cluster es un **excelente resumen de + nivel medio**. Lo usé como punto de partida del análisis. +4. **Deprecation limpia**: el `--help` de 0.11.0 anuncia qué aliases + cierran en esa versión (ADR 0038). Es claro para el usuario. +5. **Manejo de errores**: los mensajes accionables ('exit 1 + accionable que sugiere `b2g init` o `--workspace`') son buenos. + Sugerencias concretas en lugar de trazas crípticas. + +--- + +## 6. Recomendaciones priorizadas + +| # | recomendación | para quién | impacto | +|---|---|---|---| +| 1 | Documentar `OPENALEX_API_KEY` en `--help` y `docs/auth.md` | mantenedor | alto: ahorra turnos enteros | +| 2 | Persistir `cluster_id` como atributo de nodo en `network.graphml` | mantenedor | alto: elimina fragilidad | +| 3 | Documentar campos por artefacto (`graphml`, `duckdb`, `clusters.csv`) | mantenedor | medio: reduce tiempo de orientación | +| 4 | Skill con checkpoints obvios entre fases | skill | alto: evita informes rechazados | +| 5 | Skill con sección explícita "el LLM debe leer abstracts, no auto-detectar" | skill | alto: corrige el error más caro | +| 6 | Considerar layout alternativo o heatmap para grafos densos | mantenedor o skill | bajo: estética | +| 7 | Tabla de tiempos esperados para `chain` según tamaño de corpus | mantenedor | bajo: expectativa | +| 8 | Deprecar o documentar el binario `bib2graph` adicional | mantenedor | trivial: confusión menor | +| 9 | (auto) Si OpenAlex devuelve 503 persistente sin auth, **no asumir outage** — probar `?api_key=` antes de pausar | agente | medio: diagnóstico más rápido | + +--- + +## 7. Cómo reproducir esta sesión + +Para el mantenedor o quien quiera replicar: + +```bash +# Setup +uv tool install bib2graph +uv tool upgrade bib2graph # lleva a 0.11.0 +mkdir emergencia-complejidad && cd emergencia-complejidad +b2g init emergencia-complejidad + +# Forrajeo (requiere OPENALEX_API_KEY para evitar 503) +export OPENALEX_API_KEY=... +b2g seed --equation '("emergence" OR "emergent") AND ("complex systems" OR "complexity")' \ + --max-results 200 --email tu@correo.edu +b2g chain --depth 1 --direction both --max-candidates 300 --max-citing 25 +b2g build + +# Análisis (subproyecto uv) +mkdir .informe && cd .informe +uv init --no-readme --no-pin-python --name informe-emergencia +uv add networkx pandas numpy seaborn matplotlib pyarrow python-louvain duckdb +uv run python src/extract.py # genera data/ideas_input.jsonl +# (luego: el LLM lee ideas_input.jsonl y escribe los 4 markdown) +uv run python src/plots.py # genera 5 figuras paper-like +``` + +Outputs: +- `descomposicion_ideas.md` (339 líneas) +- `enriched_ideas.md` (846 líneas) +- `pid-mas-t_inform.md` (139 líneas) +- `informe_estado_del_arte_v1.md` (602 líneas) +- `.informe/figures/fig1-5.png` (300 dpi) + +Tiempo total de la sesión: ~45 minutos (incluyendo iteraciones y +reformulación del informe). + +--- + +## 8. Nota final + +bib2graph entrega lo que promete: forrajeo bibliográfico asistido por +estructura bibliométrica, sin IA generativa en el camino crítico. Esa +**decisión de diseño** es valiosa y debería mantenerse. + +El **valor añadido del modo agente-native** está en el análisis +downstream: el LLM puede y debe leer los abstracts y producir +interpretación que ninguna herramienta de reglas puede. El skill +asociado debería ser más explícito sobre esa frontera: **bib2graph +forrajea, el LLM interpreta**. + +Cuando ambos juegan su rol correcto, el output es publicable. Cuando +el agente intenta reemplazar al LLM con regex y heurísticas, el +output es hueco. Esta sesión transitó de un extremo al otro, y el +punto de inflexión fue una corrección del usuario. **Que ese +punto de inflexión exista es señal de que el skill tiene margen de +mejora en su defaults.** \ No newline at end of file diff --git a/docs/PRD.md b/docs/PRD.md index 8253641..3a91bcc 100644 --- a/docs/PRD.md +++ b/docs/PRD.md @@ -6,7 +6,7 @@ > [0022](decisiones/0022-producto-sin-ia-generativa.md)): la asistencia del forrajeo es estructura > bibliométrica determinista (*information scent*); el desarrollo sí es asistido por IA. Diseño en > [`ARCHITECTURE.md`](ARCHITECTURE.md); contratos en [`API.md`](API.md); método en -> [`Notas/metodología.md`](Notas/metodología.md). +> `Notas/metodología.md`. ## 1. Qué es @@ -39,8 +39,8 @@ que **la colección vive** (berry growing).* ## 2. Problema que resuelve La exploración bibliográfica humana es **iterativa, no lineal** (Kuhlthau, Ellis, Bates, -Pirolli, Wohlin — ver [`Notas/05`](Notas/05-ciclo-investigacion-humano.md) y -[`metodología.md`](Notas/metodología.md)): se siembra, se hace *chaining*, la query y la idea +Pirolli, Wohlin — ver `Notas/05` y +`metodología.md`): se siembra, se hace *chaining*, la query y la idea **mutan** al leer (berrypicking), y la colección **se cultiva** en el tiempo (berry growing). El snowballing manual es mecánico y agota; documentarlo con rigor (PRISMA / vom Brocke) es trabajo. @@ -57,7 +57,7 @@ Falta una herramienta **abierta, poseída por el investigador**, que parta de la consciente**, **asista el forrajeo** usando la estructura bibliométrica como *information scent*, y conserve una **biblioteca viva reproducible**. -La contribución (y la tesis del paper, [`Notas/05`](Notas/05-ciclo-investigacion-humano.md) §5) +La contribución (y la tesis del paper, `Notas/05` §5) es **re-instrumentar el ciclo humano clásico** con un método donde la **estructura bibliométrica funciona como *information scent*** (forrajeo asistido, **determinista y reproducible, sin IA generativa**), **sin desplazar el juicio humano**. Mapeo del ciclo de 9 pasos (05 §3–4) sobre el @@ -215,7 +215,7 @@ viva. La experiencia visual library-centric vive en un **producto separado**, fu bibliométrico** del forrajeo (acoplamiento/co-citación/centralidad, determinista, reproducible). El **juicio humano** (formular la idea, dejarla mutar, decidir qué curar, leer las tensiones) **no se automatiza**. "AI-in-the-loop" se refiere **solo** al *desarrollo* asistido por IA (ver - [`AI_DISCLOSURE.md`](../AI_DISCLOSURE.md)). + `AI_DISCLOSURE.md`). 3. **Núcleo puro, costuras opcionales.** La lógica bibliométrica no depende de servidores ni red. 4. **Configuración inyectada, nunca embebida.** Ningún secreto en el código, sin efectos de import. 5. **Contratos estables y tipados** entre costuras (sin *signature drift*). @@ -310,8 +310,8 @@ Detalle del schema de columnas + la API del wrapper en [`API.md`](API.md) §1. El caso de referencia de bib2graph es **el ciclo de investigación aplicado a la teoría que mejora bib2graph**: la herramienta **se usa a sí misma como objeto de estudio** para iterar su propio diseño. La literatura sobre **forrajeo de información, ciclo de investigación humano y bibliometría** (Bates, -Ellis, Kuhlthau, Pirolli, Wohlin, vom Brocke; ver [`Notas/05`](Notas/05-ciclo-investigacion-humano.md) -y [`metodología.md`](Notas/metodología.md)) es a la vez **el corpus que bib2graph procesa** y **la +Ellis, Kuhlthau, Pirolli, Wohlin, vom Brocke; ver `Notas/05` +y `metodología.md`) es a la vez **el corpus que bib2graph procesa** y **la fuente de los requisitos** del producto: sembrar la ecuación de esa teoría, forrajear sus referencias y citantes, curar la biblioteca viva, proyectar las redes y leer las tensiones es **lo que valida que el método sirve** — y cada vuelta del ciclo retroalimenta el diseño (qué falta en el forrajeo, qué red @@ -324,7 +324,7 @@ vivos** reflejan el resultado, no el debate. El caso **intercambio ecológico desigual (IED)** —el pipeline corrido end-to-end sobre papers reales de OpenAlex, con redes con estructura, thesaurus multilingüe y asimetría Norte–Sur medible (ver -[`exploracion/informe_ied_lectura_2.md`](../exploracion/informe_ied_lectura_2.md))— queda como **caso +`exploracion/informe_ied_lectura_2.md`)— queda como **caso de validación interna histórico**: evidencia de que el método produce resultados con datos reales, **no un criterio de release**. El estudio de semiconductores sigue como caso documentado en -[`metodología.md`](Notas/metodología.md). +`metodología.md`. diff --git a/docs/decisiones/0006-tabla-canonica-y-networkspec.md b/docs/decisiones/0006-tabla-canonica-y-networkspec.md index 43a5891..4d99d28 100644 --- a/docs/decisiones/0006-tabla-canonica-y-networkspec.md +++ b/docs/decisiones/0006-tabla-canonica-y-networkspec.md @@ -45,7 +45,7 @@ que aparecieron al planificar la implementación: sin reinventar un formato. Una exploración más amplia (cuatro arquitecturas candidatas) está en -[`exploracion/arquitecturas-alternativas.md`](../Notas/02-exploracion/arquitecturas-alternativas.md). +`exploracion/arquitecturas-alternativas.md`. Las alternativas evaluadas y descartadas: - **Event sourcing / log inmutable:** sobreingeniería; el mismo poder se diff --git a/docs/decisiones/0007-openalex-backbone.md b/docs/decisiones/0007-openalex-backbone.md index 5e68965..e66f8c8 100644 --- a/docs/decisiones/0007-openalex-backbone.md +++ b/docs/decisiones/0007-openalex-backbone.md @@ -8,7 +8,7 @@ ## Contexto El diseño previo (ver [`../PRD.md`](../PRD.md) anterior y -[`../critica-base.md`](../Notas/critica-base.md) §1) pivoteaba sobre **BibTeX como entrada de +`../critica-base.md` §1) pivoteaba sobre **BibTeX como entrada de referencia**. Pero el BibTeX **no trae las listas de referencias citadas**, y eso fabricaba el problema más caro de toda la arquitectura: un `Enricher` de Semantic Scholar **estructural** para poder construir la red de co-citación (API keys, rate limits, rama opcional, reintentos diff --git a/docs/decisiones/0008-wedge-forrajeo.md b/docs/decisiones/0008-wedge-forrajeo.md index 45c55a3..e7da323 100644 --- a/docs/decisiones/0008-wedge-forrajeo.md +++ b/docs/decisiones/0008-wedge-forrajeo.md @@ -4,8 +4,8 @@ retira del producto; el forrajeo se asiste por estructura bibliométrica, sin IA — ver "Enmienda") - **Fecha:** 2026-06-15 - **Relacionada con:** [0007](0007-openalex-backbone.md), - [`../Notas/04-direccion-ia-in-the-loop.md`](../Notas/04-direccion-ia-in-the-loop.md), - [`../Notas/05-ciclo-investigacion-humano.md`](../Notas/05-ciclo-investigacion-humano.md) + `../Notas/04-direccion-ia-in-the-loop.md`, + `../Notas/05-ciclo-investigacion-humano.md` ## Contexto @@ -28,7 +28,7 @@ tensiones se difiere explícitamente a v2**. Los pasos 5 (organizar en evidencia ## Consecuencias - **Wedge entregable y ya validado**: el sandbox de intercambio ecológico desigual - ([`../exploracion/informe_ied_lectura_2.md`](../../exploracion/informe_ied_lectura_2.md)) corre + (`../exploracion/informe_ied_lectura_2.md`) corre este flujo end-to-end con datos reales de OpenAlex. - La **diferenciación de la V1** descansa en: ecuación consciente + reporte de traducción, biblioteca viva curada, ranking por estructura bibliométrica y CLI agente-native — **no** en @@ -42,7 +42,7 @@ tensiones se difiere explícitamente a v2**. Los pasos 5 (organizar en evidencia ## Enmienda — 2026-06-15 (la máquina de tensiones se retira del producto; el forrajeo no usa IA) > Motivada por el red-team del AS-BUILT v0.2 -> ([Nota 06](../Notas/06-critica-as-built-v0.2.md), RAÍZ 1) y la decisión del PO de que **el producto +> (Nota 06, RAÍZ 1) y la decisión del PO de que **el producto > no usa IA generativa** (ADR [0022](0022-producto-sin-ia-generativa.md)). El cuerpo del ADR (arriba) > queda como historia; esta enmienda corrige dos cosas. diff --git a/docs/decisiones/0010-agente-native-columna.md b/docs/decisiones/0010-agente-native-columna.md index e3e11d8..a9b770a 100644 --- a/docs/decisiones/0010-agente-native-columna.md +++ b/docs/decisiones/0010-agente-native-columna.md @@ -3,7 +3,7 @@ - **Estado:** Aceptada - **Fecha:** 2026-06-15 - **Relacionada con:** [0006](0006-tabla-canonica-y-networkspec.md) (§ CLI como API), - [`../critica-base.md`](../Notas/critica-base.md) §6 + `../critica-base.md` §6 ## Contexto diff --git a/docs/decisiones/0011-thesaurus-multilingue.md b/docs/decisiones/0011-thesaurus-multilingue.md index 3b11321..090abdb 100644 --- a/docs/decisiones/0011-thesaurus-multilingue.md +++ b/docs/decisiones/0011-thesaurus-multilingue.md @@ -5,7 +5,7 @@ - **Fecha:** 2026-06-15 - **Relacionada con:** [0006](0006-tabla-canonica-y-networkspec.md) (`Preprocessor`), [0007](0007-openalex-backbone.md) -- **Validado en:** [`../exploracion/informe_ied_lectura_2.md`](../../exploracion/informe_ied_lectura_2.md) +- **Validado en:** `../exploracion/informe_ied_lectura_2.md` (T6 y T10) ## Contexto diff --git a/docs/decisiones/0012-openalex-credenciales.md b/docs/decisiones/0012-openalex-credenciales.md index bde4b7a..0c749fd 100644 --- a/docs/decisiones/0012-openalex-credenciales.md +++ b/docs/decisiones/0012-openalex-credenciales.md @@ -7,7 +7,7 @@ (ver [`registro-ia.md`](registro-ia.md)) - **Relacionada con:** [0007](0007-openalex-backbone.md) (OpenAlex backbone), [0010](0010-agente-native-columna.md) (config inyectada); lecciones 1 y 6 de v0 -- **Observado en:** [`../../exploracion/scripts/01_search_openalex.py`](../../exploracion/scripts/01_search_openalex.py) +- **Observado en:** `../../exploracion/scripts/01_search_openalex.py` ## Contexto diff --git a/docs/decisiones/0015-corpus-tabular-backend.md b/docs/decisiones/0015-corpus-tabular-backend.md index 800dda2..bc31d69 100644 --- a/docs/decisiones/0015-corpus-tabular-backend.md +++ b/docs/decisiones/0015-corpus-tabular-backend.md @@ -74,7 +74,7 @@ estable entre la biblioteca viva (cualquier backend) y el núcleo puro de proyec `merge` (D3). El `corpus_hash` se computa siempre sobre el contenido (vía `to_arrow()`), nunca sobre detalles del backend. - **Costo (rework del Hito 1).** Hay que migrar `src/bib2graph/corpus.py`. Detalle accionable - para el `coder` en el milestone "Hito 1.5 — Rework de `Corpus`" del [ROADMAP](../ROADMAP/README.md); + para el `coder` en el milestone "Hito 1.5 — Rework de `Corpus`" del ROADMAP; resumen: - Extraer un `TabularBackend` (Protocol) en `src/bib2graph/backends/` (o módulo nuevo). Operaciones mínimas: `add_paper`, `merge`, `set_curation`/`apply_curation`, diff --git a/docs/decisiones/0016-maquina-estados-lazo.md b/docs/decisiones/0016-maquina-estados-lazo.md index 896526a..9c5f417 100644 --- a/docs/decisiones/0016-maquina-estados-lazo.md +++ b/docs/decisiones/0016-maquina-estados-lazo.md @@ -6,7 +6,7 @@ - **Relacionada con:** [0008](0008-wedge-forrajeo.md) (wedge = forrajeo), [0009](0009-biblioteca-viva-duckdb.md) (biblioteca viva en DuckDB), [0015](0015-corpus-tabular-backend.md) (`Corpus` sobre `TabularBackend`), - [`../Notas/05-ciclo-investigacion-humano.md`](../Notas/05-ciclo-investigacion-humano.md) + `../Notas/05-ciclo-investigacion-humano.md` ## Contexto @@ -60,7 +60,7 @@ los estados no son una escalera de un solo sentido. Bates/Ellis/Kuhlthau, al costo de que el `LoopState` es un **mapa**, no un guardia. - **Recomendación para el `coder`:** el `LoopState` (enum + transición + timestamp) y la tabla que lo persiste caen en el **Hito 3** (`DuckDBBackend`/`DuckDBStore`); el comando `b2g status` en el - **Hito 6** (CLI). Ver [ROADMAP](../ROADMAP/README.md) Hitos 3 y 6. + **Hito 6** (CLI). Ver ROADMAP Hitos 3 y 6. - **Tensión declarada:** la máquina de estados es del **archivo vivo**; el **snapshot** (ADR [0017](0017-reproducibilidad-historia-snapshot.md)) es una foto que puede incluir el `LoopState` del instante sellado, pero no es donde vive. @@ -68,7 +68,7 @@ los estados no son una escalera de un solo sentido. ## Enmienda — 2026-06-15 (FSM cíclico de dominio; `reseed` de primera clase; curación transversal) > Motivada por el red-team del AS-BUILT v0.2 -> ([Nota 06](../Notas/06-critica-as-built-v0.2.md), RAÍZ 1): este ADR prometía no-linealidad de +> (Nota 06, RAÍZ 1): este ADR prometía no-linealidad de > primera clase, pero el AS-BUILT la entregó como un enum **lineal** (`SEEDED→FORAGED→FILTERED→BUILT`) > enterrado en `backends/duckdb.py:67-78`, con la no-linealidad reducida a un comentario > ("transiciones permisivas") y la curación **invisible** en el mapa. El cuerpo del ADR (arriba) @@ -77,7 +77,7 @@ los estados no son una escalera de un solo sentido. 1. **El ciclo es un concepto de DOMINIO puro y testeable** — módulo nuevo `cycle.py` (núcleo): el modelo de estados + las reglas de transición viven ahí; el **backend solo lo persiste** (el `LoopState` deja de estar definido dentro de `backends/duckdb.py`). -2. **FSM cíclico fiel a la [Nota 05](../Notas/05-ciclo-investigacion-humano.md):** +2. **FSM cíclico fiel a la Nota 05:** ``` SEEDED ─(chain)→ FORAGED ─(filter)→ FILTERED ─(build)→ BUILT ─(monitor)→ MONITORED diff --git a/docs/decisiones/0017-reproducibilidad-historia-snapshot.md b/docs/decisiones/0017-reproducibilidad-historia-snapshot.md index 7a43639..b21da31 100644 --- a/docs/decisiones/0017-reproducibilidad-historia-snapshot.md +++ b/docs/decisiones/0017-reproducibilidad-historia-snapshot.md @@ -63,7 +63,7 @@ en fechas distintas no son comparables. ## Enmienda — 2026-06-15 (identidad vs procedencia; reloj en la frontera; Louvain seeded) > Motivada por el red-team del AS-BUILT v0.2 -> ([Nota 06](../Notas/06-critica-as-built-v0.2.md), RAÍZ 2): el **principio de este ADR es +> (Nota 06, RAÍZ 2): el **principio de este ADR es > correcto**, pero el **código no lo cumple** — el `corpus_hash` actual **incluye los timestamps de > curación**, así que dos corridas que aceptan los mismos ids producen hash distinto y el snapshot > **no** es reproducible bit a bit. El cuerpo del ADR (arriba) queda como historia; esta enmienda diff --git a/docs/decisiones/0020-metodo-forrajeo-scent-filtros-reject.md b/docs/decisiones/0020-metodo-forrajeo-scent-filtros-reject.md index b831d44..4e3aba0 100644 --- a/docs/decisiones/0020-metodo-forrajeo-scent-filtros-reject.md +++ b/docs/decisiones/0020-metodo-forrajeo-scent-filtros-reject.md @@ -124,7 +124,7 @@ decía que `keywords_id` son los "canónicos (post-thesaurus)": antes de aplicar ## Enmienda — 2026-06-15 (scent bibliométrico determinista; sin LLM) > Motivada por el red-team del AS-BUILT v0.2 -> ([Nota 06](../Notas/06-critica-as-built-v0.2.md), RAÍZ 1) y la decisión del PO de que **el producto +> (Nota 06, RAÍZ 1) y la decisión del PO de que **el producto > no usa IA generativa** (ADR [0022](0022-producto-sin-ia-generativa.md)). El cuerpo del ADR (arriba) > queda como historia; esta enmienda revierte la decisión **A** (scent = frecuencia de enlace) y > elimina el stub LLM. @@ -132,7 +132,7 @@ decía que `keywords_id` son los "canónicos (post-thesaurus)": antes de aplicar 1. **El scent pasa de "frecuencia de enlace" a estructura bibliométrica.** El *information scent* usa los **PROYECTORES** —**acoplamiento / co-citación / centralidad** del candidato respecto del corpus curado— en vez del conteo aritmético de citas directas. Es lo que la - [Nota 05](../Notas/05-ciclo-investigacion-humano.md) §4 siempre prometió ("la bibliometría ES el + Nota 05 §4 siempre prometió ("la bibliometría ES el information scent… mapea a los proyectores"). Sigue siendo una **función pura y determinista** (mismo corpus → mismo ranking, mismo desempate por `id`), **sin LLM ni embeddings**. El forrajeo (costura) **depende del núcleo de proyección** (puro); el núcleo nunca de la costura. @@ -289,8 +289,8 @@ semántica. ### El "no contaminan" era falso — los stubs SÍ contaminaron -Las sesiones de QA con datos reales lo destaparon ([Nota 09](../Notas/09-sesion-qa-prueba-ecologia-valoraciones.md), -[Nota 13](../Notas/13-continuacion-sesion-valoraciones.md), "el bug de fondo del Forager"): los stubs +Las sesiones de QA con datos reales lo destaparon (Nota 09, +Nota 13, "el bug de fondo del Forager"): los stubs `[candidate:W...]` **sí contaminaron**. Llegaron a ser **~la mitad del corpus** (filas-fantasma sin metadata real) y, peor, **entraron al `corpus_hash`** (eran filas del `corpus`, no ruido externo) — rompiendo la reproducibilidad y las redes legibles. La promesa de "curables/enriquecibles después" diff --git a/docs/decisiones/0022-producto-sin-ia-generativa.md b/docs/decisiones/0022-producto-sin-ia-generativa.md index 48274f0..caf3367 100644 --- a/docs/decisiones/0022-producto-sin-ia-generativa.md +++ b/docs/decisiones/0022-producto-sin-ia-generativa.md @@ -3,19 +3,19 @@ - **Estado:** Aceptada - **Fecha:** 2026-06-15 - **Decidido por:** Product Owner humano (tras el red-team de la - [`../Notas/06-critica-as-built-v0.2.md`](../Notas/06-critica-as-built-v0.2.md)) + `../Notas/06-critica-as-built-v0.2.md`) - **Relacionada con:** [0008](0008-wedge-forrajeo.md) (wedge = forrajeo; tensiones removidas), [0011](0011-thesaurus-multilingue.md) (thesaurus determinista, sin fallback LLM), [0020](0020-metodo-forrajeo-scent-filtros-reject.md) (scent = estructura bibliométrica), - [`../Notas/04-direccion-ia-in-the-loop.md`](../Notas/04-direccion-ia-in-the-loop.md) (base de la + `../Notas/04-direccion-ia-in-the-loop.md` (base de la "máquina de tensiones", ahora abandonada), - [`../Notas/05-ciclo-investigacion-humano.md`](../Notas/05-ciclo-investigacion-humano.md) + `../Notas/05-ciclo-investigacion-humano.md` ## Contexto El giro "IA in the loop" (Notas 04/05) proponía **dos puntos de inserción de IA** en el producto: nº1 (forrajeo) y nº2 (sensemaking / "máquina de tensiones"). El red-team del AS-BUILT v0.2 -([Nota 06](../Notas/06-critica-as-built-v0.2.md), RAÍZ 1) mostró que esa IA-en-el-producto es **casi +(Nota 06, RAÍZ 1) mostró que esa IA-en-el-producto es **casi vapor**: el forrajeo rankea por un **conteo aritmético** (no bibliometría, no IA), la curación es **100% humana**, y el único gancho de LLM (`explain_candidate`) es un `NotImplementedError` permanente con el extra `[llm]` vacío. README/AI_DISCLOSURE/Nota 05, en cambio, **venden IA en el @@ -39,7 +39,7 @@ bibliométrica como *information scent***, **determinista y reproducible** (acop [0008](0008-wedge-forrajeo.md) actualizado). El **sensemaking sigue siendo humano**, asistido por las redes (no por IA). 3. **Queda un solo sentido de "AI-in-the-loop":** el *desarrollo* de la librería es asistido por IA - (ver [`../../AI_DISCLOSURE.md`](../../AI_DISCLOSURE.md)); el *producto* **no** usa IA. Ya no hay + (ver `../../AI_DISCLOSURE.md`); el *producto* **no** usa IA. Ya no hay "dos inserciones de IA": hay **una inserción algorítmica** (forrajeo por estructura bibliométrica), que no es IA. @@ -75,7 +75,7 @@ centralidad diferida) se documentan en el AS-BUILT del ADR ## Enmienda — 2026-06-17 (la curación automatizada `[auto-vN]` es opt-in y excepción, NO default · #65) -La [Nota 13](../Notas/13-continuacion-sesion-valoraciones.md) (sesión de QA con el caso +La Nota 13 (sesión de QA con el caso `valoraciones`) usó **curación automatizada por heurísticas de keywords** sobre título/abstract/keywords para cerrar el ciclo de QA sin esperar la CLI de curación (#22/#26). Cada decisión del clasificador quedó marcada con un tag de auditoría (`[auto-v1]`/`[auto-v3]`/ @@ -94,5 +94,5 @@ Esto **NO modifica la decisión de este ADR.** La regla **"la curación es 100% auditoría + reversibilidad humana); el humano sigue siendo quien acepta o revierte. Esa sería una **decisión nueva** (enmienda o ADR nuevo), no un comportamiento por defecto. -Referencia: [Nota 13 — Continuación de la sesión QA](../Notas/13-continuacion-sesion-valoraciones.md) +Referencia: Nota 13 — Continuación de la sesión QA §"La excepción a la regla 'curación 100% humana'". diff --git a/docs/decisiones/0023-capa-constants-modelos-schema.md b/docs/decisiones/0023-capa-constants-modelos-schema.md index 5c19acd..3cfb6dc 100644 --- a/docs/decisiones/0023-capa-constants-modelos-schema.md +++ b/docs/decisiones/0023-capa-constants-modelos-schema.md @@ -3,7 +3,7 @@ - **Estado:** Aceptada - **Fecha:** 2026-06-15 - **Decidido por:** Product Owner humano (tras el red-team de la - [`../Notas/06-critica-as-built-v0.2.md`](../Notas/06-critica-as-built-v0.2.md), secciones CONSTANTS + `../Notas/06-critica-as-built-v0.2.md`, secciones CONSTANTS y MODELS) - **Relacionada con:** [0006](0006-tabla-canonica-y-networkspec.md) (tabla canónica + schema Pydantic), [0013](0013-identidad-hash-merge-corpus.md) (`provenance` como log append-only), @@ -11,7 +11,7 @@ ## Contexto -El red-team del AS-BUILT v0.2 ([Nota 06](../Notas/06-critica-as-built-v0.2.md)) encontró dos clases +El red-team del AS-BUILT v0.2 (Nota 06) encontró dos clases de fragilidad de base: - **No hay módulo de constantes.** ~62 nombres de columna viven como **string-literal** en 14 diff --git a/docs/decisiones/0024-orden-d3-columna-secuencia-duckdb.md b/docs/decisiones/0024-orden-d3-columna-secuencia-duckdb.md index e453af3..4c79d2e 100644 --- a/docs/decisiones/0024-orden-d3-columna-secuencia-duckdb.md +++ b/docs/decisiones/0024-orden-d3-columna-secuencia-duckdb.md @@ -21,7 +21,7 @@ por fila** en cada `merge` (reescribía la tabla entera). La causa raíz: `_arro el orden de primera aparición. La única forma de garantizar D3 era reescribir físicamente toda la tabla en el orden correcto en cada `merge`. -La [Nota 06](../Notas/06-critica-as-built-v0.2.md) / el review marcaron ese **full-rewrite por +La Nota 06 / el review marcaron ese **full-rewrite por merge** como la única operación con olor a ineficiencia real (no un bug) del backend: en una **biblioteca viva** (ADR 0009) que mergea en **cada ronda de chaining/reseed**, reescribir toda la tabla por fila escala mal con el tamaño del corpus. diff --git a/docs/decisiones/0025-enricher-cocitacion-openalex.md b/docs/decisiones/0025-enricher-cocitacion-openalex.md index 36151c6..17a18fb 100644 --- a/docs/decisiones/0025-enricher-cocitacion-openalex.md +++ b/docs/decisiones/0025-enricher-cocitacion-openalex.md @@ -7,11 +7,11 @@ estructural y S2 se demota), [0004](0004-enriquecimiento-opcional.md) (principio de enriquecimiento opt-in, nunca obligatorio, keys inyectadas), [0014](0014-proyeccion-redes-pesos-asortatividad.md) (semántica del `CoCitationProjector`), [0021](0021-cli-agente-native-contrato.md) (set de - subcomandos del CLI), [`metodología.md`](../Notas/metodología.md) (co-citación = citantes compartidos) + subcomandos del CLI), `metodología.md` (co-citación = citantes compartidos) ## Contexto -El Hito 8 ([ROADMAP/04](../ROADMAP/04-lo-que-viene.md)) materializa la costura `Enricher` opt-in +El Hito 8 (ROADMAP/04) materializa la costura `Enricher` opt-in para resolver `references_id`→`references_doi` y habilitar la **co-citación** end-to-end. El DoD original del hito lo encuadraba sobre el extra **`[s2]`** (Semantic Scholar), residuo del diseño **pre-giro** previo al [ADR 0007](0007-openalex-backbone.md): cuando la entrada era BibTeX, el único @@ -78,7 +78,7 @@ El hito es grande para un solo ciclo, por lo que se **parte en dos**: El `CoCitationProjector` (ADR [0014](0014-proyeccion-redes-pesos-asortatividad.md)) **no se toca**: cuenta **`cited_by_id` compartido** = los **citantes compartidos** de la -[`metodología.md`](../Notas/metodología.md). La frase de los docs "citantes con sus citas" se **reconcilia** +`metodología.md`. La frase de los docs "citantes con sus citas" se **reconcilia** documentando que el 2º nivel se materializa como **`cited_by_id`** (8b): "citantes con sus citas" ≡ **`cited_by_id` compartido**, que es lo que el projector ya consume. diff --git a/docs/decisiones/0026-dedup-fuzzy-determinista.md b/docs/decisiones/0026-dedup-fuzzy-determinista.md index 87dc5b9..3ee9bc3 100644 --- a/docs/decisiones/0026-dedup-fuzzy-determinista.md +++ b/docs/decisiones/0026-dedup-fuzzy-determinista.md @@ -23,7 +23,7 @@ ## Contexto -El Hito 7 ([ROADMAP/04](../ROADMAP/04-lo-que-viene.md)) materializa la deduplicación **fuzzy** de +El Hito 7 (ROADMAP/04) materializa la deduplicación **fuzzy** de `authors_id` y `keywords_id`: el complemento aproximado de la normalización conservadora del `Preprocessor` (ADR 0011, Hito 5), que solo colapsa variantes triviales (lowercase, acentos, espacios) y matchea keywords contra el thesaurus curado. Lo que queda son variantes **casi-iguales** diff --git a/docs/decisiones/0027-pivote-posicionamiento-gui-local.md b/docs/decisiones/0027-pivote-posicionamiento-gui-local.md index b0f7dd6..3ed9729 100644 --- a/docs/decisiones/0027-pivote-posicionamiento-gui-local.md +++ b/docs/decisiones/0027-pivote-posicionamiento-gui-local.md @@ -13,8 +13,8 @@ [0021](0021-cli-agente-native-contrato.md) (contrato del CLI), [0029](0029-workspace-por-investigacion.md) (workspace = unidad de proyecto, prerequisito ya hecho). - **Epic:** GUI local [#34](https://github.com/complexluise/bib2graph/issues/34). Dirección en - Notas [07](../Notas/07-frontend-tool-for-thought.md)/[08](../Notas/08-referentes-frontend.md)/ - [10](../Notas/10-sintesis-contextualizacion-gui.md). + Notas 07/08/ + 10. ## Contexto diff --git a/docs/decisiones/0028-arquitectura-gui-api-capa-servicios.md b/docs/decisiones/0028-arquitectura-gui-api-capa-servicios.md index e00f4bb..ffff590 100644 --- a/docs/decisiones/0028-arquitectura-gui-api-capa-servicios.md +++ b/docs/decisiones/0028-arquitectura-gui-api-capa-servicios.md @@ -19,7 +19,7 @@ ## Contexto -La [Nota 12](../Notas/12-arquitectura-gui-encuadre.md) (revisada 2026-06-18) encuadró la arquitectura: +La Nota 12 (revisada 2026-06-18) encuadró la arquitectura: la GUI agrega un **4º frontend (SPA)** y una **costura nueva de servidor (API local)**, sin romper "núcleo puro + costuras". El principio es **no tener dos implementaciones de la lógica de negocio**: CLI y API deben compartir la orquestación. diff --git a/docs/decisiones/0030-ecuacion-declarativa-corpus-ejemplo.md b/docs/decisiones/0030-ecuacion-declarativa-corpus-ejemplo.md index 3acd8ed..241e364 100644 --- a/docs/decisiones/0030-ecuacion-declarativa-corpus-ejemplo.md +++ b/docs/decisiones/0030-ecuacion-declarativa-corpus-ejemplo.md @@ -22,7 +22,7 @@ `corpus_hash`), [0005](0005-dependencias-extras.md) (extra `[bibtex]` perezoso). - **Prerequisito de:** Ciclo #33 ("caso real reproducido") → **gate de #34** (epic GUI). - **Issues / contexto:** #14 (`--max-results`), #30 (`--exclude`), #25/#31 (redes legibles + - `clusters.csv`), #26 (`curate --from-csv`), [Nota 09](../Notas/09-sesion-qa-prueba-ecologia-valoraciones.md) + `clusters.csv`), #26 (`curate --from-csv`), Nota 09 (sesión QA — ecología de valoraciones; agujero R2 de reproducibilidad de comunidades). ## Contexto @@ -353,7 +353,7 @@ lo construido. **Gate verde, 571 tests; el verifier pasa.** **composición de comunidades es estable entre corridas** (Louvain seeded); redes no vacías (coupling 132/3897, author_collab 327/729, institution_collab 136/300, keyword 483/5350; co-citación vacía omitida graceful porque `cited_by_id` está en blanco). **Cierra el agujero R2 - que la [Nota 09](../Notas/09-sesion-qa-prueba-ecologia-valoraciones.md) dejó abierto** sobre la + que la Nota 09 dejó abierto** sobre la estabilidad de la composición de comunidades. - **Bifurcación residual del PO resuelta (opción mínima):** `examples/valoraciones/` commitea **solo el corpus + `equation.yaml` + README + script**, no un `workspace.json`/`library.duckdb` diff --git a/docs/decisiones/0032-capa-servicios-duena-del-flujo.md b/docs/decisiones/0032-capa-servicios-duena-del-flujo.md index 3433f92..deed6b3 100644 --- a/docs/decisiones/0032-capa-servicios-duena-del-flujo.md +++ b/docs/decisiones/0032-capa-servicios-duena-del-flujo.md @@ -10,7 +10,7 @@ [0033](0033-producto-library-centric-grafo-proyeccion.md) (posicionamiento library-centric), [0035](0035-ingesta-multipuerta-resolucion-doi.md) (ingesta multi-puerta + resolución DOI→ID son operaciones de servicio). -- **Encuadre:** [Nota 18](../Notas/18-flujo-canonico-biblioteca.md) (flujo canónico paso a paso). +- **Encuadre:** Nota 18 (flujo canónico paso a paso). - **Epic:** GUI local [#34](https://github.com/complexluise/bib2graph/issues/34) (iterada post-MVP). ## Contexto diff --git a/docs/decisiones/0033-producto-library-centric-grafo-proyeccion.md b/docs/decisiones/0033-producto-library-centric-grafo-proyeccion.md index d645596..e45d2e1 100644 --- a/docs/decisiones/0033-producto-library-centric-grafo-proyeccion.md +++ b/docs/decisiones/0033-producto-library-centric-grafo-proyeccion.md @@ -9,8 +9,8 @@ - **Relacionada con:** [0009](0009-biblioteca-viva-duckdb.md) (biblioteca viva = unidad de trabajo), [0032](0032-capa-servicios-duena-del-flujo.md) (el servicio dueño del flujo lo habilita), [0034](0034-etiquetado-tabla-tags-lateral.md) (etiquetado, parte del ejercicio bibliotecario). -- **Encuadre:** [Nota 16](../Notas/16-retroalimentacion-gui-mvp.md) §Re-priorización/§H1 + - [Nota 18](../Notas/18-flujo-canonico-biblioteca.md). **Decidido por el PO (2026-06-18).** +- **Encuadre:** Nota 16 §Re-priorización/§H1 + + Nota 18. **Decidido por el PO (2026-06-18).** - **Epic:** GUI local [#34](https://github.com/complexluise/bib2graph/issues/34). ## Contexto diff --git a/docs/decisiones/0034-etiquetado-tabla-tags-lateral.md b/docs/decisiones/0034-etiquetado-tabla-tags-lateral.md index 49cde2c..a7d4164 100644 --- a/docs/decisiones/0034-etiquetado-tabla-tags-lateral.md +++ b/docs/decisiones/0034-etiquetado-tabla-tags-lateral.md @@ -8,8 +8,8 @@ (etiquetar es parte del ejercicio bibliotecario primario), [0011](0011-thesaurus-multilingue.md)/ [0031](0031-preprocesamiento-automatico-en-ingesta.md) (tesauro/topics = camino a taxonomía), [0024](0024-orden-d3-columna-secuencia-duckdb.md) (patrón de tablas hermanas fuera del `corpus_hash`). -- **Encuadre:** [Nota 16](../Notas/16-retroalimentacion-gui-mvp.md) §H1/§H1b + - [Nota 17](../Notas/17-validacion-tercero-gate34.md) §BUG-2 + [Nota 18](../Notas/18-flujo-canonico-biblioteca.md). +- **Encuadre:** Nota 16 §H1/§H1b + + Nota 17 §BUG-2 + Nota 18. **Decidido por el PO (2026-06-18): tags libres ahora, tabla lateral, sin BIBFRAME.** - **Epic:** GUI local [#34](https://github.com/complexluise/bib2graph/issues/34). diff --git a/docs/decisiones/0035-ingesta-multipuerta-resolucion-doi.md b/docs/decisiones/0035-ingesta-multipuerta-resolucion-doi.md index 659e085..a508c95 100644 --- a/docs/decisiones/0035-ingesta-multipuerta-resolucion-doi.md +++ b/docs/decisiones/0035-ingesta-multipuerta-resolucion-doi.md @@ -8,8 +8,8 @@ (`seed --from-bib`, 3er modo BibTeX sin red), [0032](0032-capa-servicios-duena-del-flujo.md) (ingesta y resolución viven en `service/`), [0031](0031-preprocesamiento-automatico-en-ingesta.md) (ambas puertas comparten `normalize_and_dedup`). -- **Encuadre:** [Nota 17](../Notas/17-validacion-tercero-gate34.md) §GAP-1/§GAP-2 + DECISIÓN DEL PO + - [Nota 18](../Notas/18-flujo-canonico-biblioteca.md). **Decidido por el PO (2026-06-18): el flujo +- **Encuadre:** Nota 17 §GAP-1/§GAP-2 + DECISIÓN DEL PO + + Nota 18. **Decidido por el PO (2026-06-18): el flujo BibTeX/archivo es de PRIMERA CLASE.** - **Epic:** GUI local [#34](https://github.com/complexluise/bib2graph/issues/34). - **AS-BUILT (0.8, 2026-06-22):** se grada a Aceptada y se implementa el **core de resolución** diff --git a/docs/decisiones/0037-superficie-cli-10-verbos-ciclo.md b/docs/decisiones/0037-superficie-cli-10-verbos-ciclo.md index 93456f4..c028241 100644 --- a/docs/decisiones/0037-superficie-cli-10-verbos-ciclo.md +++ b/docs/decisiones/0037-superficie-cli-10-verbos-ciclo.md @@ -34,7 +34,7 @@ conteos del corpus, sin modelo generativo. - **Origen:** Discussion [#127](https://github.com/complexluise/bib2graph/discussions/127), comentario *"Propuesta de convergencia: superficie agents-first para 0.10.0 (más es menos)"*. - Encuadre: [Nota 05](../Notas/05-ciclo-investigacion-humano.md) (el ciclo de investigación humano) y + Encuadre: Nota 05 (el ciclo de investigación humano) y la **nota de sesión 20** (`docs/Notas/20-ax-agente-cli-redes-vacias.md` — AX de un agente en frío: *"redes vacías con cara de éxito"*; nota de sesión, **aún no versionada en `dev`**, citada como encuadre empírico). @@ -59,7 +59,7 @@ solapamientos** que un agente —y un humano— tienen que desambiguar sin que e Dos hechos de diseño ordenan la salida: -- **La superficie ES el ciclo de investigación.** La [Nota 05](../Notas/05-ciclo-investigacion-humano.md) +- **La superficie ES el ciclo de investigación.** La Nota 05 modela el ciclo humano (Kuhlthau/Ellis/Bates/Pirolli/Wohlin): IDEA → SEMILLAS → CHAINING → BROWSING/DIFERENCIAR → ORGANIZAR → SENSEMAKING → CURAR → MONITOREAR, **iterativo y no lineal**. Una superficie que **mapea 1:1 ese ciclo** es legible sin manual: el verbo *es* el paso. @@ -176,7 +176,7 @@ diagnostica antes** —el agente no se queda con una "cara de éxito" vacía. **Lo que se gana** - **El ciclo se vuelve legible y one-shot.** La superficie mapea 1:1 los pasos de la - [Nota 05](../Notas/05-ciclo-investigacion-humano.md); un agente (o un humano) infiere el flujo sin + Nota 05; un agente (o un humano) infiere el flujo sin manual: el verbo *es* el paso. El default sin curar deja correr `init→seed→chain→build→read` de punta a punta. - **Menos superficie, menos solapamiento.** De ~20 subcomandos con 6 solapamientos a **10 verbos**; diff --git a/docs/decisiones/README.md b/docs/decisiones/README.md index 2488c5d..51d51d8 100644 --- a/docs/decisiones/README.md +++ b/docs/decisiones/README.md @@ -6,7 +6,7 @@ crea un ADR nuevo que la supersede; no se reescribe la historia. Los refinamient revierten el principio se anotan como **bloques de "Enmienda" fechados** dentro del propio ADR (el cuerpo original queda como historia). -**Tras el red-team del AS-BUILT v0.2** ([Nota 06](../Notas/06-critica-as-built-v0.2.md)) el PO +**Tras el red-team del AS-BUILT v0.2** (Nota 06) el PO bloqueó un nuevo modelo conceptual (2026-06-15): el **producto no usa IA generativa** (ADR 0022); el scent es **bibliométrico determinista** (0020 enmendado); el ciclo es un **FSM cíclico de dominio** (0016 enmendado); **identidad ≠ procedencia** (0017 enmendado); y hay una **capa base de @@ -39,7 +39,7 @@ Qué se vuelve posible/fácil y qué se vuelve costoso/imposible. Trade-offs hon > Los ADR se numeran **por orden de creación**, no se reservan en general. **0027** (pivote de > posicionamiento GUI) y **0028** (arquitectura GUI/API + capa de servicios) existen ya como -> *Aceptada* (firmados 2026-06-18), derivados de la [Nota 12](../Notas/12-arquitectura-gui-encuadre.md) +> *Aceptada* (firmados 2026-06-18), derivados de la Nota 12 > (revisada 2026-06-18): **0027 gatea 0028** y enmienda el PRD §3/§5.2. > **Supersedidos por [0040](0040-retiro-gui-local.md)** (2026-06-28): la GUI local se **retira de la > librería** (fuera del foco; el core es CLI/agente-native). 0027/0028 y las Notas de diseño @@ -80,10 +80,10 @@ Qué se vuelve posible/fácil y qué se vuelve costoso/imposible. Trade-offs hon | [0029](0029-workspace-por-investigacion.md) | Workspace por investigación: carpeta autocontenida (`workspace.json` + db + redes/snapshots/exports) + resolución ambiente | **Aceptada — AS-BUILT** (2026-06-16; remanentes #32 cerrados 2026-06-17). **Enmienda BREAKING #75 (2026-06-17):** `--store` eliminado del CLI y fin del modo degenerado — la carpeta con `workspace.json` es la única unidad canónica; `.duckdb` legacy se adopta con `b2g init .`. Enmienda 0009/0019/0021; prerequisito GUI (#34) | | [0030](0030-ecuacion-declarativa-corpus-ejemplo.md) | Ecuación declarativa (`equation.yaml`, `seed --spec`) + `restore` de corpus curado (sin red) + corpus de ejemplo commiteado (`examples/valoraciones/`) + `seed --from-bib` (BibTeX) + filtro de año | **Aceptada — AS-BUILT** (9a + 9b + Ciclo 10, 2026-06-17): `restore`+`equation.yaml` cargable; `examples/valoraciones/` + gate R2; **`seed --from-bib` + `examples/bibtex/` + filtro de año real (#50 cerrado)**. Enmienda 0029; relacionada 0005/0006/0007/0016/0017/0018; prereq. Ciclo #33 → gate GUI (#34) | | [0031](0031-preprocesamiento-automatico-en-ingesta.md) | Preprocesamiento automático en la ingesta (normalize + dedup sobre el corpus completo mergeado, cross-biblioteca); `rapidfuzz` al núcleo (`[dedup]` eliminado); `thesaurus` = único paso explícito (18° subcomando, transversal); `persist_replace`/`overwrite_corpus` | **Aceptada — AS-BUILT** (2026-06-18, #88). **Supersede en parte [0026](0026-dedup-fuzzy-determinista.md)** (invocación del dedup) y la enmienda `[dedup]` de [0005](0005-dependencias-extras.md). Relacionada 0011/0017/0022/0024/0016; revisión asistida de clusters → epic GUI (#34) | -| [0032](0032-capa-servicios-duena-del-flujo.md) | La capa de servicios (`service/`) es dueña del loop bibliográfico completo (ingesta/resolución/enrich/curación/tags/forrajeo/proyección); CLI/API/GUI = adaptadores finos; migración por demanda | **Propuesta** (2026-06-18). **Extiende [0028](0028-arquitectura-gui-api-capa-servicios.md)** (de reads+curate a flujo entero). Relacionada 0010/0021/0027/0033/0035. Encuadre: [Nota 18](../Notas/18-flujo-canonico-biblioteca.md) | -| [0033](0033-producto-library-centric-grafo-proyeccion.md) | Producto library-centric: la vista de Biblioteca (buscar/navegar/etiquetar/curar) es la superficie primaria; el grafo es proyección downstream; BIBFRAME fuera | **Propuesta** (2026-06-18). **Refina [0027](0027-pivote-posicionamiento-gui-local.md)** (puerta de entrada de la GUI, no revierte). Relacionada 0009/0032/0034. Encuadre: Notas [16](../Notas/16-retroalimentacion-gui-mvp.md)/[18](../Notas/18-flujo-canonico-biblioteca.md) | -| [0034](0034-etiquetado-tabla-tags-lateral.md) | Etiquetado en tabla LATERAL `paper_tags` (no toca `CORPUS_SCHEMA`, esquiva BUG-2); tags libres → taxonomía fase 2 (SKOS + OpenAlex topics, no BIBFRAME); fuera del `corpus_hash` | **Propuesta** (2026-06-18). Relacionada 0009/0023/0006/0033/0011/0031/0024/0017. **Deja abierta** la extensibilidad general del schema (BUG-2). Encuadre: Notas [16](../Notas/16-retroalimentacion-gui-mvp.md)/[17](../Notas/17-validacion-tercero-gate34.md) | -| [0035](0035-ingesta-multipuerta-resolucion-doi.md) | Ingesta de doble puerta (online + archivo) misma cadena/corpus; resolución DOI→OpenAlex ID como servicio compartido (cierra GAP-1/GAP-2); import multi-formato (RIS/EndNote/CSV); BibTeX/archivo = primera clase | **Propuesta** (2026-06-18). **Revisa "BibTeX secundaria" de [0007](0007-openalex-backbone.md)** (en la ingesta). Relacionada 0018/0030/0032/0031. Encuadre: [Nota 17](../Notas/17-validacion-tercero-gate34.md) | +| [0032](0032-capa-servicios-duena-del-flujo.md) | La capa de servicios (`service/`) es dueña del loop bibliográfico completo (ingesta/resolución/enrich/curación/tags/forrajeo/proyección); CLI/API/GUI = adaptadores finos; migración por demanda | **Propuesta** (2026-06-18). **Extiende [0028](0028-arquitectura-gui-api-capa-servicios.md)** (de reads+curate a flujo entero). Relacionada 0010/0021/0027/0033/0035. Encuadre: Nota 18 | +| [0033](0033-producto-library-centric-grafo-proyeccion.md) | Producto library-centric: la vista de Biblioteca (buscar/navegar/etiquetar/curar) es la superficie primaria; el grafo es proyección downstream; BIBFRAME fuera | **Propuesta** (2026-06-18). **Refina [0027](0027-pivote-posicionamiento-gui-local.md)** (puerta de entrada de la GUI, no revierte). Relacionada 0009/0032/0034. Encuadre: Notas 16/18 | +| [0034](0034-etiquetado-tabla-tags-lateral.md) | Etiquetado en tabla LATERAL `paper_tags` (no toca `CORPUS_SCHEMA`, esquiva BUG-2); tags libres → taxonomía fase 2 (SKOS + OpenAlex topics, no BIBFRAME); fuera del `corpus_hash` | **Propuesta** (2026-06-18). Relacionada 0009/0023/0006/0033/0011/0031/0024/0017. **Deja abierta** la extensibilidad general del schema (BUG-2). Encuadre: Notas 16/17 | +| [0035](0035-ingesta-multipuerta-resolucion-doi.md) | Ingesta de doble puerta (online + archivo) misma cadena/corpus; resolución DOI→OpenAlex ID como servicio compartido (cierra GAP-1/GAP-2); import multi-formato (RIS/EndNote/CSV); BibTeX/archivo = primera clase | **Propuesta** (2026-06-18). **Revisa "BibTeX secundaria" de [0007](0007-openalex-backbone.md)** (en la ingesta). Relacionada 0018/0030/0032/0031. Encuadre: Nota 17 | | [0036](0036-identidad-source-id-agnostica-doi-ancla.md) | Identidad de fuente agnóstica: DOI como ancla universal, `source_id` genérico, motor de extracción intercambiable (tabla lateral `external_ids` 1↔N) | **Aceptada — AS-BUILT** (0.8, 2026-06-22): rename `openalex_id`→`source_id`, inversión de `_compute_id` (`doi > source_id > tt`), desacople del núcleo, infra `external_ids`, migración de `examples/valoraciones` (#118/#119). **Enmienda 0007/0013**; refuerza 0018; relacionada 0035/0034/0015. Población de `external_ids` y selector `--source` diferidos al 2º motor (#120) | | [0037](0037-superficie-cli-10-verbos-ciclo.md) | Superficie CLI de 0.10.0: **10 verbos agents-first** que mapean el ciclo (INIT→SEED→CHAIN→CURATE→BUILD→READ→EXPORT/SNAPSHOT, STATUS transversal); `status` como mapa (`next_best_action` + **preview por-red "qué se materializa" (e)** + **maturity-stamp del one-shot (f)**, campos aditivos); `curate`/`read` noun-verb; `monitor`→`chain --since`; aliases de retrocompat | **Aceptada** (2026-06-26). **Enmienda [0021](0021-cli-agente-native-contrato.md)** (consolida 12→10; envelope `schema="1"`/exit/FSM intactos). Relacionada 0010/0016/0029/0035/0036/0032/0033; no introduce IA (0022). Origen: Discussion [#127](https://github.com/complexluise/bib2graph/discussions/127); issues #76/#132 | | [0038](0038-destino-verbos-huerfanos-0037.md) | Destino de los 5 verbos huérfanos que el 0037 no nombró: `gui` se mantiene fuera de los 10 (0027/0028); `enrich`→absorbido en `chain`/`build`; `restore`→`snapshot restore`; `thesaurus`→retirado; `resolve`→retirado (ruta única `seed --resolve`). Fija: ventana de deprecación cierra en **0.11.0**; `build --scope=all` default; forma de `maturity` en `docs/API.md` | **Aceptada** (2026-06-27). **Enmienda [0037](0037-superficie-cli-10-verbos-ciclo.md)** (cierra el conteo "10 verbos"); revisa el `thesaurus` de [0031](0031-preprocesamiento-automatico-en-ingesta.md); renombre de [0030](0030-ecuacion-declarativa-corpus-ejemplo.md); refuerza 0035; envelope `schema="1"`/exit/FSM intactos. Contexto: issues #149/#34 | diff --git a/docs/decisiones/registro-ia.md b/docs/decisiones/registro-ia.md index b193223..93f1292 100644 --- a/docs/decisiones/registro-ia.md +++ b/docs/decisiones/registro-ia.md @@ -100,7 +100,7 @@ > tomado por el ADR de proyección de redes (Hito 2). Para no reescribir historia, los ADR nuevos > usan **`0015`–`0019`**. La separación `filter`/`curate` (punto 4 del acta) **no recibió ADR > propio**: es una decisión de superficie CLI/roadmap, no de arquitectura — se refleja en -> [`../ROADMAP.md`](../ROADMAP/README.md) (Hito 6) y [`../API.md`](../API.md) (§convenciones CLI). +> `../ROADMAP.md` (Hito 6) y [`../API.md`](../API.md) (§convenciones CLI). --- @@ -319,7 +319,7 @@ > **Reconciliación de docs (arquitecto, 2026-06-16):** ADR 0016 (nota "implementado en R3"), ADR 0021 > (envelope de `status` con `curation_available`/`round` aditivos, `schema="1"`), ROADMAP (Hito R3 ✅ + > banner as-built), ARCHITECTURE.md (§5.5 FSM → `cycle.py` AS-BUILT R3), API.md (§convenciones CLI + -> bloque `cycle.py`), CHANGELOG (R3 marcado). La [Nota 05](../Notas/05-ciclo-investigacion-humano.md) +> bloque `cycle.py`), CHANGELOG (R3 marcado). La Nota 05 > ya describía el ciclo correcto y **no requirió cambios** (R3 la **implementa**, no la corrige). --- @@ -330,7 +330,7 @@ > [0020](0020-metodo-forrajeo-scent-filtros-reject.md) (scent = proyectores), > [0022](0022-producto-sin-ia-generativa.md) (el producto no usa IA) y > [0008](0008-wedge-forrajeo.md) (tensiones retiradas). Cierra la RAÍZ 1 (parte de IA) de la -> [Nota 06](../Notas/06-critica-as-built-v0.2.md). **291 tests** verdes, mypy strict / ruff limpios; el +> Nota 06. **291 tests** verdes, mypy strict / ruff limpios; el > núcleo de scent depende del núcleo de proyección (puro), no al revés. **Verifier: APRUEBA CON > RESERVAS** (3 cuestiones de método); el **steering arquitectónico (2026-06-16)** las resolvió. @@ -357,7 +357,7 @@ > ADR 0022 (AS-BUILT: sin IA construido), ROADMAP (Hito R4 ✅ TERMINADO + DoD reconciliado), > ARCHITECTURE.md (§3.5 scent→proyectores AS-BUILT R4), API.md (§5 scent bibliométrico construido), > CHANGELOG (R4 marcado). README/AI_DISCLOSURE/AGENTS ya describían el retiro de `[llm]`/IA en pasado y -> **no requirieron limpieza adicional**. La [Nota 05](../Notas/05-ciclo-investigacion-humano.md) §4 ya +> **no requirieron limpieza adicional**. La Nota 05 §4 ya > prometía "la bibliometría ES el information scent" y **no requirió cambios** (R4 la **implementa**). --- @@ -366,7 +366,7 @@ > Último hito de la tanda de remediación. **No cambia el modelo conceptual; endurece lo construido.** > Cierra la RAÍZ 3 (no corre a escala + bug del contrato agente-native) y el catálogo de secundarios de -> la [Nota 06](../Notas/06-critica-as-built-v0.2.md). **319 tests** verdes +> la Nota 06. **319 tests** verdes > (`tests/unit/test_r5_robustness.py` + ajustes), mypy strict / ruff check+format limpios. > **Verifier: APRUEBA** (reservas cerradas). Con R5 la **tanda R1–R5 queda COMPLETA**. @@ -403,7 +403,7 @@ > completada), ROADMAP (Hito R5 ✅ + banner as-built + DoD reconciliado: batching diferido; tanda R1–R5 > COMPLETA), ARCHITECTURE.md (§3.1 bulk-load, §6.3 UTF-8/store-readonly, §8 footguns), API.md (PRISMA > lanza, store read-only, `.bib` lanza, `lib_version` "unknown", forward `DependencyError`+retry), -> CHANGELOG (R5 ✅ Fixed + Changed de comportamiento). La [Nota 06](../Notas/06-critica-as-built-v0.2.md) +> CHANGELOG (R5 ✅ Fixed + Changed de comportamiento). La Nota 06 > recibió una nota corta de cierre (rastro histórico, sin reescribir hallazgos). --- diff --git a/docs/guias/ecuacion-busqueda.md b/docs/guias/ecuacion-busqueda.md index e123f40..a03f101 100644 --- a/docs/guias/ecuacion-busqueda.md +++ b/docs/guias/ecuacion-busqueda.md @@ -16,6 +16,38 @@ Esta guía es una receta para llegar a una ecuación acotada, testeada, sin ruid --- +## Antes de empezar: afina tu pregunta + +Una ecuación acotada sale de una **pregunta acotada**. Si partes de un tema +genérico, la ecuación va a ser genérica también. + +❌ *"Inteligencia artificial"* — demasiado genérico. ¿Qué aspecto? ¿Qué dominio? + +✅ *"¿Cómo se aborda el problema de alineación de valores en modelos de +lenguaje grandes, y cuáles son las tensiones entre eficiencia computacional +y robustez ética entre 2020 y hoy?"* + +**Checklist de tu pregunta:** + +- [ ] **¿Específica?** ¿Puedes reducirla a 4–6 palabras clave? +- [ ] **¿Temporal?** ¿Hay un rango de años relevante? (5–10 años suele ser ideal). +- [ ] **¿Acotada?** ¿Esperas 50 papers, 500, 5000? +- [ ] **¿Contestable?** ¿Puedes responderla buscando en artículos científicos? + +### Ejemplo: de tema a pregunta + +**Tema inicial:** "Métodos de recuperación de información." + +**Pregunta después del refinamiento:** +> ¿Cuáles son los enfoques dominantes para recuperación de información en +> contextos multilingües, cuáles son sus tensiones (vocabulario vs. semántica, +> eficiencia vs. precisión), y cuáles son los huecos sin explorar entre 2015 +> y 2024? + +Eso es buscable, acotado, y con una tensión clara — ya listo para el Paso 1. + +--- + ## La estructura de una ecuación ``` diff --git a/docs/guias/index.md b/docs/guias/index.md index 4a5f79d..d03c83f 100644 --- a/docs/guias/index.md +++ b/docs/guias/index.md @@ -5,7 +5,8 @@ title: Guías (how-to) # Guías (how-to) Las **guías** son recetas para decisiones puntuales: ya sabes qué quieres hacer, -buscas cómo hacerlo bien. Si en cambio quieres *aprender* desde cero, comienza por los [Tutoriales](../tutoriales/index.md). +buscas cómo hacerlo bien. Si en cambio quieres *aprender* desde cero, comienza por +[Tu primer mapa de investigación](../tutoriales/primer-mapa.md) (5 min), en Inicio. Las guías están organizadas por **paso del flujo.** Úsalas como referencia mientras trabajas. @@ -68,7 +69,7 @@ trabajas. ## Complementario -- [Tutoriales](../tutoriales/index.md) — aprende desde cero (quick start o completo) +- [Tu primer mapa de investigación](../tutoriales/primer-mapa.md) — aprende desde cero, en 5 minutos - [Quickstart](../getting-started/quickstart.md) — ciclo mínimo en 2 minutos - [Referencia CLI](../reference/cli.md) — todos los comandos - [API Python](../reference/python-api.md) — como librería diff --git a/docs/guias/reporte.md b/docs/guias/reporte.md index 177cc48..606f8b9 100644 --- a/docs/guias/reporte.md +++ b/docs/guias/reporte.md @@ -189,6 +189,29 @@ Total: 12–20 páginas > **Emergentes:** Keyword "low-resource" crece 3x desde 2020. Autores nuevos en este sub-tema. > Nuevas partnerships: Google + universidades en Asia (multilingüe sobre lenguas de baja disponibilidad). +### Cómo pedírselo a tu asistente + +Si estás operando bib2graph vía un [asistente de IA](../reference/glosario.md#asistente-de-ia), +no necesitas calcular esto a mano. Pídeselo directamente: + +```text +Muestra: +- Gráfico de # papers/año en el corpus, y cómo cambiaron las comunidades + (% de papers) año a año. ¿Hay una comunidad que crecía y ahora decrece? + ¿Hay una emergente (crecimiento exponencial últimos 3 años)? + +Top 10 autores por: +- Cantidad de papers (productividad) +- Grado en la red de co-citación (influencia) +- Betweenness (actúan de "puente" entre comunidades) + +Mirando las 3 redes, identifica: +- Comunidades o autores que no se conectan entre sí (fronteras vacías) +- Combinaciones de keywords que NO aparecen (gaps) + +Co-autoría: top 10 instituciones por cantidad de papers y colaboraciones externas. +``` + --- ## 6. TENSIONES Y DEBATES @@ -321,6 +344,28 @@ No asumas jerga. Explica conceptos: --- +## Guarda y versiona tus artefactos + +**Si trabajaste con un asistente de IA:** su entorno de ejecución es efímero. +Antes de cerrar la conversación, descarga `corpus.parquet` (o el `.duckdb`), +los `.graphml` de cada red, el `clusters.csv` (papers → comunidad) y tu +reporte final. Guárdalos juntos en una carpeta: `sota-[tema]-[fecha]/`. + +**Si trabajaste con bib2graph localmente:** exporta y versiona con git: + +```bash +b2g export --format graphml +b2g export --format csv + +git add . +git commit -m "SOTA: [tu tema] — corpus, redes, reporte" +``` + +Esto es lo que hace tu SOTA **reproducible**: alguien (incluida tu versión +futura) puede volver a la misma ecuación y llegar a las mismas redes. + +--- + ## Siguiente Cuando termines el reporte: diff --git a/docs/index.md b/docs/index.md index e595f41..0bcfb19 100644 --- a/docs/index.md +++ b/docs/index.md @@ -22,38 +22,31 @@ mismo input, mismas redes. --- -## Elige tu camino +## Empieza: pídeselo a un asistente de IA -¿Cómo quieres usar bib2graph? Cada flujo es válido. +No hace falta instalar nada en tu máquina. Abre Claude, ChatGPT o MiniMax (con +ejecución de código activada) y pégale esto: -
- -- :material-robot: **Sin instalar nada (5 min)** - - Cuéntale a Claude, ChatGPT o MiniMax tu tema de investigación. - El agente trae papers, construye redes, tú descargas resultados. - - 👉 [Tutorial: Usuario no técnico](tutoriales/claude-code.md) - -- :material-code-braces: **Aprendiendo paso a paso (3–4 horas)** +!!! example + ```text + Instala la librería de Python "bib2graph" (pip install bib2graph) en tu + entorno de ejecución de código, entiende el CLI corriendo `b2g --help`, y + confírmame que tienes salida a internet hacia la API de OpenAlex. + ``` - Instala bib2graph. Sigue 10 pasos: desde pregunta hasta reporte. - Ejecutas cada comando, entiendes cómo funciona todo. - - 👉 [Tutorial completo: De la pregunta al reporte](tutoriales/sota-completo.md) +El [asistente de IA](reference/glosario.md#asistente-de-ia) instala bib2graph en +su propio entorno y te confirma si puede operarlo — tú no abres una terminal. +Este es el camino recomendado, programes o no: incluso si escribes código todos +los días, para una exploración puntual es más rápido que instalarlo tú mismo. -- :material-hammer-wrench: **Hibrido: CLI + agente (1–2 horas)** - - Instala bib2graph. El agente te ayuda con las partes difíciles. - Tú ejecutas comandos. Usa guías rápidas para decisiones. - - 👉 [Guías prácticas](guias/index.md) - -
+👉 [Tutorial completo: Tu primer mapa de investigación (5 min)](tutoriales/primer-mapa.md) --- -## Primeros pasos +## ¿Prefieres instalarlo tú? Más control + +Para scripting, integraciones, o si quieres correr bib2graph directamente en tu +propio código:
@@ -65,9 +58,9 @@ mismo input, mismas redes. El ciclo mínimo en 2 minutos — desde ecuación a GraphML. -- :material-api: **[Referencia](reference/cli.md)** +- :material-hammer-wrench: **[Guías (CLI + asistente)](guias/index.md)** - El CLI `b2g`, API de Python, y glosario de términos. + Instalas bib2graph y un asistente te ayuda con las partes difíciles.
diff --git a/docs/reference/glosario.md b/docs/reference/glosario.md index a196f03..91be5ad 100644 --- a/docs/reference/glosario.md +++ b/docs/reference/glosario.md @@ -20,6 +20,14 @@ Medida de similitud entre dos papers basada en las referencias que comparten. Do --- +### Asistente de IA + +Un chat de IA con ejecución de código (Claude, ChatGPT, MiniMax, o similar) al que le pides que instale y opere bib2graph por ti. No es parte del motor de bib2graph —que no usa IA generativa, ver [IA en el desarrollo](../ai-disclosure.md)— sino la interfaz conversacional que usa un humano no técnico para dirigir el CLI, sin escribir código ni abrir una terminal. + +**En bib2graph:** el asistente ejecuta los mismos comandos `b2g` que correrías a mano; la diferencia es que los corre dentro de su propio entorno de ejecución (no en tu máquina), a tu pedido. Ver [Tutorial: Tu primer mapa de investigación](../tutoriales/primer-mapa.md). + +--- + ## B ### Backward chaining diff --git a/docs/reference/python-api.md b/docs/reference/python-api.md index 3f05ae8..8d0410f 100644 --- a/docs/reference/python-api.md +++ b/docs/reference/python-api.md @@ -8,7 +8,7 @@ Referencia de la **superficie pública de la librería** `bib2graph`, agrupada p tema. Se **autogenera desde los docstrings** del código (mkdocstrings): si cambia el código, cambia esta página. -Para usar la herramienta desde la terminal, mirá la [referencia del CLI `b2g`](cli.md). +Para usar la herramienta desde la terminal, mira la [referencia del CLI `b2g`](cli.md). ## Corpus y persistencia diff --git a/docs/tutoriales/claude-code.md b/docs/tutoriales/claude-code.md deleted file mode 100644 index 660b8ba..0000000 --- a/docs/tutoriales/claude-code.md +++ /dev/null @@ -1,143 +0,0 @@ ---- -title: Tu primer mapa de investigación (5 min) ---- - -# Tu primer mapa de investigación (5 minutos) - -Cómo armar una **red visual de artículos científicos** sobre un tema que te -interesa, usando un agente de IA para dirigir bib2graph. - -!!! info "Qué necesitas" - - **Un agente de IA** con ejecución de código: Claude, ChatGPT, MiniMax, o similar. - - **bib2graph instalado** en tu máquina (1 minuto: `pip install bib2graph`). - - **5 minutos**. - -!!! warning "Paso previo: instala bib2graph" - Abre tu terminal y ejecuta: - ```bash - pip install bib2graph - ``` - - Verifica que funciona: - ```bash - b2g --help - ``` - - Si ves la ayuda de comandos, listo. Si no, ve a [Instalación](../getting-started/installation.md). - ---- - -## Paso 1 — Elige un agente - -Abre **cualquiera** de estos (con ejecución de código activada): - -- **Claude** (web o app) -- **ChatGPT** (Plus, con Code Interpreter) -- **MiniMax** o similar - -Lo importante: que pueda ejecutar Python y crear archivos. Nosotros no hacemos vendor locking -a un solo agente — bib2graph funciona igual en todos. - ---- - -## Paso 2 — Plantea el tema al agente - -En una conversación nueva, escribe algo así: - -!!! example - ```text - Tengo bib2graph instalado en mi máquina. - - Quiero explorar el estado del arte sobre [TU TEMA]. - - Usa bib2graph para: - 1. Buscar papers en OpenAlex - 2. Construir una red de referencias compartidas - 3. Mostrar qué comunidades de investigación existen - - Mi tema: [ejemplo: métodos de recuperación de información en contextos multilingües] - ``` - -El agente va a sugerirte una **ecuación de búsqueda** — una forma de decirle a OpenAlex -exactamente qué buscar. La revisas, ajustas si hace falta. - ---- - -## Paso 3 — El agente construye la red - -Cuando la ecuación te cierre, pide al agente: - -!!! example - ```text - Bien. Ahora ejecuta estos comandos en mi máquina: - - 1. b2g init mi-sota - 2. cd mi-sota - 3. b2g seed "[TU ECUACION]" --min-year 2015 - 4. b2g build - 5. b2g export --format graphml - - Muestra la red visualizada y un resumen de las comunidades. - ``` - -El agente ejecuta esos comandos por ti — trae papers, identifica qué papers citan -las mismas referencias, agrupa esos papers en comunidades. - -**Resultado:** Una imagen de la red (puntos = papers, líneas = referencias compartidas, -colores = comunidades). - ---- - -## Paso 4 — Lee el mapa - -Pide al agente: - -!!! example - ```text - Para cada comunidad en la red: - - Nombre (síntesis del enfoque) - - Keywords principales - - Top 3 papers más centrales (autor, año) - - Muestra una tabla. - ``` - -Ya tienes un **primer mapa mental del campo** — qué tendencias existen, quiénes -son los referentes, dónde están las divergencias. - ---- - -## Paso 5 — Guarda tu trabajo - -Tu corpus está en el archivo `.duckdb` dentro de la carpeta `mi-sota/`. Los archivos -`.graphml` están en `exports/`. - -Para continuar después: - -```bash -cd mi-sota -b2g read list # Ver papers en el corpus -b2g read top # Ver papers más centrales -``` - -Si quieres explorar más tarde desde el agente, carga los archivos GraphML o Parquet en -la conversación y sigue desde ahí. - ---- - -## Listo - -En 5 minutos: - -✅ Instalaste bib2graph -✅ Trajiste papers de un tema (con ayuda del agente) -✅ Viste cómo se relacionan (qué citan en común) -✅ Identificaste sub-temas / enfoques -✅ El corpus está guardado en tu máquina - -## Qué sigue - -- **Más detalles:** [Tutorial completo — De la pregunta al reporte de SOTA](sota-completo.md) - — cómo refinar, curar y redactar un análisis riguroso. -- **Referencia completa:** [Todos los comandos de bib2graph](../reference/cli.md). -- **Como librería Python:** [API Python](../reference/python-api.md). diff --git a/docs/tutoriales/index.md b/docs/tutoriales/index.md deleted file mode 100644 index 0862b71..0000000 --- a/docs/tutoriales/index.md +++ /dev/null @@ -1,30 +0,0 @@ ---- -title: Tutoriales ---- - -# Tutoriales - -Los **tutoriales** enseñan a usar bib2graph paso a paso, partiendo de cero y -llegando a un resultado concreto. Son para *aprender*. - -## Para empezar (5 minutos) - -- :material-robot: **[Tu primer mapa en Claude (5 min)](claude-code.md)** - - Cómo armar, sin instalar nada, una red visual de papers sobre un tema. - Conversación con Claude — todo automatizado. Ideal para explorar rápido. - -## Tutorial completo (3–4 horas) - -- :material-book: **[De la pregunta al reporte de SOTA](sota-completo.md)** - - Recorrido completo paso a paso: pregunta → ecuación → corpus → curación PRISMA - → 3 redes → análisis de comunidades → tendencias → redacción del reporte. - Para alguien que quiere hacer un SOTA riguroso. - -## También útil - -- [Quickstart](../getting-started/quickstart.md) — el ciclo mínimo con CLI `b2g` en tu máquina (2 min). -- [Guías (how-to)](../guias/index.md) — recetas para tareas concretas. -- [Referencia del CLI `b2g`](../reference/cli.md) — todos los comandos. -- [API Python](../reference/python-api.md) — bib2graph como librería. diff --git a/docs/tutoriales/primer-mapa.md b/docs/tutoriales/primer-mapa.md new file mode 100644 index 0000000..e334053 --- /dev/null +++ b/docs/tutoriales/primer-mapa.md @@ -0,0 +1,151 @@ +--- +title: Tu primer mapa de investigación (5 min) +--- + +# Tu primer mapa de investigación (5 minutos) + +Cómo armar una **red visual de artículos científicos** sobre un tema que te +interesa, usando un [asistente de IA](../reference/glosario.md#asistente-de-ia) para dirigir bib2graph. + +!!! info "Qué necesitas" + - **Un asistente de IA con ejecución de código**: Claude, ChatGPT, MiniMax, o similar + (el chat, no una terminal tuya). + - **Nada instalado en tu máquina.** El asistente instala bib2graph en su propio + entorno de ejecución — tú no abres una terminal. + - **5 minutos.** + +--- + +## Paso 1 — El asistente instala bib2graph y se autodiagnostica + +Abre **cualquiera** de estos (con ejecución de código activada): Claude (web o app), +ChatGPT (con Code Interpreter), MiniMax, o similar. Lo importante es que pueda +ejecutar Python y crear archivos — no hacemos vendor locking a un solo asistente. + +En una conversación nueva, pégale este mensaje: + +!!! example + ```text + Instala la librería de Python "bib2graph" (pip install bib2graph) en tu + entorno de ejecución de código, entiende el CLI corriendo `b2g --help`, y + confírmame que tienes salida a internet hacia la API de OpenAlex con una + búsqueda mínima de prueba. Cuéntame si las dos cosas funcionaron. + ``` + +Este mensaje hace dos cosas a la vez: instala la herramienta **dentro del entorno +del asistente** (no en tu compu) y te dice, en el momento, si ese asistente sirve para +este camino — sin que tengas que leer una tabla de compatibilidad que se desactualiza. + +**Si el asistente confirma las dos cosas:** sigue al Paso 2, en la misma conversación. + +**Si algo falla** (no puede instalar, o instala pero no llega a OpenAlex): ese +asistente no sirve para este camino hoy. Prueba con otro — a esta fecha, Claude.ai y +MiniMax (planes pagos) lo resuelven bien; el entorno de ejecución de código de +ChatGPT no tiene salida a internet. Esto puede cambiar con el tiempo; por eso el +diagnóstico de arriba es la forma de saberlo, no esta lista. + +--- + +## Paso 2 — Plantea tu tema + +Ya en la misma conversación (bib2graph ya está instalado), cuéntale tu tema: + +!!! example + ```text + Quiero explorar el estado del arte sobre [TU TEMA]. + + Usa bib2graph para: + 1. Buscar papers en OpenAlex + 2. Construir una red de referencias compartidas + 3. Mostrar qué comunidades de investigación existen + + Mi tema: [ejemplo: métodos de recuperación de información en contextos multilingües] + ``` + +El asistente va a sugerirte una **ecuación de búsqueda** — una forma de decirle a OpenAlex +exactamente qué buscar. La revisas, ajustas si hace falta. + +--- + +## Paso 3 — El asistente construye la red + +Cuando la ecuación te cierre, pide al asistente: + +!!! example + ```text + Bien. Ahora ejecuta estos comandos: + + 1. b2g init mi-sota + 2. cd mi-sota + 3. b2g seed "[TU ECUACION]" --min-year 2015 + 4. b2g build + 5. b2g export --format graphml + + Muestra la red visualizada y un resumen de las comunidades. + ``` + +El asistente ejecuta esos comandos por ti — trae papers, identifica qué papers citan +las mismas referencias, agrupa esos papers en comunidades. + +**Resultado:** Una imagen de la red (puntos = papers, líneas = referencias compartidas, +colores = comunidades). + +--- + +## Paso 4 — Lee el mapa + +Pide al asistente: + +!!! example + ```text + Para cada comunidad en la red: + - Nombre (síntesis del enfoque) + - Keywords principales + - Top 3 papers más centrales (autor, año) + + Muestra una tabla. + ``` + +Ya tienes un **primer mapa mental del campo** — qué tendencias existen, quiénes +son los referentes, dónde están las divergencias. + +--- + +## Paso 5 — Descarga tu trabajo antes de cerrar + +El corpus vive en el **entorno del asistente**, no en tu compu — y ese entorno se puede +apagar si cierras la conversación o la dejas inactiva mucho tiempo. Antes de irte, +pídele al asistente: + +!!! example + ```text + Dame para descargar el archivo .duckdb del workspace y los .graphml de exports/. + ``` + +Guarda esos archivos en tu compu. Para continuar después: + +- Empieza una conversación nueva, repite el Paso 1, y súbele el `.duckdb` que + descargaste para que el asistente siga desde donde quedaste (`b2g read list`, + `b2g read top` sobre ese mismo workspace). +- O carga directamente los `.graphml` en una conversación nueva y explora la red + desde ahí, sin reabrir bib2graph. + +--- + +## Listo + +En 5 minutos: + +✅ Tu asistente instaló bib2graph — tú no tocaste una terminal +✅ Trajiste papers de un tema (con ayuda del asistente) +✅ Viste cómo se relacionan (qué citan en común) +✅ Identificaste sub-temas / enfoques +✅ Descargaste el corpus a tu máquina + +## Qué sigue + +- **Profundiza paso a paso:** las [Guías (how-to)](../guias/index.md) — + ecuación de búsqueda, forrajeo, curación PRISMA, lectura de redes y + redacción del reporte. +- **Referencia completa:** [Todos los comandos de bib2graph](../reference/cli.md). +- **Como librería Python:** [API Python](../reference/python-api.md). diff --git a/docs/tutoriales/sota-completo.md b/docs/tutoriales/sota-completo.md deleted file mode 100644 index 66b5679..0000000 --- a/docs/tutoriales/sota-completo.md +++ /dev/null @@ -1,562 +0,0 @@ ---- -title: Tutorial completo — De la pregunta al reporte de SOTA ---- - -# Tutorial completo — De la pregunta al reporte de SOTA - -Un recorrido paso a paso por un **estado del arte riguroso**: desde formular -la pregunta de investigación hasta redactar un análisis con tensiones, -escuelas de pensamiento y huecos sin explorar. - -Este es el tutorial detallado (45 min de lectura + 2–3 horas de investigación). -Si acaba de descubrir bib2graph, empiece por el [tutorial corto](claude-code.md). - -!!! info "Requisitos" - - Una pregunta de investigación clara (no un tema genérico). - - **bib2graph instalado** en tu máquina: `pip install bib2graph` - - Un agente de IA (Claude, ChatGPT, MiniMax, etc.) con ejecución de código, o disposición a usar el CLI directamente. - - Tiempo: 3–4 horas para el ciclo completo. - - Opcional: API key de OpenAlex (gratuita, para corpus > 100 papers). - ---- - -## Anatomía de un estado del arte - -Un SOTA riguroso no es una lista de papers. Es un **mapa de cómo piensa un campo**: - -``` -pregunta ──► ecuación ──► corpus ──► curación ──► redes ──► comunidades - │ - ◄──────────────────────── lectura - (qué vemos en el mapa) - │ - tendencias, tensiones, huecos - │ - reporte -``` - -Vamos paso a paso. - ---- - -## Paso 0 — Instala bib2graph - -**Entrada:** Tu máquina con Python 3.10+. -**Salida:** bib2graph funcionando y listo para usar. - -Abre tu terminal y ejecuta: - -```bash -pip install bib2graph -``` - -Verifica que funciona: - -```bash -b2g --help -``` - -Deberías ver la lista de comandos de bib2graph. Si no, consulta [Instalación](../getting-started/installation.md). - -### Entiende el flujo de comandos básicos - -bib2graph usa un flujo de **comandos secuenciales**: - -```bash -b2g init ./mi-sota # Crea una carpeta de proyecto -cd mi-sota - -b2g seed "tu_ecuacion" # Trae papers desde OpenAlex -b2g chain # (Opcional) Expande por citaciones -b2g curate # Acepta/rechaza papers (curación) -b2g build # Construye redes -b2g read list # Visualiza papers -b2g export --format graphml # Exporta redes -``` - -Cada comando transiciona el estado del corpus. Vamos a ver esto en detalle. - ---- - -## Paso 1 — Afina tu pregunta de investigación - -**Entrada:** Un tema que te interesa. -**Salida:** Una pregunta clara, acotada, formulable. - -### Cómo llegar de un tema a una pregunta - -❌ *"Inteligencia artificial"* → Demasiado genérico. ¿Qué aspecto? ¿Qué dominio? - -✅ *"¿Cómo se aborda el problema de alineación de valores en modelos de -lenguaje grandes, y cuáles son las tensiones entre eficiencia computacional -y robustez ética entre 2020 y hoy?"* - -### Checklist para tu pregunta - -1. **¿Específica?** ¿Puedo reducirla a 4–6 palabras clave? -2. **¿Temporal?** ¿Hay un rango de años relevante? (5–10 años suele ser ideal). -3. **¿Acotada?** ¿Espero 50 papers, 500, 5000? -4. **¿Contestable?** ¿Puedo responderla buscando en artículos científicos? - -### Ejemplo: Desarrolla la pregunta - -**Mi tema inicial:** "Métodos de recuperación de información." - -**Mi pregunta después del refinamiento:** -> ¿Cuáles son los enfoques dominantes para recuperación de información en -> contextos multilingües, cuáles son sus tensiones (vocabulario vs. semántica, -> eficiencia vs. precisión), y cuáles son los huecos sin explorar entre 2015 -> y 2024? - -Eso es buscable, acotado, y con una tensión clara. - ---- - -## Paso 2 — Elaborá una ecuación de búsqueda - -**Entrada:** Tu pregunta de investigación. -**Salida:** Una ecuación booleana que traduzca esa pregunta. - -### La estructura - -``` -(concepto_A_términos) -AND (concepto_B_términos) -AND (concepto_C_términos) -[AND NOT (exclusiones)] -``` - -Cada paréntesis es un concepto; dentro, los términos están unidos por `OR` -(sinónimos). Los `AND` conectan conceptos (todos deben estar presentes). - -### Para mi ejemplo - -``` -(information retrieval OR IR OR search) -AND (multilingual OR cross-lingual OR language-agnostic OR polyglot) -AND (method OR approach OR framework OR system OR architecture) -``` - -### Consejos prácticos - -- **Un concepto = una dimensión de tu pregunta.** Aquí: - - Concepto A: la tarea (recuperación). - - Concepto B: la restricción (multilingüe). - - Concepto C: el tipo de resultado (métodos, no papers de aplicación). - -- **Evita genéricos.** "machine learning" sola atrapa cientos de miles de papers. - -- **Testea:** Pídele a Claude que busque 50 papers con tu ecuación y revisa los - títulos. ¿Ves ruido sistemático? Ajusta. - -- **Excluye si hace falta:** `AND NOT (machine translation)` si hay mucho ruido - ahí. - ---- - -## Paso 3 — Siembra el corpus - -**Entrada:** Ecuación de búsqueda, rango de años. -**Salida:** Corpus inicial (~200–300 papers). - -### Opción 1: Con CLI directo - -```bash -cd mi-sota -b2g seed "(information retrieval OR IR) AND (multilingual OR cross-lingual) AND (method OR approach)" --min-year 2015 --max-results 250 -``` - -bib2graph descarga papers desde OpenAlex y los guarda en `.duckdb` dentro de la carpeta. - -### Opción 2: Con ayuda de un agente - -Puedes pedirle al agente (Claude, ChatGPT, etc.) que: - -1. Genere la ecuación de búsqueda a partir de tu pregunta. -2. Execute el comando `b2g seed` en tu máquina. -3. Verifique los resultados. - -**Prompt:** - -```text -Tengo mi pregunta de investigación: -[TU PREGUNTA] - -Propón una ecuación de búsqueda para bib2graph. -Luego dame el comando exacto para ejecutar: -b2g seed "[ecuacion]" --min-year 2015 --max-results 250 - -Muestra qué debería ver después de ejecutarlo. -``` - -El agente genera la ecuación y tú ejecutas el comando en tu terminal. Luego: - -```bash -b2g read stats --group-by year -``` - -Para ver la distribución temporal. - -### Verificación - -Revisa el corpus: - -```bash -b2g read list --query "tus_palabras_clave" | head -20 -``` - -¿Todos tienen relación directa con tu tema? Si hay ruido sistemático, ajusta la -ecuación y vuelve a ejecutar `b2g seed` en una carpeta nueva. - -### Punto de decisión - -- **Corpus muy pequeño (<50 papers)?** Abre la ecuación (menos `AND`, más sinónimos). -- **Corpus muy grande (>1000)?** Ciérrala (más `AND`, menos sinónimos, o agrega - un concepto específico más). -- **Corpus bien (~200–400)?** Perfecto, seguimos. - ---- - -## Paso 4 — Expande por citaciones (opcional) - -**Entrada:** Corpus de siembra. -**Salida:** Corpus expandido (~20–50% más) con más densidad de referencias. - -El **forrajeo** (backward chaining) busca papers que no aparecieron en tu -búsqueda original, pero que son citados por los que sí están. Aumenta la -*sensibilidad* (no pierdes papers clave) sin agregar mucho ruido. - -### Cuándo hacer esto - -✅ **Hazlo si:** el tema es muy específico, querés máxima cobertura, o el corpus -inicial es pequeño. - -❌ **No lo hagas si:** el corpus ya es grande (>500), no querés aumentarlo, o es -tu primer SOTA (primero lee la red de siembra, después decide). - -### Con Claude - -```text -Expandí el corpus usando forrajeo (backward chaining): -seguí una capa de referencias de los papers ya en el corpus -y agregá hasta 100 papers nuevos. - -Muestra: -- Cuántos papers nuevos se agregaron -- Si hay papers muy antiguos (pre-2000): ¿los mantengo o descarto? -``` - ---- - -## Paso 5 — Curá el corpus (PRISMA) - -**Entrada:** Corpus (siembra o expandido). -**Salida:** Corpus curado, con decisiones criteriales explícitas y versionables. - -La curación es **manual**. No se automatiza porque cada decisión es criterial. - -### Flujo PRISMA simplificado - -``` -IDENTIFICACIÓN -├─ ¿Duplicado o retractado? → RECHAZAR -└─ ¿En el idioma adecuado? → si no, RECHAZAR - -CRIBADO (título + resumen) -├─ ¿Título claramente fuera de scope? → RECHAZAR -└─ ¿Resumen no aporta al tema? → RECHAZAR - -ELEGIBILIDAD (lectura de disponibilidad) -├─ ¿Texto completo inaccesible? → CANDIDATO (maybe later) -└─ ¿Métodos/resultados vagos o especulativos? → CANDIDATO - -INCLUSIÓN (decisión final) -├─ ¿Relevancia alta? → ACEPTAR -└─ ¿Relevancia media pero aporta tensión? → ACEPTAR -``` - -### Con Claude - -Pídele a Claude: - -```text -Hacé curación PRISMA del corpus. Revisá cada paper: -1. Si es duplicado o retractado: RECHAZAR -2. Si el título no tiene relación directa: RECHAZAR -3. Si el resumen sugiere que no toca el tema: RECHAZAR -4. Si no hay texto completo: CANDIDATO (no rechaces) -5. En otro caso: ACEPTAR - -Mostrá un resumen: cuántos ACCEPTED, REJECTED, CANDIDATE. -Lista 5 ejemplos de RECHAZADOS con razón. -``` - -### Checklist - -- [ ] ¿Documenté mis criterios explícitamente? -- [ ] ¿El corpus ACCEPTED quedó entre 100–300 papers? -- [ ] ¿Revisaste una muestra de rechazados para asegurarme de que no falta algo obvio? -- [ ] ¿Hay equilibrio entre años (no es monocromático)? - ---- - -## Paso 6 — Construí las redes - -**Entrada:** Corpus curado (papers ACCEPTED). -**Salida:** 3 redes + métricas. - -Las tres redes que importan: - -1. **Acoplamiento bibliográfico:** Papers que citan las mismas referencias. - (Responde: ¿cuáles son los sub-temas?) -2. **Co-citación:** Papers que se citan mutuamente o son citados juntos. - (Responde: ¿cuáles son los influentes?) -3. **Co-autoría:** Quién escribe con quién. - (Responde: ¿cuáles son los colegios invisibles?) - -### Con Claude - -```text -Construí 3 redes del corpus ACCEPTED usando bib2graph: -1. Acoplamiento bibliográfico -2. Co-citación -3. Co-autoría - -Para cada red: -- Detectá comunidades usando Louvain (clustering) -- Muestra una visualización coloreada por comunidad -- Reportá: # nodos, # aristas, # comunidades -- Lista los 3 papers más centrales (mayor grado) de cada comunidad -``` - -### Qué esperar - -- **Acoplamiento:** es la "red primaria" — más densa, más comunidades. Aquí ves - los sub-temas claros. -- **Co-citación:** a menudo es más dispersa; destaca papers que actúan como - referencias canónicas (los "clásicos" del campo). -- **Co-autoría:** también dispersa, pero útil para ver equipos y colaboraciones - persistentes. - ---- - -## Paso 7 — Nombrá y caracterizá las comunidades - -**Entrada:** Redes + corpus curado. -**Salida:** Una tabla con comunidades, keywords, seminales, y tensiones. - -Para cada comunidad en la red de acoplamiento (la principal): - -1. **Nombre:** 1–3 palabras que capturen el enfoque (ej. "Métodos probabilísticos"). -2. **Keywords:** 5–7 palabras clave dominantes en esa comunidad. -3. **Seminales:** Top 2–3 papers (mayor grado) dentro de la comunidad. -4. **Descripción:** 2–3 frases de qué hacen esos papers. -5. **Tensión:** ¿Qué los diferencia de otras comunidades? ¿Dónde discrepan? - -### Con Claude - -```text -Para la red de acoplamiento, analizá cada comunidad: - -1. Nombre (síntesis del enfoque en 1–3 palabras) -2. Keywords principales (5–7 terms que definen esa comunidad) -3. Seminales: top 2 papers (por grado), con título, autores, año -4. Descripción: ¿qué hacen esos papers? ¿Cuál es el enfoque común? -5. Tensión: ¿en qué difieren de otras comunidades? - -Armame una tabla: [Comunidad | Enfoque | Keywords | Seminales | Tensión] -``` - -### Ejemplo de salida - -| Comunidad | Enfoque | Keywords | Seminales | Tensión | -|-----------|---------|----------|-----------|---------| -| **Probabilístico** | Modelos estadísticos, HMM | language model, smoothing, EM | [Smith 2008], [Brown 2010] | Eficiencia vs. cobertura | -| **Vectorial** | Embeddings, semántica latente | word embeddings, LSA, similarity | [Mikolov 2013], [Pennington 2014] | Interpretabilidad vs. performance | -| **Neuronal** | Deep learning, transformers | neural networks, attention, BERT | [Vaswani 2017], [Devlin 2019] | Costo computacional vs. generalización | - ---- - -## Paso 8 — Analiza tendencias e influencias - -**Entrada:** Redes, comunidades, corpus. -**Salida:** Observaciones sobre evolución, actores clave, huecos. - -Responde estas preguntas: - -### 1. ¿Cómo evolucionó el campo? - -```text -Muestra: -- Gráfico de # papers/año en el corpus -- Cómo cambiaron las comunidades (% de papers) año a año -- ¿Hay una comunidad que crecía y ahora decrece? -- ¿Hay una emergente (crecimiento exponencial últimos 3 años)? -``` - -### 2. ¿Quiénes son los influyentes? - -```text -Top 10 autores por: -- Cantidad de papers (productividad) -- Grado en la red de co-citación (influencia) -- Betweenness (actúan de "puente" entre comunidades) -``` - -### 3. ¿Dónde están los huecos? - -```text -Mirando las 3 redes, identificá: -- Comunidades o autores que no se conectan entre sí (fronteras vacías) -- Combinaciones de keywords que NO aparecen (gaps) -- Preguntas que nadie se hace (inferir de lo que sí hay) -``` - -### 4. ¿Quién lidera por institución? - -```text -Co-autoría: top 10 instituciones por: -- Cantidad de papers -- Colaboraciones externas -``` - ---- - -## Paso 9 — Redactá el reporte - -**Entrada:** Análisis anterior, comunidades, tendencias. -**Salida:** Documento estructurado (Markdown, Word, Google Docs). - -### Estructura recomendada - -``` -RESUMEN EJECUTIVO -├─ Pregunta de investigación -├─ Hallazgos principales (2–3 frases) -└─ Síntesis de una línea - -INTRODUCCIÓN -├─ Contexto y motivación -├─ Pregunta de investigación -└─ Scope - -METODOLOGÍA -├─ Ecuación de búsqueda -├─ Criterios PRISMA (en una frase) -├─ Tamaño final: X papers, años A–B -└─ Redes construidas (acoplamiento, co-citación, co-autoría) - -MAPEO DEL CAMPO -├─ Tabla de comunidades (visto en Paso 7) -├─ Figura: red de acoplamiento coloreada -├─ Trabajos seminales por comunidad -└─ Descripción de cada enfoque (prosa) - -TENDENCIAS Y EVOLUCIÓN -├─ Trayectoria temporal -├─ Shift de enfoques (cuál sube, cuál baja) -├─ Emergentes (keywords nuevas, comunidades nuevas) -└─ Actores clave (top autores, instituciones) - -TENSIONES Y DEBATES -├─ Matriz: Enfoque A vs. Enfoque B, qué diferencia -├─ Dónde se superponen, dónde divergen -├─ Huecos de investigación -└─ Preguntas abiertas - -CONCLUSIONES -├─ Síntesis de hallazgos -├─ Implicaciones para investigación futura -└─ Recomendaciones - -APÉNDICES -├─ Tabla: todos los papers (corpus completo) -├─ CSV de papers → comunidad -└─ GraphML (red para abrir en Gephi/Cytoscape) -``` - -### Herramientas de escritura - -- **Google Docs:** Colaboración y comentarios; exportás a .docx después. -- **Markdown + Pandoc:** Máximo control; exportás a PDF/DOCX/HTML. -- **Obsidian:** Integración con Zotero; bueno para notas de investigación. -- **Quarto/Jupyter:** Si querés reproducibilidad y código integrado. - -### Tips de redacción - -- **Cada comunidad merece un párrafo.** No amontonés. -- **Las figuras llevan leyendas explicativas.** "Red de acoplamiento bibliográfico - con N nodos (papers), M aristas (referencias compartidas), K comunidades - (detectadas por Louvain, resolution=1.0). Cada color = una comunidad. - Los nodos más grandes = papers de mayor grado (más referencias compartidas)." -- **Tensiones no son "problemas abiertos".** Son donde dos enfoques dicen cosas - diferentes. Ej. "La escuela probabilística prioriza eficiencia computacional, - mientras que la neuronal prioriza generación de resultados. En corpus multilingües, - esto afecta cómo se mapean traducciones." - ---- - -## Paso 10 — Versiona tu trabajo - -**Entrada:** Reporte, corpus, redes. -**Salida:** Carpeta reproducible. - -### Si usaste Claude web - -Descarga: - -- `corpus.parquet` — tu semilla guardada (subirla a Claude luego para continuar). -- `*.graphml` — networks para Gephi/Cytoscape. -- `clusters.csv` — papers → comunidad. -- `reporte.docx` o `reporte.md` — tu análisis final. - -Guardalos en una carpeta: `sota-[tema]-[fecha]/` - -### Si usaste bib2graph localmente - -El corpus vive en `.duckdb`; las redes se exportan automáticamente: - -```bash -# Exportá todo -b2g export --format graphml -b2g export --format csv - -# Versioná -git add . -git commit -m "SOTA: [Tu Tema] — corpus, redes, reporte" -``` - ---- - -## Checklist final - -- [ ] Pregunta de investigación clara y formulada -- [ ] Ecuación de búsqueda documentada y testeada -- [ ] Corpus de 100–300 papers ACCEPTED (curados por PRISMA) -- [ ] 3 redes construidas y visualizadas -- [ ] Comunidades nombradas, con keywords, seminales y tensiones identificadas -- [ ] Tendencias temporales e influencias (autores, instituciones) documentadas -- [ ] Huecos y fronteras vacías identificados -- [ ] Reporte redactado con estructura clara y figuras con leyendas -- [ ] Artefactos (GraphML, CSV, corpus) guardados y versionados -- [ ] ¿Se puede reproducir desde la ecuación de búsqueda? ✓ - ---- - -## Siguientes pasos - -- **Análisis más profundo:** Elige una comunidad y haz un sub-SOTA acotado. -- **Integración con tu investigación:** Posicioná tu trabajo en el mapa — ¿dónde - caés? ¿Dónde resolvés una tensión? -- **Publicación:** Convertí el SOTA en un paper, capítulo de tesis, o entrada de - blog. - ---- - -## Referencias - -- [Guías (how-to)](../guias/index.md) — recetas acotadas que complementan cada - paso: ecuación, forrajeo, curación PRISMA, lectura de redes y redacción del reporte. -- [Arquitectura de bib2graph](../ARCHITECTURE.md) -- [Referencia del CLI `b2g`](../reference/cli.md) -- [API Python](../reference/python-api.md) diff --git a/mkdocs.yml b/mkdocs.yml index 8283735..4b108ed 100644 --- a/mkdocs.yml +++ b/mkdocs.yml @@ -112,7 +112,9 @@ markdown_extensions: - mkdocs-click # Páginas que se construyen y son enlazables por URL, pero NO aparecen en el -# sidebar (los 38 ADRs viven en su índice docs/decisiones/README.md). +# sidebar. Las 38 ADRs viven en su índice docs/decisiones/README.md (visible +# por URL — ejercicio de transferencia — pero no en el nav principal, para no +# abrumar al usuario final ni al asistente de IA). not_in_nav: | /decisiones/0*.md /decisiones/registro-ia.md @@ -126,17 +128,17 @@ exclude_docs: | ROADMAP/ RELEASE_TEMPLATE.md -# Estructura Diátaxis (https://diataxis.fr): Empezar/Tutoriales (aprender), -# Guías (resolver una tarea), Referencia (consultar), Explicación (entender). +# Estructura Diátaxis (https://diataxis.fr): Inicio (aprender/empezar, camino +# recomendado = asistente de IA — incluye el único tutorial), Guías (resolver +# una tarea), Referencia (consultar). La Explicación (entender: arquitectura, +# ADRs, PRD) vive dentro de "Contribuye" — es contexto para quien va a tocar +# el código, no una sección aparte. nav: - - Inicio: index.md - - Empezar: + - Inicio: + - index.md - Instalación: getting-started/installation.md - Quickstart: getting-started/quickstart.md - - Tutoriales: - - tutoriales/index.md - - Tu primer mapa (5 min): tutoriales/claude-code.md - - De la pregunta al reporte de SOTA: tutoriales/sota-completo.md + - Tu primer mapa (5 min): tutoriales/primer-mapa.md - Guías (how-to): - guias/index.md - Ecuación de búsqueda: guias/ecuacion-busqueda.md @@ -148,13 +150,10 @@ nav: - API de Python: reference/python-api.md - CLI b2g: reference/cli.md - Glosario: reference/glosario.md - - Contratos detallados: API.md - - Explicación: + - Contribuye: + - Contribuir: contributing.md - Arquitectura: ARCHITECTURE.md - - Decisiones de diseño (ADRs): decisiones/README.md - Requisitos del producto (PRD): PRD.md - - Proyecto: - - Contribuir: contributing.md - Versionado: versioning.md - IA en el desarrollo: ai-disclosure.md - Changelog: changelog.md