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: -