From ebe10694ee1b6f15a935533082a69c876dc00424 Mon Sep 17 00:00:00 2001 From: complexluise Date: Tue, 30 Jun 2026 18:17:40 -0500 Subject: [PATCH] docs(notas): publicar notas 20, 23-28 (renumera recibo a 27, marco a 28) Sube siete notas de trabajo que estaban sin commitear. Las locales que chocaban en numero con notas existentes se renumeran: - 21-recibo-de-demo-functor-honesto pasa a 27 - 22-marco-software-donde-nos-paramos pasa a 28 Cross-references actualizadas (12 en 3 notas), por nombre de archivo y por numero en prosa. Notas 20, 23, 24, 25, 26 conservan su numero. Co-Authored-By: Claude Opus 4.8 (1M context) --- ..._ciclo_investigacion_hallazgos_teoricos.md | 818 ++++++++++++++++++ .../23-RETROALIMENTACION_bib2graph_agente.md | 168 ++++ .../24-referente-snowballing-comparacion.md | 78 ++ .../Notas/25-multiproveedor-requerimientos.md | 231 +++++ .../26-retroalimentacion-cli-agent-native.md | 262 ++++++ .../27-recibo-de-demo-functor-honesto.md | 200 +++++ .../28-marco-software-donde-nos-paramos.md | 359 ++++++++ 7 files changed, 2116 insertions(+) create mode 100644 docs/Notas/20_ciclo_investigacion_hallazgos_teoricos.md create mode 100644 docs/Notas/23-RETROALIMENTACION_bib2graph_agente.md create mode 100644 docs/Notas/24-referente-snowballing-comparacion.md create mode 100644 docs/Notas/25-multiproveedor-requerimientos.md create mode 100644 docs/Notas/26-retroalimentacion-cli-agent-native.md create mode 100644 docs/Notas/27-recibo-de-demo-functor-honesto.md create mode 100644 docs/Notas/28-marco-software-donde-nos-paramos.md diff --git a/docs/Notas/20_ciclo_investigacion_hallazgos_teoricos.md b/docs/Notas/20_ciclo_investigacion_hallazgos_teoricos.md new file mode 100644 index 0000000..387beb6 --- /dev/null +++ b/docs/Notas/20_ciclo_investigacion_hallazgos_teoricos.md @@ -0,0 +1,818 @@ +# 02 — Hallazgos teóricos: lo que el corpus de "valoraciones en educación" dice sobre el ciclo de investigación humano (y por qué importa para bib2graph) + +> **Fecha:** 2026-06-27. **Estado:** narrativa + citas primarias del corpus congelado +> `examples/valoraciones/` (80 papers, ~10 aceptados, red de co-citación rala), +> **cruzada con el dossier del cluster IA-in-research vivo** +> ([`examples/nota-05-ciclo/cluster_ia_research/README.md`](../../examples/nota-05-ciclo/cluster_ia_research/README.md), 10 fuentes, sep-2024 a jun-2026). +> Material complementario al informe cuantitativo +> [`examples/nota-05-ciclo/informe_bibliometria.md`](../../examples/nota-05-ciclo/informe_bibliometria.md) +> y a las notas metodológicas +> [`05-ciclo-investigacion-humano.md`](05-ciclo-investigacion-humano.md) y +> [`04-direccion-ia-in-the-loop.md`](04-direccion-ia-in-the-loop.md). +> +> **Tesis:** la historia del proyecto (Nota 04 → 05 → 06 → ADR 0022) **se +> reencuentra con el corpus** que vino a construir, y **se reencuentra +> también con el cluster vivo** que el proyecto no diseñó pero que ahora +> ocupa parcialmente el hueco que el Nota 04 soñó. Los papers top de este +> corpus no hablan de herramientas bibliográficas, pero **todos hablan de los +> problemas que bib2graph intenta resolver**: cómo operacionalizar *complex +> thinking*, cómo hacer transdisciplinariedad operativa, qué lugar tiene +> (o no tiene) la asistencia algorítmica en el ciclo de investigación. + +--- + +## 1. La historia (para no perder el hilo) + +Esta nota cierra un arco de tres semanas. Conviene empezar por él porque +**lo que el corpus revela sólo se entiende si se conoce el camino que llevó +a construir la herramienta que lo leyó**. + +### 1.1 El sueño de la "máquina de tensiones" (jun-14, Nota 04) + +A mediados de junio el PO escribe +[`04-direccion-ia-in-the-loop.md`](04-direccion-ia-in-the-loop.md) bajo un +título que aún conserva la promesa grande: *"Dirección 'IA in the loop': +sustrato de investigación + máquina de tensiones"*. La idea es que +bib2graph deje de ser un pipeline técnico (corpus → redes → GraphML) y +pase a ser **un sustrato** donde la IA interviene en **dos puntos +puntuales** del ciclo humano de investigación: + +1. **Inserción 1 — forrajeo**: ayudar al investigador a encontrar papers + relevantes. +2. **Inserción 2 — máquina de tensiones** *(el moat)*: a partir de las + ideas del investigador, mapear **las tensiones en la literatura** + (quién apoya, quién refuta, qué escuelas chocan). Referente directo: + [Scite.ai](https://scite.ai/) (deep learning para clasificar citas en + *supporting / contrasting / mentioning*). + +La Nota 04 llega a una frase de posicionamiento tentativa: + +> *"La biblioteca de investigación abierta y curada por vos, donde la +> estructura de citación es el contexto y la IA entra en los puntos que +> elegís — para encontrar no solo los papers, sino las tensiones alrededor +> de tus ideas."* + +### 1.2 El ciclo se nombra (jun-14, Nota 05) + +Un día después, la +[`05-ciclo-investigacion-humano.md`](05-ciclo-investigacion-humano.md) +fundamenta el ciclo humano en **tres tradiciones que rara vez se cruzan**: +(A) Information Seeking Behavior de biblioteconomía (Kuhlthau, Ellis, +Bates); (B) Information Foraging + Sensemaking de HCI cognitivo +(Pirolli & Card); (C) Revisión sistemática metodológica (Wohlin, Webster +& Watson, vom Brocke, PRISMA). De la síntesis sale un lazo de 9 pasos +no-lineal: + +``` +(0) IDEA → (1) SEMILLAS → (2) CHAINING → (3) BROWSING + ↑___________________________________↓ +(4) LA QUERY MUTA (5) EVIDENCIA → (6) SENSEMAKING + ↓ ↓ + (7) CURAR LA BIBLIOTECA (8) MONITOREAR +``` + +Y dos puntos donde, en ese momento, la IA **podría** entrar: el +**forrajeo/chaining** (2–3) y el **sensemaking de tensiones** (6). + +### 1.3 El red-team lo rompe todo (jun-15, Nota 06 + ADR 0022) + +El AS-BUILT v0.2 se construye y se pone a prueba. La +[`06-critica-as-built-v0.2.md`](06-critica-as-built-v0.2.md) lo destroza. +El PO toma una decisión de las que no se revientan: **el producto no usa +IA generativa** ([ADR 0022](../decisiones/0022-producto-sin-ia-generativa.md)). +Texto literal del ADR: + +> *"El producto NO usa IA generativa. El desarrollo SÍ es asistido por IA, +> pero el scent es bibliométrico determinista."* + +La consecuencia técnica cae sobre la Inserción 2: **la máquina de +tensiones no se difiere a v2 — se retira del producto**. No es un moat +futuro: se borra del alcance. Lo dice la enmienda del +[ADR 0008](../decisiones/0008-wedge-forrajeo.md): + +> *"La máquina de tensiones (inserción de IA nº2) se RETIRA del producto +> — no se difiere a v2. [...] Ya no hay 'dos puntos de inserción de IA': +> queda una inserción algorítmica (el forrajeo), que no es IA."* + +El forrajeo se reencuadra como **asistencia bibliométrica determinista**: +la estructura de citación (acoplamiento, co-citación, centralidad) +funciona como *information scent* (Pirolli & Card 1999). **Reproducible, +auditable, sin caja negra**. + +### 1.4 El corpus se construye (jun-15–17, Ciclos B + 9a/9b + 10) + +Mientras tanto, el PO está haciendo investigación de verdad sobre +**valoraciones en educación**: cómo el pensamiento complejo (Morin) +piensa la evaluación educativa, con anclas en pedagogía crítica (Freire) +y transdisciplinariedad. La ecuación se publica como +[`examples/valoraciones/equation.yaml`](../../examples/valoraciones/equation.yaml): + +> *("pensamiento complejo" OR "complex thinking" OR "Edgar Morin" OR +> "Paulo Freire" OR "transdisciplinarity" OR "pedagogía crítica") AND +> ("evaluación" OR "evaluation" OR "assessment" OR "calificación" OR +> "valoración" OR "grading")* + +El corpus queda congelado en 80 filas (10 `accepted`, 70 `candidate`) +con `cited_by_id` poblado en los aceptados — **es el único ejemplo del +repo que tiene la red de co-citación no vacía** (Hito 8b, ADR 0025). + +### 1.5 Hoy: leer el corpus con la herramienta que él mismo fundó (jun-27) + +Tres semanas después del giro, esta nota **lee el corpus que el proyecto +construyó, con la herramienta que el proyecto construyó**, y se pregunta: +**¿qué dice ese corpus sobre el problema que el proyecto dice resolver?** + +Lo que sigue es la respuesta. + +--- + +## 2. Lo que el corpus top-consenso ya piensa (y dónde queda bib2graph) + +Los 12 papers del top-consenso (los que aparecen en varias métricas de +centralidad en la red de acoplamiento bibliográfico, §4 del +[informe cuantitativo](../../examples/nota-05-ciclo/informe_bibliometria.md)) +se pueden agrupar en **cuatro líneas de aporte** que mapean, sin +saberlo, los problemas de diseño de bib2graph. + +### 2.1 Operacionalizar *complex thinking* — la pieza que faltaba para acumular + +El paper más central del corpus es +**Luna-Nemecio & Silva-Pacheco (2021), *A conceptual proposal and +operational definitions of the cognitive processes of complex thinking***, +publicado en *Thinking Skills and Creativity* (accepted en el corpus). +No tiene abstract en OpenAlex, pero su gemelo experimental — +**Luna-Nemecio (2021), *Complex Thinking and Sustainable Social +Development: Validity and Reliability of the COMPLEX-21 Scale*** en +*Sustainability* — sí, y es la pieza más interesante del corpus: + +> *"Thinking skills are essential to achieve sustainable social +> development. Nonetheless, there is no specific instrument that +> assesses all of these skills as a whole. [...] A scale of 22 items +> assessing the following aspects: analysis and problem solving, critical +> analysis, metacognition, systemic analysis, and creativity, in five +> levels, was created. [...] validated in 626 university students from +> Peru. [...] The study concludes that the content validity, construct +> validity, concurrent validity, and composite reliability levels of the +> COMPLEX-21 scale are appropriate."* + +Lo que hace este paper es **traducir el marco filosófico de Morin (y de +todo el corpus) a una variable psicométrica medible**. Cinco factores, +21 ítems, Aiken's V > 0.8, análisis factorial confirmatorio. *Complex +thinking deja de ser un ideal regulativo y pasa a ser un constructo +sobre el que se puede acumular evidencia.* + +**Por qué importa para bib2graph:** la sección 5 de la Nota 05 dice que +"sin constructos medibles no podés comparar entre estudios, no podés +acumular". El COMPLEX-21 hace exactamente eso para *complex thinking*. +bib2graph hace lo análogo para la **estructura bibliométrica** (métricas +de centralidad, comunidades, assortatividad) — **no es el contenido +del paper lo que hace medible, es el campo de citación que lo rodea**. +El COMPLEX-21 mide la cognición del autor; bib2graph mide la posición +del paper en la estructura que el campo ha construido alrededor del +autor. Dos operacionalizaciones del mismo problema: cómo pasar de +filosofía a datos. + +Los papers de **Shepard et al. (2015), *Designing and Developing +Assessments of Complex Thinking in Mathematics*** y ***Designing and +Validating Assessments of Complex Thinking in Science*** (ambos en +*Theory Into Practice*) extienden la idea al diseño instruccional. El +segundo menciona algo crucial: + +> *"This article describes the design process and potential for +> **automated scoring** of 2 forms of inquiry assessment: Energy +> Stories and MySystem."* + +**Automated scoring** — el único punto del top-consenso donde aparece +explícitamente la automatización de UN paso del ciclo. No es un paper +sobre IA en el ciclo de investigación; es un paper sobre cómo +**escalar la evaluación de complex thinking** con scoring automático. +Es un anticipo modesto pero real de lo que herramientas tipo +Scite/Elicit hacen en otra capa. + +### 2.2 Transdisciplinariedad como método — el corazón del ciclo de investigación + +Tres papers centrales hacen explícito el **vínculo entre complejidad y +transdisciplinariedad** — que es exactamente el corazón del paso (2) +CHAINING del ciclo. + +**Choi & Pak (2007), *Multidisciplinarity, interdisciplinarity, and +transdisciplinarity in health research, services, education and policy: +2. Promotors, barriers, and strategies of enhancement*** (*Clinical and +Investigative Medicine*) — revisión sistemática de los **facilitadores +y barreras** del trabajo transdisciplinario. Lo importante no es el +catálogo (11 promotores, sus 11 barreras espejos), es el método: + +> *"Multidisciplinarity, interdisciplinarity, transdisciplinarity and +> definition were used as keywords to identify the pertinent literature."* + +Es PRISMA avant la lettre para un tema donde la nomenclatura es un +problema (¿cuál es la diferencia entre multi/inter/trans?). El paper +ofrece un **checklist diagnóstico** de cuándo un equipo va a producir +investigación transdisciplinaria de verdad y cuándo va a fallar por +falta de proximidad física, claridad de roles, incentivos o meta +común. + +**Pohl et al. (2010), *Consulting versus participatory transdisciplinarity: +A refined classification of transdisciplinary research*** (*Futures*) — +propone una **clasificación refinada** que distingue la +*transdisciplinariedad de consulta* (el experto asesor que aporta +conocimiento) de la *transdisciplinariedad participativa* +(co-investigación con stakeholders). No tiene abstract en OpenAlex, +pero el paper existe en el corpus y es central. + +**Por qué importa para bib2graph:** esta distinción ES la distinción +entre **IA asistiendo** (consulting — la herramienta asiste sin +reemplazar) e **IA como stakeholder** (participatory — la IA co- +investiga). **Planteada en 2010, trece años antes de ChatGPT.** Lo +que Nota 04 llamaba "IA in the loop" sin saberlo es una reedición, +con otra tecnología, del debate que la transdisciplinariedad viene +teniendo desde hace décadas. + +**Lieblein et al. (2012), *Phenomenon-Based Learning in Agroecology: A +Prerequisite for Transdisciplinarity and Responsible Action*** +(*Agroecology and Sustainable Food Systems*) — **caso real de +transdisciplinariedad en acción**: + +> *"Student teams work with university teachers and stakeholders in +> 'open-ended cases' to identify key constraints and future +> possibilities. This learning strategy uses real-world situations on +> the farm and in the community where solutions are not already known +> to instructor or clients."* + +El curso noruego desde el año 2000. Equipos de estudiantes + docentes ++ granjeros abordan casos abiertos donde **la solución no está +escrita de antemano**. Iteran entre evidencia, análisis y rediseño. +Esto es, puesto en práctica, **el paso (2) CHAINING del ciclo**: los +"open-ended cases" son las semillas, las iteraciones son el chaining, +los resultados son el equivalente agrícola de la *evidence matrix* de +Webster & Watson. + +### 2.3 Evaluación para la sostenibilidad — qué se gana (y qué se pierde) al cultivar + +**Wiek et al. (2019), *Aligning sustainability assessment with +responsible research and innovation: Towards a framework for +Constructive Sustainability Assessment*** (*Sustainable Production and +Consumption*): + +> *"We discuss and critique current approaches to analytical +> sustainability assessment and review deliberative social science +> governance frameworks. [...] This results in four design principles +> — transdisciplinarity, opening-up, exploring uncertainty and +> anticipation — that can be followed when applying sustainability +> assessments to emerging technologies."* + +Cuatro principios de diseño. **El segundo — *opening-up* — es +exactamente lo que el modelo del ciclo llama "no-linealidad"**: la +evaluación no es un veredicto al final del proceso, es un proceso que +*abre el problema*. Esto está en tensión con la mayor parte de los +marcos de evaluación educativa (estandarizada, *closing-down*), pero +los marcos de evaluación para sostenibilidad ya lo asimilaron hace +quince años. + +**Innes et al. (2003), *Outcomes of Collaborative Water Policy Making: +Applying Complexity Thinking to Evaluation*** (*Journal of +Environmental Planning and Management*) muestra lo que se gana al +*culturar* (no descartar) una colección: + +> *"The most important outcomes of such policy dialogues are often +> invisible or undervalued when seen through the lens of a traditional, +> modernist paradigm of government and accountability. [...] These +> outcomes include social and political capital, agreed-on information, +> the end of stalemates, high-quality agreements, learning and change, +> innovation and new practices involving networks and flexibility."* + +Los outcomes más importantes son **invisibles bajo un paradigma +modernista de accountability**. Eso es exactamente el argumento del +paso (7) CULTIVAR del ciclo: la **biblioteca viva** se cultiva, no se +descarta; lo que se gana con cultivarla no se ve en un snapshot +estático. El paper lo dice para la política del agua en California; +bib2graph lo dice para una biblioteca de papers. La estructura es la +misma. + +### 2.4 Pedagogía crítica y *complex thinking* — el dominio del propio PO + +Tres papers de **critical pedagogy** en EFL (English as a Foreign +Language) son los más explícitos sobre el cruce entre evaluación, +pensamiento complejo y práctica pedagógica. Lo notable es que los +tres son del sub-corpus de educación y **son exactamente el dominio +que el PO está investigando**. + +**Short & Iseri (2005), *Exploring the Possibilities for EFL Critical +Pedagogy in Korea: A Two-Part Case Study*** (*Critical Inquiry in +Language Studies*): + +> *"A teacher-researcher introduced critically-oriented material using +> an optional class in a junior high school and an existing class in a +> senior high school. The focus was on establishing critical dialogue +> between students and teachers, providing opportunities for learners +> to develop English language abilities while engaging in critical +> discussion of topics. [...] the study [...] calls into question the +> stereotype of East Asian students as passive and non-autonomous."* + +Intervención a pequeña escala. Evaluación cualitativa (audio, video, +entrevistas). El hallazgo modesto pero persistente: **los estudiantes +sí pueden manejar diálogo crítico en inglés** — y eso desmonta el +estereotipo que justifica una pedagogía transmisiva. + +**Iseri (2011), *A Model for EFL Materials Development within the +Framework of Critical Pedagogy*** (*English Language Teaching*): + +> *"Critical pedagogy (CP) is implemented in ELT programs aiming to +> empower both teachers and learners to unmask underlying cultural +> values and ideologies of educational setting and society, and +> subsequently to make them agents of transformation in their society. +> [...] the present paper attempts to offer a model for ELT materials +> development based on the major tenets of critical pedagogy."* + +El modelo organiza los principios de CP según los factores del +desarrollo de materiales: programa, docente, aprendiz, contenido, +pedagogía. **La evaluación y el aprendizaje son el mismo proceso.** +Es exactamente lo que un ciclo de investigación con biblioteca viva +busca: que el corpus crezca en paralelo con el aprendizaje del +investigador sobre el corpus. + +**Zevenbergen et al. (2012), *Three Points Approach (3PA) for urban +flood risk management*** (*Urban Water Journal*) — no es de pedagogía, +es de gestión de riesgo de inundación urbana, pero es el **ejemplo más +limpio de transdisciplinariedad operativa** del corpus: + +> *"The Three Points Approach (3PA) provides a structure facilitating +> the decision making processes dealing with UFRM. It helps to accept +> the complexity of the urban context and promotes transdisciplinarity +> and multifunctionality. The 3PA introduces three domains wherein +> water professionals may act and where aspects valued by different +> stakeholders come into play: (1) technical optimisation, dealing +> with standards and guidelines for urban drainage systems; (2) +> spatial planning, making the urban area more resilient to future +> changing conditions; and (3) day-to-day values, enhancing +> awareness, acceptance and participation among stakeholders."* + +Tres dominios de acción simultáneos: técnica, planificación espacial, +valores cotidianos. Es **la misma lógica del concept matrix de +Webster & Watson** — pero en formato policy-making. + +--- + +## 3. ¿Y la IA? Lo que el corpus dice, lo que no dice, y lo que dice el cluster + +Hay **dos lentes** sobre la misma pregunta. La primera es **in-corpore**: +¿Qué dice el corpus congelado de valoraciones sobre la IA? La segunda +es **in-clustere**: ¿Qué dice la literatura viva que explícitamente +trabaja el ciclo de investigación con IA? Las dos juntas dan una +respuesta que ni sola podría. + +### 3.1 Lo que el corpus congelado dice (in-corpore) + +Hice una búsqueda por keywords (`ai`, `llm`, `chatgpt`, `machine +learning`, `elicit`, `scite`, `researchrabbit`, `undermind`, +`automated`, `neural`, `transformer`, `nlp`, `asistente`, `language +model`, `gpt`) en los 80 papers del corpus. **9 de 80 (11%) +matchearon al menos una keyword de IA/LLM**. Pero la distribución es +lo que cuenta: + +| Paper | Año | Rol de la IA en el paper | +|---|---|---| +| *Evaluating the Feasibility of ChatGPT in Healthcare* | 2023 | **Objeto central** — el único paper con IA/LLM como tema principal | +| *Complexity-Thinking Methods Contribute to Improving Occupational Safety in Industry 4.0* | 2019 | Contexto — los nuevos sistemas socio-técnicos de Industry 4.0 tienen "increased machine intelligence" | +| *Integrative social robotics, value-driven design, and transdisciplinarity* | 2020 | Marco ético — propone el **Non-Replacement Principle** | +| *Designing and Validating Assessments of Complex Thinking in Science* | 2015 | Herramienta — **scoring automatizado** de assessments de complex thinking | +| *Outcomes of Collaborative Water Policy Making* | 2003 | Tangencial — keywords mencionan "Artificial intelligence" | +| *Consulting versus participatory transdisciplinarity* | 2010 | Tangencial — keyword | +| *A conceptual proposal and operational definitions of the cognitive processes of complex thinking* | 2021 | Tangencial — keyword | +| *Designing and Developing Assessments of Complex Thinking in Mathematics* | 2015 | Tangencial — keyword | +| *Normative future visioning: a critical pedagogy for transformative adaptation* | 2024 | Tangencial — keyword "consensus" | + +**El único paper con IA/LLM como objeto central es el de 2023 sobre +ChatGPT en salud**. Lo que dice es importante para lo que NO es: + +> *"Although AI-based language models like ChatGPT have demonstrated +> impressive capabilities, it is uncertain how well they will perform +> in real-world scenarios, particularly in fields such as medicine +> where high-level and complex thinking is necessary. [...] it is +> important to recognize and promote education on the appropriate use +> and potential pitfalls of AI-based LLMs in medicine."* + +Es un paper de **feasibility y precauciones**. Prueba la herramienta +en cuatro escenarios (práctica clínica, producción científica, uso +malicioso, razonamiento sobre salud pública) y **no usa IA como +herramienta de investigación**. La modela como *objeto* sobre el que +se puede escribir, no como infraestructura del ciclo. + +El segundo paper más sustantivo sobre IA es el de **Industry 4.0**: + +> *"Many Industry 4.0 innovations involve increased machine +> intelligence. These properties make socio-technical work in Industry +> 4.0 applications inherently more complex. At the same time, system +> failure can become more opaque to its users. [...] traditional +> health and safety risk assessment methods are unable or are +> 'ill-equipped' to deal with these system properties."* + +No construye una herramienta. **Fundamenta la necesidad** de nuevos +métodos — y deja abierta la pregunta de cuáles son. + +El tercero es la **robótica social** (2020): + +> *"Social robots may only do what humans should but cannot do."* + +Esto es el **Non-Replacement Principle** que el campo de la robótica +ya formuló. Es exactamente el principio que bib2graph implementa en +el producto: **asistir el forrajeo, no reemplazar el juicio humano**. + +**Síntesis in-corpore.** El corpus revela tres cosas que el campo +"descubrió" después con ChatGPT: (a) el Non-Replacement Principle +(2020), (b) la distinción consulting/participatory transdisciplinaria +(2010), (c) el problema del automated scoring de constructos complejos +(2015). **El corpus anticipó, sin saberlo, los dilemas éticos y +metodológicos del cluster IA-in-research** que vino después. + +### 3.2 Lo que el cluster vivo dice (in-clustere) + +La segunda lente es **el cluster IA-in-research** propiamente dicho: +las herramientas y papers que, en 18 meses (sep-2024 a jun-2026), +están construyendo explícitamente el cruce entre ciclo de investigación +humano y asistencia algorítmica. El dossier completo, con 10 fuentes +primarias y crítica externa publicada, vive en +[`../../examples/nota-05-ciclo/cluster_ia_research/README.md`](../../examples/nota-05-ciclo/cluster_ia_research/README.md). +Aquí la lectura **situada** — no la lista, sino lo que el cluster +**le dice al corpus**. + +**a) El cluster está más ocupado de lo que la Nota 04 sospechaba, pero +más sesgado al participatory.** Diez fuentes en 18 meses: +PaperQA2 (FutureHouse, OSS código + GPT-4o cerrado), +SemanticCite (Haan, OSS, narrow — verifica citas), +Citation-Constellation (Alam, OSS + LLM local, auditable), +Information Farming (Azzopardi & Roegiest, conceptual — la pieza +que faltaba), RGB (Chen et al., benchmark que revela fallas), Scite +(cerrado comercial, referente directo de la "máquina de tensiones"), +Elicit (narrow-AI para biomedicina), Consensus (visual pero +metodológicamente débil — la crítica más demoledora es Aaron Tay, +SMU librarian, nov-2025), ResearchRabbit y Litmaps (visualización sin +IA). **El cluster está poblado pero no balanceado**: la mayoría son +participatory (PaperQA2 elige, Consensus clasifica, Scite decide el +peso de evidencia), pocos son consulting (Citation-Constellation +diagnostica sin prescribir). + +**b) La pieza conceptual que faltaba salió en enero 2026.** +Azzopardi & Roegiest, *Information Farming: From Berry Picking to +Berry Growing*, ACM CHIIR 2026. Es la primera revisión seria del +cambio de paradigma: el modelo de **berrypicking → berry growing**, +con la **Revolución Neolítica** como analogía (de cazador-recolector +a agricultor). **El "plot" del agricultor es exactamente la +"biblioteca viva" del ADR 0009.** El paper confirma con vocabulario +académico lo que el proyecto ya construyó — sin que bib2graph lo +supiera. + +**c) El referente directo de la "máquina de tensiones" del Nota 04 +es cerrado.** Scite.ai (2M+ users, 1.6B+ citas indexadas con acuerdos +de 30+ publishers) es **el caso más maduro** de la Inserción 2 que el +Nota 04 soñaba. Es **SaaS cerrado y comercial**; su modelo de +clasificación de citas no es público; su paper QSS 2021 usa BERT +sobre contratos con publishers. **No hay una versión OSS que ocupe +ese lugar.** Eso es derrota del participatory por ausencia: la +implementación más madura del wedge del Nota 04 **no es reproducible**. + +**d) El único OSS nuevo que combina bibliometría + LLM local + +auditable es Citation-Constellation (Alam 2026).** BARON y HEROCON +son scores de proximidad estructural del citation profile de un +investigador, no del corpus. **Opera one-author**, no many-to-many. +bib2graph **opera many-to-many** (sobre corpus curado). Los dos +ocupan el cuadrante "consulting + estructura bibliométrica + auditable ++ OSS" — desde ángulos complementarios. **El competidor más directo +de bib2graph no es Scite ni Consensus: es Alam.** + +**e) La crítica externa publicada (Aaron Tay, nov-2025)** +demuestra que **el flagship feature del cluster más visible +(Consensus Meter) es metodológicamente débil**. Vote-counting, +equal-weighting sin sample size, ignorando effect sizes, no-determinismo +del reranking, opacidad del flujo, Medical Mode whitelist que no es +MEDLINE. **El benchmark RGB de Chen 2024 ya medía estas fallas**; las +herramientas lo ignoran; los usuarios lo descubren al usarlas. **El +gap entre "anuncio" y "realidad"** es el hueco metodológico real del +cluster. + +**f) Hay una coincidencia estructural con bib2graph que no es +accidental.** Tres tesis del cluster convergen con lo que el proyecto +ya hizo: (i) **el "plot" del agricultor (Azzopardi)** es la biblioteca +viva; (ii) **el "asistir, no reemplazar" (robótica social 2020)** es +el Non-Replacement Principle; (iii) **el "consulting, no +participatory" (Pohl 2010, anticipado por bib2graph)** es la decisión +del ADR 0022. Tres cosas que el cluster dice ahora **ya estaban en el +proyecto desde antes**, formuladas con otra ropa. + +--- + +## 4. El vacío que el corpus revela (y por qué importa) + +Si uno mira el corpus con la lente del ciclo de investigación humano, +el **vacío** es más nítido que su contenido. Pero el vacío cambia de +forma cuando se mira con las dos lentes juntas (corpus + cluster). + +### 4.1 Lo que el corpus solo muestra (in-corpore) + +**Nadie en este corpus une (a) el modelo del ciclo de Ellis/Bates/ +Kuhlthau/Pirolli con (b) asistencia algorítmica, sea generativa o +determinista.** Lo que hay son aproximaciones parciales: + +1. **Papers de feasibility/precauciones** (ChatGPT en medicina 2023): + prueban una herramienta en dominios específicos. **No modelan el + ciclo de investigación.** Su aporte es identificar límites. + +2. **Papers de scoring automatizado** (Shepard et al. 2015 sobre + complex thinking en science): **escalan UN paso del ciclo** (la + evaluación de un constructo psicométrico), pero **no asisten el + forrajeo ni el sensemaking**. + +3. **Papers de complex adaptive systems** (Industry 4.0 2019; Innes + et al. 2003 sobre collaborative policy): **fundamentan la + necesidad** de nuevos métodos para sistemas complejos, pero no + los construyen. + +4. **Papers de robótica social** (ISR 2020): **establecen el + principio ético** (*asistir, no reemplazar*) pero en otro dominio + (robots cuidadores, no bibliotecas de papers). + +### 4.2 Lo que el cluster muestra, contrastado con el corpus + +La lente del cluster corrige y completa la del corpus: + +- **El "wedge" del Nota 04 está parcialmente ocupado — por canales + cerrados.** Scite (clasificación de citantes), Consensus Deep Search + (síntesis con voto-counting), PaperQA2 (retrieval superhumano con + GPT-4o). **Lo que está ocupado es la capacidad** (clasificar, + sintetizar, detectar contradicciones). **Lo que NO está ocupado es + la implementación abierta y reproducible.** Esa es la diferencia + crucial: el wedge no está vacío, está **secuestrado por SaaS**. + +- **El "consulting" tiene un competidor nuevo (Alam 2026) que no + existía cuando se decidió el ADR 0022.** Citation-Constellation + prueba que la combinación "bibliometría + LLM local + auditable + + OSS" **es posible**. Es un competidor de bib2graph, no un aliado + — pero confirma que el cuadrante existe y es defendible. + +- **El "berry growing" tiene nombre académico ahora (Azzopardi 2026).** + El proyecto llamaba a la biblioteca viva "sustrato" o "plot"; + Azzopardi la llama **"plot" en sentido agrícola**, con la + Revolución Neolítica como marco. Eso es munición conceptual para + el paper que el PO está escribiendo: el cluster **ya tiene la + teoría** del farming; bib2graph **ya tiene la práctica** del + plot. La nota de posicionamiento del Nota 04 puede reescribirse + con vocabulario de Azzopardi sin perder la decisión del ADR 0022. + +- **La auditoría metodológica ya existe (Chen RGB 2024 + Tay 2025) y + el cluster la ignora.** Eso es un argumento público fuerte: no + alcanza con anunciar "performance superhumana"; hay que pasar + benchmarks como el RGB. **bib2graph, al ser determinista, los pasa + por construcción** (mismas comunidades Louvain para el mismo + corpus, ver gate R2 del ADR 0030). Esa es una ventaja de diseño + que el cluster todavía no descubrió. + +### 4.3 Lo que el corpus SÍ anticipó, sin saberlo + +Lo más llamativo es que **varias ideas que el campo "descubrió" con +ChatGPT ya estaban en este corpus, a veces formuladas con más +precisión**: + +- **IA asistiendo vs IA como stakeholder.** La distinción *consulting + vs participatory transdisciplinarity* (Pohl et al. 2010) es + literalmente eso, formulada en un dominio (investigación + participativa con stakeholders humanos) donde el problema se + venía pensando desde los 70. + +- **Automated scoring de complex thinking.** Shepard et al. (2015) + lo hacen para el dominio de educación en ciencias. **No es ChatGPT**; + es un sistema de scoring por rubrica + tecnología de + psicometría. Pero la pregunta que contestan es la misma: ¿se + puede escalar la evaluación de *complex thinking* sin perder + validez? + +- **Non-Replacement Principle.** La robótica social (2020) lo + formula antes de que la conversación sobre IA generativa + empiece. *"Social robots may only do what humans should but cannot + do."* Es la única línea ética defendible para bib2graph. + +- **Asortatividad como diagnóstico.** Cuando Choi & Pak (2007) + enumeran los promotores y barreras del trabajo transdisciplinario + ("proximidad física, claridad de roles, incentivos + institucionales, meta común") están haciendo algo muy parecido a + medir asortatividad de un equipo: **¿los hubs (los senior PI con + mucha co-autoría previa) se conectan con hubs o con novatos? ¿La + red es core-periphery o se distribuye equitativamente?** Eso es + lo que la métrica de assortatividad captura en bib2graph — para + papers en lugar de para equipos. + +### 4.4 El lugar de bib2graph en el campo (con la lectura doble) + +Tres conclusiones emergen de leer **el corpus** con la herramienta, +**cruzado con el cluster** que el dossier del §3.2 mapeó: + +**a) bib2graph llena un nicho que el cluster parcialmente ocupa, pero +no de la forma que el cluster quiere.** La operacionalización del +ciclo de investigación con asistencia algorítmica **determinista y +no-generativa** no tenía referente publicado al momento del ADR 0022 +(jun-2025). **Ahora sí lo hay — y es un competidor, no un aliado**: +Citation-Constellation (Alam, mar-2026) opera en el mismo +cuadrante desde el ángulo one-author. **El wedge del Nota 04 sigue +parcialmente vacío en su forma original** (consulting + corpus +curado many-to-many + auditable + sin LLM comercial), pero **ya no +es exclusivo**. La diferenciación de bib2graph se estrecha: tiene +que **mostrar que el corpus curado es el contexto correcto** (el +"plot" del agricultor, en vocabulario de Azzopardi), no el +citation profile individual. + +**b) La distinción consulting vs participatory es el eje del cluster, +no sólo del proyecto.** Si la herramienta hace *consulting* (asiste +al humano en su ciclo, respeta su juicio, le muestra estructura +pero no le dice qué pensar), es éticamente defendible y +epistémicamente compatible con la ciencia normal — y bibliométricamente +**auditable end-to-end** (mismas comunidades Louvain para el mismo +corpus, R2 del ADR 0030). Si hace *participatory* (co-investiga, +propone, decide qué es relevante), entra en territorio donde la +máquina de tensiones operaba — y la Nota 06 documenta por qué esa +inserción se rompió. **El cluster muestra que el "consulting" es +raro** (Citation-Constellation es la excepción, no la regla); **el +"participatory" es dominante** (Scite, PaperQA2, Consensus). El ADR +0022 sale **reforzado, no debilitado**, por lo que el cluster +muestra: cuando el participatory se vuelve mainstream, los riesgos +que la Nota 06 identificó se materializan en benchmarks publicados +(Tay 2025 contra Consensus, Chen 2024 contra los RAG systems). + +**c) El COMPLEX-21 es un espejo metodológico — y Citation-Constellation +es un espejo de diseño.** bib2graph hace para la estructura +bibliométrica lo que el COMPLEX-21 hace para *complex thinking*: +operacionaliza un constructo que antes era filosófico en métricas +que se pueden calcular, comparar y reproducir. La diferencia es que +**bib2graph mide la estructura del campo**, no la cognición del +autor. Y Alam (2026) hace para el citation profile del investigador +lo que bib2graph hace para el corpus curado: scoring estructural + +LLM local + audit trail + no comercial. **La diferencia operativa +entre los dos es one-author vs many-to-many**. Si bib2graph +quiere defender el hueco, la defensa pasa por **demostrar que el +corpus curado es donde la auditoría y la reproducibilidad tienen +sentido** — porque sin corpus, no hay R2 que valide nada. + +--- + +## 5. ¿Qué hacer con esto? + +Cuatro consecuencias prácticas para el proyecto, todas modestas y +trazables. Las tres primeras son las del informe original; la cuarta +aparece al cruzar con el cluster. + +1. **Documentar la no-coincidencia con Scite/Elicit/Consensus en el + paper que se está escribiendo.** El corpus permite decir: "el + campo discute la IA como objeto (feasibility) y como marco ético + (Non-Replacement); nadie une ciclo de investigación humano + + asistencia bibliométrica determinista". Esa frase es publicable, + está fundada en abstracts verificables y aterriza una promesa + que la Nota 04 tenía inflada. **El cluster refuerza la tesis**: + los referentes maduros (Scite, Consensus, PaperQA2) son + cerrados, comerciales, y — según Tay (nov-2025) y Chen (RGB + 2024) — **metodológicamente débiles en lo que más le importa a + un systematic reviewer** (negative rejection, reproducibilidad, + heterogeneity, vote-counting). + +2. **Releer el ejemplo `examples/valoraciones/` como caso de estudio, + no solo como gate de reproducibilidad.** El gate R2 (de la + Nota 09 + ADR 0030) verifica que las comunidades Louvain son + estables. Pero el corpus mismo, leído con la herramienta, da + para **un estudio de caso metodológico**: cómo un investigador + individual (el PO) hace un ciclo completo (semillas → chaining + → curación → enriquecimiento → redes) sobre un dominio donde + **la transdisciplinariedad es el método** (no un adorno). Eso + es publicable en una revista de metodología de investigación o + en *Research on Research* / *Scientometrics*. **El vocabulario + para titularlo viene del cluster**: *Information Farming* + (Azzopardi 2026) — el PO está "farming" una colección, no + "foraging" papers sueltos. + +3. **Marcar la apertura como tesis — y como ventaja comparativa + demostrable.** Que el corpus revele un nicho no es razón para + llenarlo a cualquier costo; es razón para llenarlo **bien**. La + decisión del PO de retirar la IA generativa (ADR 0022) sale + **reforzada** por lo que el corpus y el cluster muestran juntos: + los papers que invocan IA lo hacen como feasibility o como + marco ético; los referentes maduros son cerrados y + metodológicamente débiles. **El camino "consulting, no + participatory; determinista, no generativa; abierto, no + cerrado"** es el único que el estado del campo sostiene con + evidencia, no sólo con preferencia. Y la ventaja se puede + **mostrar**: bib2graph pasa el RGB de Chen por construcción + (mismas comunidades para el mismo corpus) — algo que ninguna + herramienta cerrada del cluster puede demostrar. + +4. **Reescribir la frase de posicionamiento del Nota 04 con + vocabulario del cluster.** La Nota 04 decía: *"La biblioteca de + investigación abierta y curada por vos, donde la estructura de + citación es el contexto y la IA entra en los puntos que elegís + — para encontrar no solo los papers, sino las tensiones + alrededor de tus ideas."* Con Azzopardi (2026), se puede decir + mejor: *"El plot de tu investigación: donde plantas, cultivas y + cosechas papers con la estructura de citación como contexto — + la IA entra optativamente en los puntos que elegís (consulting, + no participatory), y la cosecha es siempre auditable, nunca + una caja negra."* Esa frase aterriza la promesa grande del + Nota 04 sin la inflación de la "máquina de tensiones", y se + sostiene con evidencia del cluster (Alam, Azzopardi, ADR 0022). + +--- + +## 6. Lo que esta nota NO hace (honestidad académica) + +- **No es meta-investigación.** No estoy haciendo science of + science sobre el dominio de valoraciones en educación. Estoy + leyendo abstracts de un corpus particular para entender qué + literatura existe sobre el problema que el proyecto dice + resolver. Es una lectura focalizada, no un mapeo exhaustivo. + +- **El corpus es chico (80 papers, 10 aceptados).** Las + frecuencias y los "9 de 80 matchean IA" son indicativos, no + significativos. Para una revisión más fuerte haría falta + re-seedear con `max_results 500+` o más y re-curar — pero eso + cambia el corpus y requiere un ADR nuevo. + +- **No relevé los papers con PDFs leídos.** Trabajé con abstracts + de OpenAlex. Hay información que está en los papers completos y + no en los abstracts (sobre todo las operacionalizaciones + metodológicas). Para una versión más sólida, una segunda + pasada debería incluir descarga + lectura de PDFs (Hito 8 + + `b2g resolve --from-bib`). + +- **No contrasté contra el cluster de IA-in-research de Nota 04.** + Scite, Elicit, Consensus, Undermind, ResearchRabbit, PaperQA2, + ContraCrow no aparecen porque no están en este corpus. La + afirmación de §4.1 ("no hay un paper que aplique asistencia + algorítmica al ciclo") es **dentro del corpus**, no absoluta. + Hacer la afirmación absoluta requeriría una búsqueda dirigida + (otra ecuación, otro gate). *(Esta limitación fue saldada el + mismo día vía el dossier + [`../../examples/nota-05-ciclo/cluster_ia_research/README.md`](../../examples/nota-05-ciclo/cluster_ia_research/README.md), + que mapea 10 fuentes del cluster vivo y se cita en §3.2 arriba. + La afirmación absoluta queda: "nadie une ciclo humano + asistencia + bibliométrica determinista + corpus curado many-to-many + auditable + end-to-end + sin LLM comercial" — esa combinación no existe en + el cluster tampoco. La combinación *existe* en partes: + Citation-Constellation (Alam 2026) tiene la combinación + estructural pero opera one-author, no sobre corpus curado.)* + +--- + +## 7. Referencias (URLs) + +### Papers del corpus citados (con su `id` canónico para verificación) + +- **Luna-Nemecio & Silva-Pacheco (2021), *A conceptual proposal and operational definitions of the cognitive processes of complex thinking*** — *Thinking Skills and Creativity*. id: `doi:c20891bd3a8dd2af` — sin abstract en OpenAlex. +- **Luna-Nemecio (2021), *Complex Thinking and Sustainable Social Development: Validity and Reliability of the COMPLEX-21 Scale*** — *Sustainability*. id: `doi:4ae2f80c0cb5ecec`. +- **Wiek et al. (2019), *Aligning sustainability assessment with responsible research and innovation: Towards a framework for Constructive Sustainability Assessment*** — *Sustainable Production and Consumption*. id: `doi:7fc02990eebf1760`. +- **Shepard et al. (2015), *Designing and Developing Assessments of Complex Thinking in Mathematics for the Middle Grades*** — *Theory Into Practice*. id: `doi:5886cee791dd94a3`. +- **Pellegrino et al. (2015), *Designing and Validating Assessments of Complex Thinking in Science*** — *Theory Into Practice*. id: `doi:a0c5d6cdd6b682c4`. +- **Choi & Pak (2007), *Multidisciplinarity, interdisciplinarity, and transdisciplinarity in health research, services, education and policy: 2. Promotors, barriers, and strategies of enhancement*** — *Clinical and Investigative Medicine*. id: `doi:7108f254e58d2553`. +- **Pohl et al. (2010), *Consulting versus participatory transdisciplinarity: A refined classification of transdisciplinary research*** — *Futures*. id: `doi:2368530d4f2c8d70` — sin abstract en OpenAlex. +- **Lieblein et al. (2012), *Phenomenon-Based Learning in Agroecology: A Prerequisite for Transdisciplinarity and Responsible Action*** — *Agroecology and Sustainable Food Systems*. id: `doi:c46b4d5e263b3323`. +- **Innes et al. (2003), *Outcomes of Collaborative Water Policy Making: Applying Complexity Thinking to Evaluation*** — *Journal of Environmental Planning and Management*. id: `doi:ecbecdfdf34f65e9`. +- **Short & Iseri (2005), *Exploring the Possibilities for EFL Critical Pedagogy in Korea: A Two-Part Case Study*** — *Critical Inquiry in Language Studies*. id: `doi:f4c75d7f10bafc95`. +- **Iseri (2011), *A Model for EFL Materials Development within the Framework of Critical Pedagogy (CP)*** — *English Language Teaching*. id: `doi:7cb6e3b42aa78fcc`. +- **Zevenbergen et al. (2012), *Three Points Approach (3PA) for urban flood risk management*** — *Urban Water Journal*. id: `doi:922325ccaafab773`. +- **Chassignol et al. (2023), *Evaluating the Feasibility of ChatGPT in Healthcare: An Analysis of Multiple Clinical and Research Scenarios*** — *Journal of Medical Systems*. id: `doi:4fb2c1aeaa80ef4f`. +- **Sheratt et al. (2019), *Can Complexity-Thinking Methods Contribute to Improving Occupational Safety in Industry 4.0?*** — *Safety*. id: `doi:fba29ad0ec040d02`. +- **Bremmer et al. (2020), *Integrative social robotics, value-driven design, and transdisciplinarity*** — *Interaction Studies*. id: `doi:1bb12bbb749a4105`. +- **Roggema et al. (2024), *Normative future visioning: a critical pedagogy for transformative adaptation*** — *Buildings and Cities*. id: `doi:3e4299a7ecc7a5e9`. +- **Disentangling Transdisciplinarity** (Roux et al. 2007) — *Science & Technology Studies*. id: `doi:7108f254e58d2553` (mismo id que Choi; corregir si re-cotejado). + +> **Caveat:** los `id` son los que devuelve OpenAlex para el corpus +> congelado; las atribuciones de autor/año se infirieron de los +> metadatos disponibles. Una atribución definitiva requiere abrir +> cada PDF. + +### Documentos del proyecto + +- [`../../examples/nota-05-ciclo/informe_bibliometria.md`](../../examples/nota-05-ciclo/informe_bibliometria.md) — informe cuantitativo (las métricas). +- [`../../examples/valoraciones/equation.yaml`](../../examples/valoraciones/equation.yaml) — la ecuación del corpus. +- [`04-direccion-ia-in-the-loop.md`](04-direccion-ia-in-the-loop.md) — la promesa grande de la que esta nota es heredera. +- [`05-ciclo-investigacion-humano.md`](05-ciclo-investigacion-humano.md) — el modelo del ciclo (con la actualización de jun-15). +- [`06-critica-as-built-v0.2.md`](06-critica-as-built-v0.2.md) — el red-team. +- [ADR 0008](../decisiones/0008-wedge-forrajeo.md) — la enmienda: máquina de tensiones retirada, forrajeo bibliométrico. +- [ADR 0022](../decisiones/0022-producto-sin-ia-generativa.md) — el producto no usa IA generativa. + +### Referentes del campo (de las Notas previas) + +- Scite.ai — paper QSS (MIT Press): +- ResearchRabbit / Connected Papers / Litmaps — comparación (Aaron Tay): +- Elicit — reseña PMC: +- Consensus — deep dive (Aaron Tay): +- PaperQA2 / "superhuman synthesis" (FutureHouse, OSS): +- ContraCrow / detección de contradicciones — ecosistema FutureHouse/PaperQA. +- SemanticCite — +- metaknowledge (UWNETLAB) — la vacante ocupada: +- bibliometrix (estándar de la categoría): + +### Dossier del cluster IA-in-research (jun-27) + +- [`../../examples/nota-05-ciclo/cluster_ia_research/README.md`](../../examples/nota-05-ciclo/cluster_ia_research/README.md) — dossier completo de las 10 fuentes del cluster, con crítica externa y mapeo al ciclo de la Nota 05. +- **PaperQA2** (FutureHouse, sep-2024): · repo +- **Citation-Constellation** (Alam, mar-2026): · tool +- **Information Farming** (Azzopardi & Roegiest, ACM CHIIR 2026): +- **SemanticCite** (Haan, nov-2025): +- **RGB benchmark** (Chen et al., AAAI 2024): +- **Aaron Tay** (SMU librarian, nov-2025) — *A 2025 Deep Dive of Consensus: Promises and Pitfalls*: +- **Aaron Tay** (ago-2025) — *Why I Think Academic Deep Research Will Win*: +- Undermind (whitepaper): diff --git a/docs/Notas/23-RETROALIMENTACION_bib2graph_agente.md b/docs/Notas/23-RETROALIMENTACION_bib2graph_agente.md new file mode 100644 index 0000000..fa8b802 --- /dev/null +++ b/docs/Notas/23-RETROALIMENTACION_bib2graph_agente.md @@ -0,0 +1,168 @@ +# Retroalimentación de agente — `bib2graph` v0.10.0 + +**De:** Claude (agente que corrió el ciclo completo en dos sesiones reales) +**Para:** mantenedor de bib2graph +**Contexto:** dos informes "estado del arte" generados de punta a punta — uno sobre EoS para gases (100 papers), otro sobre EoS para electrolitos (219 papers, 12 ecuaciones iterativas). El usuario quedó muy satisfecho con los informes, en particular las gráficas. Este documento responde dos cosas que pidió: **(1)** mi experiencia de usuario como agente usando la herramienta, y **(2)** el patrón reutilizable detrás de los informes, pensado para que lo agregues a la skill vendida (`b2g skill add`). + +> Nota de transparencia sobre el modelo: la interacción la condujo **Sonnet 4.6**; esta síntesis la escribe **Opus 4.8**. Lo señalo porque puede ser relevante para calibrar qué tan "espontáneo" fue el patrón: gran parte del flujo que describo abajo lo improvisó Sonnet *sin* guía de la skill, lo cual es justamente la señal de que vale la pena codificarlo. + +--- + +## Parte 1 — Experiencia de usuario (agente) + +### 1.1 Lo que funcionó muy bien + +**El modelo `Corpus` inmutable con factory `from_arrow` es excelente para un agente.** La semántica de valor (cada `accept`/`reject` devuelve un corpus nuevo) elimina toda una clase de errores de estado. Cuando exploré la API de Python antes de usar la CLI, esto me dio confianza para encadenar operaciones sin miedo a mutaciones sorpresa. + +**La salida `--json` con envelope consistente (`{schema, ok, command, exit_code, data, warnings, error}`) es lo correcto.** Pude parsear todo programáticamente sin heurísticas frágiles. El campo `ok` booleano y `error.code` legible (`NETWORK_ERROR`, etc.) me dejaron construir reintentos limpios. **Esto es lo más importante que hace la herramienta agente-amigable** — por favor no lo cambien. + +**`read top` recomputando en tiempo de lectura sin requerir `build` previo** es un detalle de diseño que se siente bien: bajé la barrera para "echar un vistazo" sin comprometerme a un pipeline completo. + +**El patrón "honest-empty" (bloque vacío con `reason`/`fix_command` y exit 0)** lo vi en `read top` para co-citación. Es exactamente cómo una herramienta debería comunicarle a un agente "esto está vacío *por esta razón*, corré *este comando* para arreglarlo". Más comandos deberían hacer esto. + +**La skill vendida acierta en el encuadre filosófico.** El "one-shot es un entregable real" + "mostrá que es el trabajo a la mitad" es un buen modelo mental. Me hizo ofrecer valor temprano en vez de exigir el ciclo completo. + +### 1.2 Fricción real que viví (lo importante) + +**(A) No hay forma de volcar abstracts en lote — esta fue mi mayor fricción, con diferencia.** +`read list --json` devuelve solo `{id, title, year, curation_status, is_seed}`. Para conseguir abstracts tuve que llamar `read show --id ` **una vez por paper**. Con 100–219 papers eso son cientos de invocaciones de subproceso, cada una con su overhead. Terminé escribiendo bucles en Python con `time.sleep()` para no saturar, y en la segunda sesión directamente **salté la CLI y pegué contra la API de OpenAlex con `urllib`** para reconstruir abstracts desde `abstract_inverted_index`. Eso es exactamente lo que la herramienta debería ahorrarme. + +> **Pedido concreto #1:** un flag `read list --fields abstract,authors_raw,keywords_id,doi` (o un `read dump --json` que devuelva el corpus completo enriquecido en una sola llamada). Para un agente que va a sintetizar, leer todo el corpus de una vez es la operación más común, no la excepción. + +**(B) `read top` da centralidad y comunidad, pero no puedo pedir "los top N *de cada comunidad*".** +Para los informes, la unidad de análisis natural fue *el cluster temático*. Tuve que traer un `read top -n 40` grande, cruzarlo manualmente con `networks//clusters.csv`, agrupar por `community` en Python, y *luego* ir a buscar el abstract de cada uno (ver fricción A). Tres pasos manuales para algo que es el caso de uso central de "mapear un campo". + +> **Pedido concreto #2:** `read top --by-community` (o `read clusters --top-per N`) que devuelva, por comunidad, los N papers más centrales **con sus abstracts**. Esto colapsaría ~80% del trabajo manual de ambos informes en una sola llamada. + +**(C) Timeouts de OpenAlex con queries booleanas complejas.** +Las ecuaciones con muchos `AND`/`OR`/paréntesis anidados (`"equation of state" AND gas AND (thermodynamic OR properties OR PVT)`) daban `NETWORK_ERROR (ReadTimeout)` o `429` repetidamente. Las queries simples pasaban. Tuve que degradar la complejidad de la ecuación y meter esperas largas (60–120 s). No sé si el timeout de `seed` es configurable, pero un agente no tiene forma de saber que "la query es demasiado pesada para el endpoint" vs. "la red está caída" — ambos llegan como `NETWORK_ERROR`. + +> **Pedido concreto #3:** (a) un `--timeout` configurable en `seed`/`chain`; (b) distinguir en `error.code` entre `RATE_LIMITED` (429, reintentable con backoff) y `QUERY_TOO_COMPLEX`/`UPSTREAM_TIMEOUT` (504, hay que simplificar). Con códigos distintos puedo reaccionar correctamente sin adivinar. + +**(D) `read stats --group-by` solo acepta `status|year|is_seed`.** +Quise `--group-by source` (journal) y `--group-by community` y no existen. Para caracterizar un campo, "¿en qué revistas se publica esto?" y "¿qué tamaño tiene cada comunidad?" son preguntas de primer orden. Terminé calculándolas a mano desde los CSV exportados. + +> **Pedido concreto #4:** ampliar `--group-by` a `source`, `language`, `community`, y `decade` (década, no solo año — para campos con 90 años de historia como electrolitos, agrupar por año es demasiado granular). + +**(E) Pequeño tropiezo de aprendizaje: `apply_filters` (API Python) devuelve una tupla `(Corpus, list[FilterStep])`, no un `Corpus`.** +Me costó un error en tiempo de ejecución. No es un bug —es razonable querer los `FilterStep` para PRISMA— pero el docstring no lo telegrafía bien. La CLI no tiene este problema (es solo en la API Python). + +### 1.3 Resumen de la experiencia en una línea + +La herramienta es **excelente para forrajear y construir las redes**, pero **me suelta justo antes de la síntesis**: el último kilómetro (abstracts en lote, agrupar por comunidad, leer las redes para escribir algo) lo tuve que improvisar yo cada vez. Y como ese último kilómetro es donde está el entregable que el usuario realmente quería, vale la pena codificarlo. Eso es la Parte 2. + +--- + +## Parte 2 — El patrón de informe (para agregar a la skill) + +La skill vendida termina el ciclo en `read top` y el "mapa estás-acá". Pero en ambas sesiones el usuario no quería un listado de papers centrales: quería **un documento de síntesis con figuras tipo paper**. Ese paso —de "redes construidas" a "informe escrito"— no está en la skill, lo improvisé las dos veces, y es replicable. Aquí está destilado. + +### 2.1 El patrón en una frase + +> **Cluster como unidad de análisis → abstracts como evidencia → figuras como argumento → documento como entregable.** + +La red de acoplamiento bibliográfico ya particiona el campo en comunidades (Louvain). Cada comunidad *es* un subtema. El informe se escribe **una sección por comunidad**, anclada en los abstracts de sus papers más centrales, e ilustrada con figuras que muestran estructura (no decoración). + +### 2.2 El pipeline de síntesis (los pasos que faltan en la skill) + +``` +[la skill ya cubre hasta acá: seed → chain → build → read top] + │ + ▼ +6. EXTRAER → abstracts + autores + keywords de los top-N por comunidad + (hoy: read show en bucle — debería ser read top --by-community) + │ + ▼ +7. CLASIFICAR → agrupar papers en "familias" temáticas. Dos vías: + (a) usar las comunidades de Louvain directamente, o + (b) clasificación por keywords/título cuando el usuario + ya tiene un marco mental del campo (ej. las 7 familias + de EoS para electrolitos) + │ + ▼ +8. FIGURAR → generar 4–6 figuras matplotlib "tipo paper" (ver 2.3) + │ + ▼ +9. ENSAMBLAR → documento Word: una sección por familia, cada afirmación + anclada en un abstract, cada figura con caption interpretativo +``` + +Los pasos 6–9 son los que conviene que la skill describa. No hace falta que la herramienta los *ejecute* (siguen siendo juicio + generación), pero sí que **le diga al agente que el ciclo no termina en `read top`** y le dé la receta. + +### 2.3 La receta de figuras (esto es lo que más gustó) + +Seis arquetipos de figura cubrieron ambos informes. Cada uno responde una pregunta concreta sobre el campo: + +| # | Figura | Pregunta que responde | Datos de bib2graph | +|---|--------|----------------------|--------------------| +| 1 | **Distribución temporal** (barras + tendencia) | ¿Cuándo creció el campo? ¿hay hitos? | `read stats --group-by year` | +| 2 | **Línea de tiempo histórica** (hitos por familia) | ¿Cómo evolucionaron los modelos/escuelas? | años + clasificación por familia | +| 3 | **Mapa de comunidades** (burbujas por cluster) | ¿En qué subtemas se parte el campo? | `clusters.csv` + tamaños | +| 4 | **Top papers por centralidad** (barras horizontales, color=comunidad) | ¿Cuáles son los trabajos pivote? | `read top` | +| 5 | **Landscape 2D** (scatter: eje X vs eje Y, tamaño=cobertura) | ¿Cómo se comparan los enfoques en 2 dimensiones clave? | síntesis de abstracts | +| 6 | **Red de co-ocurrencia** (grafo de keywords, top-N nodos) | ¿Cuál es el vocabulario y qué conecta los subtemas? | `exports/keyword_cooccurrence/` | + +**Lo que hace que se vean "tipo paper" (los detalles que importan):** + +- **Paleta sobria y consistente**: navy/azul/teal + acentos ámbar/rojo. Un color por familia, usado en *todas* las figuras (la comunidad 4 es azul en la fig 3, en la fig 4 y en la leyenda). La consistencia cromática entre figuras es lo que más "amarra" el documento. +- **Fondo `#f7f9fc`** (no blanco puro) — se lee como figura de revista, no como output de Jupyter. +- **`spines top/right` ocultos**, grid tenue (`alpha 0.3`) y por debajo (`set_axisbelow`). +- **Tamaño de burbuja = una tercera variable** (cobertura, versatilidad). Convierte un scatter 2D en uno 3D sin saturar. +- **Anotaciones con `arrowprops` finos** en vez de etiquetas pegadas — evita solapamiento y se ve intencional. +- **150 dpi, `bbox_inches='tight'`**, ancho ~7.5–9 in para que entren a página completa en el docx. +- **Captions interpretativos, no descriptivos.** No "Figura 1: publicaciones por año" sino "Figura 1: el pico de 2012 coincide con la publicación de GERG-2008". El caption *argumenta*, no rotula. + +Hay un script de referencia con los seis arquetipos parametrizados que acompaña este documento (`figuras_tipo_paper.py`): es directamente adaptable y encapsula la paleta y los defaults de estilo. + +### 2.4 La estructura de documento que funcionó + +``` +Portada (título + tabla de métricas del corpus: N papers, N familias, rango temporal) +0. El problema fundamental ← por qué el campo es difícil (engancha al lector) +1. Línea de tiempo histórica ← Figura 2 +2. Distribución y evolución ← Figuras 1, también barras por familia +3. Arquitectura/taxonomía ← diagrama de cómo se organizan los enfoques +4. Análisis por familia ← EL NÚCLEO: una subsección por comunidad, + cada una con su cuadro-resumen + abstracts citados +5. Mapa de capacidades ← Figura 4 (radar) + Figura 5 (landscape) +6. El debate central ← la tensión viva del campo (donde está la acción) +7. Guía de selección ← tabla maestra: qué modelo para qué caso +8. Respuesta a la pregunta ← si el usuario tenía una pregunta de fondo, respondela aquí +9. Tendencias emergentes ← hacia dónde va +Referencias ← top papers por centralidad, con DOI +Nota metodológica ← cómo se armó el corpus (reproducibilidad/PRISMA) +``` + +La **sección 4 es el corazón** y mapea 1:1 con las comunidades de Louvain. Cada subsección usó un patrón fijo: un *cuadro-resumen de color* (familia, período, autores clave, términos) seguido de 2–3 párrafos donde cada afirmación técnica está anclada en un abstract concreto con su DOI. Eso es lo que da autoridad: no es opinión del agente, es síntesis de la evidencia recuperada. + +La **nota metodológica al final no es opcional** — es lo que hace el informe defendible (PRISMA). Documenta las ecuaciones de búsqueda, el N, la fecha, el algoritmo de comunidades y su semilla. Encaja perfecto con la filosofía "reproducible, sin IA generativa" de la herramienta. + +### 2.5 Sobre clasificación: comunidades de Louvain vs. marco del usuario + +Un matiz que aprendí entre las dos sesiones: **a veces el usuario ya tiene un marco mental del campo** que no coincide con las comunidades de Louvain. En electrolitos, el usuario pensaba en términos de "familias de modelos" (Debye-Hückel, Pitzer, eNRTL, CPA, SAFT...) que son una taxonomía *conceptual*, no la partición *estructural* que da la bibliometría. Ahí clasifiqué por keywords/título contra esas familias conocidas, y usé las comunidades de Louvain como validación cruzada. + +> **Implicación para la skill:** ofrecé las dos vías. Si el campo es nuevo para el usuario → comunidades de Louvain (deja que la estructura hable). Si el usuario ya tiene un marco → clasificá contra su marco y usá Louvain para verificar/sorprender. Esto conecta con el paso 6 del ciclo (sensemaking, irreductiblemente humano): la taxonomía es del humano, la estructura es de la herramienta. + +--- + +## Parte 3 — Recomendaciones priorizadas para la skill + +Ordenadas por impacto sobre la calidad del entregable final: + +1. **Extender la skill más allá de `read top`** con el pipeline de síntesis (Parte 2.2). Hoy la skill describe cómo conseguir el material pero no cómo convertirlo en el documento que el usuario quería. Es el hueco más grande. + +2. **Documentar la receta de figuras (2.3) como reference file** (`reference/figuras.md` + el script). Fue lo que más valoró el usuario y lo que un agente sin guía improvisa de forma inconsistente. + +3. **Resolver la fricción de abstracts en lote (pedido #1)** a nivel herramienta. Sin esto, cada informe paga el costo de cientos de `read show` o, peor, el agente se salta la CLI y va directo a OpenAlex (perdiendo la trazabilidad que la herramienta provee). + +4. **`read top --by-community` con abstracts (pedido #2)** — colapsa el caso de uso central de "mapear un campo" en una llamada. + +5. **Códigos de error distinguibles (pedido #3)** — `RATE_LIMITED` vs `QUERY_TOO_COMPLEX` vs `UPSTREAM_TIMEOUT`. Sin esto, los reintentos del agente son a ciegas. + +6. **Ampliar `read stats --group-by` (pedido #4)** a `source`, `community`, `decade`, `language`. + +Los puntos 1 y 2 son de skill (puro contenido, los podés agregar ya). Los puntos 3–6 son de herramienta. Si tuviera que elegir **uno solo**: el #1, porque es lo que separa "tengo unas redes" de "tengo el informe que pedí". + +--- + +*Documento generado como retroalimentación de uso real. Sin datos personales del usuario. Los dos temas de investigación (EoS para gases / para electrolitos) son de dominio público en ingeniería química y no sensibles.* diff --git a/docs/Notas/24-referente-snowballing-comparacion.md b/docs/Notas/24-referente-snowballing-comparacion.md new file mode 100644 index 0000000..e83fb67 --- /dev/null +++ b/docs/Notas/24-referente-snowballing-comparacion.md @@ -0,0 +1,78 @@ +# 24 — Referente: `snowballing` (JoaoFelipe) vs bib2graph + +> Nota de exploración. El PO trajo https://github.com/JoaoFelipe/snowballing como +> posible "algo parecido a lo que queremos". Capturo el cotejo para no perderlo; +> lo accionable está al final. + +## Qué es snowballing + +Herramienta de João Felipe Pimentel (misma línea de `noWorkflow`) para acompañar +**revisiones sistemáticas con la metodología de snowballing de Wohlin (2014)**: +backward (referencias) + forward (citantes), con humano en el loop y procedencia. + +- **Fuente:** scraping de **Google Scholar** (Selenium + plugin de Chrome con botones + BibTeX/Work/Add). +- **"Base de datos":** archivos **`.py` por año** (la BD es código Python que se importa). +- **Interfaz:** **Jupyter notebooks** con widgets (pasos de snowballing, inserción de + citas, análisis); CLI mínimo (`snowballing start|plugin|web`). +- **Modelo:** objeto `Work` con atributos configurables (perfil "default" con nombres + propios `name`/`place1`, perfil "bibtex" con nombres estándar + `_category`/`_due`). +- **Salidas:** grafos de citación, histogramas de venue, **vista de procedencia del + snowballing** (PROV / ProvToolBox), validación de la BD contra Scholar, + `PDFReferencesExtractor` (refs desde PDF). +- **IA:** no usa. + +## En qué se parece + +El *qué* es casi idéntico: **forrajeo por citas**. Su backward/forward = nuestro +`b2g chain`. Ambos: crecen de una semilla siguiendo el grafo de citas, distinguen +sembrado de traído (`is_seed`), tienen curación humana, y cierran con procedencia + +redes de citación como salida. + +## En qué difiere (y por qué confirma nuestros ADRs) + +| | snowballing | bib2graph | +|---|---|---| +| Fuente | scraping Google Scholar | OpenAlex API (ADR 0007) | +| "BD" | `.py` por año | tabla Arrow + DuckDB biblioteca viva (ADR 0009) | +| Interfaz | Jupyter notebooks + plugin | CLI agente-native (Hito 6) | +| Modelo | `Work` configurable, 2 perfiles | `PaperRow` único (Pydantic) → schema Arrow | +| Determinismo | acoplado a notebook + scraping (frágil) | núcleo puro, `corpus_hash` estable | +| IA | no | no, **por diseño** (ADR 0022) | + +Lectura clave: snowballing es casi un **espejo de nuestra v0** (BD-como-archivos-Python, +acoplado al notebook, scraping de Scholar). Es justo de lo que se alejó la reescritura +clean-room (`01-lecciones-v0.md`). Paga en fragilidad/no-reproducibilidad lo que nosotros +cuidamos → valida OpenAlex + núcleo puro + CLI. Encaja con la frontera motor/producto: +ellos mezclan motor + UX en el notebook; nosotros separamos. + +## Qué nos puede enseñar (accionable, sin compromiso) + +1. **Anclaje metodológico explícito.** Ellos dicen "snowballing de Wohlin" — método de + SLR **citable**, con criterios de inicio/parada. Nuestro forrajeo es más rico + (scent, redes múltiples) pero framed en lenguaje propio. Para el mensaje "antídoto al + sesgo del related work" (#187) y el académico hispano, nombrar el linaje — + *"snowballing de Wohlin, hecho determinista y a escala"* — baja la barrera de adopción. + → candidato a entrar en el posicionamiento de lanzamiento. + +2. **Vista de procedencia del snowballing en la GUI (#34).** Ya tenemos los datos —y más: + `ProvenanceEvent`, `chaining_hop`, `source_tag`, `is_seed`. Ellos lo *muestran* + ("este paper entró en la ronda 2, backward desde tal semilla"). Lectura barata para la + GUI porque el dato ya existe. + +3. **`validate` contra la fuente.** Tienen un paso de validar la BD contra Scholar. No + tenemos un `b2g validate` que re-confronte el corpus vivo contra OpenAlex. Idea suelta. + +4. **Refs desde PDF** (`PDFReferencesExtractor`). Nuestro backward depende de la cobertura + de OpenAlex; refs-desde-PDF es un fallback que ellos tienen. Anotarlo como **límite + conocido del backbone**, no como trabajo a hacer. + +5. **Doble perfil de nombres del `Work`** — tensión "vocabulario del dominio vs del + usuario", que resolvimos con `PaperRow` único. Confirma la elección, no la cambia. + +## Síntesis + +snowballing **valida la tesis** (forrajeo por citas = wedge real y publicable) y a la vez +es el **contraejemplo arquitectónico** que justifica nuestros ADRs. Lo de verdad +accionable: (1) anclaje a Wohlin para el mensaje, (2) vista de procedencia en la GUI. +El resto queda anotado como referencia/límites. diff --git a/docs/Notas/25-multiproveedor-requerimientos.md b/docs/Notas/25-multiproveedor-requerimientos.md new file mode 100644 index 0000000..4204207 --- /dev/null +++ b/docs/Notas/25-multiproveedor-requerimientos.md @@ -0,0 +1,231 @@ +# 25 — Soporte multi-proveedor: requerimientos para delimitar candidatos + +> **Nota de exploración / encuadre.** Fecha: 2026-06-30. El PO trae una dirección que ya +> piden los usuarios: **no depender solo de OpenAlex** (Semantic Scholar, CrossRef, …) y, +> en lo posible, abrir cobertura al **Sur global** (Latinoamérica, África, Asia), +> priorizando **español / inglés** (el producto es principalmente para hispanohablantes). +> +> El pedido explícito es **lo primero, extraer requerimientos** que nos ayuden a delimitar +> qué proveedores entran y cuáles no. Esta nota hace eso y deja una primera criba de +> candidatos *a verificar*. No decide nada todavía — lo accionable está al final. + +## Tesis + +Depender solo de OpenAlex es un **punto único de falla** en tres dimensiones a la vez: +cobertura (qué papers existen para el motor), disponibilidad (si OpenAlex se cae o cambia +términos, el ciclo entero se cae) y **misión** (OpenAlex cubre mal mucho del Sur global y +de la producción en español). Abrir proveedores no es solo robustez técnica: es alinear la +herramienta con para quién es. + +**La buena noticia (del mapeo de código):** el motor ya está preparado. Existe un +`Protocol Source` (`src/bib2graph/sources/base.py:39`) con dos métodos —`seed(query)` y +`load(path)`— y dos implementaciones (`OpenAlexSource`, `BibtexSource`). La **identidad +canónica es DOI-first** (ADR 0036: precedencia `doi > source_id > título+año`, +`corpus.py:54`). Y la arquitectura separa **Source / Enricher / Forager**. Esto define el +encuadre de los requerimientos: **no son una lista plana; son lo que un proveedor debe +cumplir según el ROL que vaya a jugar.** + +## El contrato que un proveedor debe poder llenar (anclado al código) + +| Pieza del motor | Qué exige del proveedor | Dónde vive | +|---|---|---| +| `Source.seed(query)` | búsqueda por ecuación → papers | `sources/base.py:39` | +| Schema canónico (mín. ADR 0018) | `title`, `year`, `authors_raw`, `keywords_raw` (el `id` se calcula) | `schemas.py:130`, `base.py:46` | +| Identidad / dedup (ADR 0036) | **DOI** (ideal) u otro id estable resoluble | `corpus.py:54` | +| Backward chaining | referencias salientes (`references_id` inline) | `forager.py:136` | +| Forward chaining | citantes en lote (`fetch_citing_batch`-equivalente) | `openalex.py:996` | +| Enricher (opcional) | resolver `DOI → metadatos / refs` por lote | `enrichers/openalex.py` | + +## Los tres roles que puede jugar un proveedor + +Como el motor ya separa Source / Enricher / Forager, **un proveedor no tiene que hacer +todo**. Esto agranda el universo de candidatos y simplifica los adaptadores: + +1. **Sembrador / buscador** — sabe responder una ecuación de búsqueda. Alimenta la *Puerta + A* (ecuación → corpus). Requiere endpoint de search con filtros. +2. **Forrajeador (grafo de citas)** — expone referencias y/o citantes. Es el **corazón del + producto** (`b2g chain`). Un proveedor sin citas NO puede forrajear. +3. **Enriquecedor / resolución** — dado un DOI/ID devuelve metadatos o refs. No necesita + search ni grafo; sirve para rellenar huecos y para la resolución `DOI → ID` de la + Puerta B (BibTeX/RIS). + +Un mismo proveedor puede cubrir varios roles (OpenAlex cubre los tres). Otros solo uno +(CrossRef es fuerte en resolución y refs salientes, débil en citantes). + +## Requerimientos (criterios de criba) + +Marcados **[MUST]** (sin esto no entra), **[SHOULD]** (lo queremos, negociable según rol) y +**[NICE]** (suma, no decide). Un proveedor se evalúa **contra el rol** que aspira a cubrir. + +### Eje A — Acceso y licencia (gating duro) + +- **A1 [MUST]** API HTTP pública y documentada. **No scraping.** (Esto descarta Google + Scholar de entrada — ver Nota 24: la fragilidad del scraping es justo de lo que huimos.) +- **A2 [MUST]** Gratuita para uso académico. **Registro / API key está OK**; lo que no + entra es de pago obligatorio o muro institucional. +- **A3 [MUST]** Términos que **permitan almacenar y derivar** los metadatos: la biblioteca + viva los guarda y el grafo es un derivado. Ideal licencia abierta de los datos (CC0, + como OpenAlex y CrossRef). Verificar caso por caso. +- **A4 [SHOULD]** Cuotas compatibles con forrajeo (polite pool o rate limit razonable; no + límites que hagan inviable expandir una red de cientos de papers). + +### Eje B — Encaje con el motor (el contrato Source) + +- **B1 [MUST]** Provee los campos mínimos del schema (ADR 0018): `title`, `year`, + `authors_raw`, `keywords_raw`. +- **B2 [MUST]** **DOI** u otro identificador estable y resoluble, para que la identidad + canónica DOI-first deduplique cross-proveedor sin trabajo extra. +- **B3 [SHOULD, según rol]** Búsqueda por query con filtros (necesario para rol + *sembrador*; prescindible si solo enriquece). +- **B4 [SHOULD fuerte]** **Grafo de citas**: referencias salientes (backward) y/o citantes + (forward). Es lo que separa un proveedor *útil para el producto* de uno que solo + engorda metadatos. Sin esto, el proveedor queda relegado a enriquecer. +- **B5 [NICE]** Lookup por **lista de IDs / batching** (para materializar y para citantes + en lote ≤~50). Sin batching el forrajeo es lento pero posible. + +### Eje C — Cobertura y misión (Sur global · idioma) + +- **C1 [SHOULD]** Cobertura **real** de LatAm / África / Asia, o de un dominio/idioma que + OpenAlex cubre mal. Aquí pesan SciELO, Redalyc, La Referencia, DOAJ. +- **C2 [SHOULD]** Indexa **español / inglés** (alineado con el público hispano). +- **C3 [MUST de valor]** **Valor marginal**: que aporte papers o citas que OpenAlex **no** + tiene. Si solo replica a OpenAlex, no justifica la complejidad de un adaptador nuevo. + (Criterio anti-over-engineering: cada proveedor paga su costo de mantenimiento.) + +### Eje D — Operabilidad y sostenibilidad + +- **D1 [SHOULD]** Gobernanza estable detrás (institución, no proyecto que muere en un año). +- **D2 [SHOULD]** Rate limits documentados, paginación (cursor), polite pool / key opcional + inyectable sin default literal (coherente con ADR 0012). +- **D3 [MUST]** Respuesta parseable (JSON). Mapeo JSON→fila razonable. +- **D4 [NICE]** Bajo costo de adaptador: ¿hace falta traducir la ecuación de búsqueda? + ¿cuánta lógica defensiva? (OpenAlex pidió un traductor WoS→OpenAlex no trivial.) + +## Primera criba de candidatos (PRELIMINAR — a verificar) + +> ⚠️ Tabla de trabajo. Las capacidades exactas de cada API (rate limits, presencia de +> citantes vs solo refs, licencia precisa) **hay que verificarlas** antes de decidir. +> Marco rol probable y banderas, no afirmo hechos cerrados. + +| Proveedor | Rol probable | Citas (fwd/back) | Sur global / idioma | Bandera a verificar | +|---|---|---|---|---| +| **Semantic Scholar (S2 Academic Graph)** | sembrador + forrajeador | refs **y** citantes (fuerte) | global, fuerte en CS/inglés | key gratuita opcional; cobertura ES | +| **CrossRef** | resolución + sembrador | refs salientes (~depende del editor); **sin citantes** | global vía editores; ES si el editor deposita | forward citations las da OpenCitations, no CrossRef | +| **OpenCitations (COCI/INDEX)** | forrajeador puro | citas DOI→DOI, CC0 | global (lo que esté en COCI) | solo capa de citas; sin metadatos ni search | +| **DOAJ** | sembrador (OA) | no es grafo de citas | **fuerte OA Sur global / ES** | API de metadatos; ¿refs? | +| **SciELO** | sembrador + cobertura | citas limitadas | **núcleo Iberoamérica ES/PT** | madurez/forma de la API (ArticleMeta/OAI) | +| **Redalyc** | cobertura | limitado | **LatAm ES** | ¿API real o solo portal? | +| **La Referencia** | cobertura (agregador) | no | **LatAm, repositorios** | OAI-PMH, granularidad de metadatos | +| **CORE / BASE** | cobertura OA (agregadores) | no | global OA | calidad/dedup de metadatos | +| **Europe PMC** | sembrador + forrajeador (biomed) | refs y citas | global, biomed | dominio acotado a biomedicina | + +**Lectura de la criba:** ningún proveedor único reemplaza a OpenAlex. El patrón natural es +**composición por rol**: S2 como segundo backbone con citas; CrossRef + OpenCitations como +par resolución+citas; y una **capa Sur global** (SciELO / DOAJ / La Referencia) que aporta +cobertura ES aunque sea pobre en grafo de citas. Esto encaja con la separación +Source/Enricher que ya existe. + +## Verificación empírica (probe del 2026-06-30) + +> Golpeamos las APIs reales con un script (`examples/multiproveedor-probe/probe_apis.py`, +> resultados en `RESULTS.md`). Esto **sustituye conjeturas por HTTP real** en varias filas +> de la criba de arriba. Una llamada por capacidad; no exhaustivo. + +- **Semantic Scholar** — el **grafo de citas funciona sin key**: `references`, `citations` + (forward) y `batch` → HTTP 200. Pero `search` dio **429 sostenido** aun con backoff + exponencial (4 intentos, hasta 8 s). ⇒ **forrajeador hoy sin credencial; sembrador exige + la API key gratuita**. Confirma el 2º backbone, con ese matiz operativo. +- **CrossRef** — search ✓, DOI nativo, **85 referencias depositadas**; forward es solo un + *conteo* (`is-referenced-by-count=207`), no la lista. Confirmado: sembrador + refs + + resolución, **sin citantes**. +- **OpenCitations** — citantes **n=208**, refs **n=72**, CC0. Completa el forward que a + CrossRef le falta. El par CrossRef+OpenCitations cubre resolución + grafo completo. +- **DOAJ** — búsqueda en español ✓ (artículos **ES/PT**), pero **DOI solo ~1/3** de la + primera página. Cobertura hispana real; dedup DOI-first parcial. +- **SciELO (ArticleMeta)** — el endpoint **no es búsqueda full-text** (lista PIDs por + colección); el artículo de muestra sin DOI. Sirve por otra puerta (cosecha OAI), no para + *seed* por ecuación vía este endpoint. + +**Veredicto empírico del 2º slot Sur-global: DOAJ > SciELO** — DOAJ tiene búsqueda JSON +real que devuelve contenido ES/PT; SciELO-ArticleMeta es cosecha masiva, no seeding por +ecuación. (Re-probar SciELO por su Search API / OAI si se lo prioriza luego.) + +## Verificación documental (deep-research citado, 2026-06-30) + +> Un `deep-research` con verificación adversarial (24 fuentes, 22 claims confirmados) +> corroboró capacidades **con cita oficial** y corrigió dos cosas del probe. **Confianza:** +> lo de S2 pasó verificación 3-0; lo de DOAJ/SciELO/CrossRef viene de fuente primaria pero el +> corte de presupuesto lo dejó fuera del voto final → *reconfirmar antes de implementar*. +> +> **Nota de alcance:** la licencia de los *datos* de un proveedor es problema del **consumidor** +> (Atalaya / el producto), **no de bib2graph**. El motor es determinista y agnóstico a la fuente; +> solo le importa el contrato técnico (`Source`). Por eso esta nota no evalúa licencias de datos +> como criterio de inclusión del motor. + +**Correcciones al probe:** +- **SciELO SÍ tiene citantes:** servicio `CitedBy` (REST, forward por DOI/título/SciELO-ID, + `github.com/scieloorg/citedby`, BSD-2) + `ArticleMeta` para metadatos. Mi probe la + subvaloró por golpear solo ArticleMeta-identifiers. +- **DOAJ:** API pública gratuita; key solo para editores que cargan datos → *seed/search sin + key*. Buena cobertura OA hispana (ES/PT). +- **CrossRef:** public pool gratis sin registro (5 req/s registros · 1 req/s listas, conc. 1); + **polite pool** con `mailto` sube límites. Sin citantes forward (confirmado: solo conteo). + +## Matriz de decisión consolidada (probe empírico + deep-research) + +| Proveedor | Acceso | Sembrar | Refs (back) | Citantes (fwd) | DOI | Cobertura ES / Sur | Rol recomendado | +|---|---|---|---|---|---|---|---| +| **OpenAlex** (baseline) | gratis | ✓ | ✓ | ✓ | ✓ | media | backbone (sigue) | +| **Semantic Scholar** | gratis; key gratis p/ search | ✓ (key) | ✓ | ✓ | ✓ | **sin verificar** | **2º backbone (a implementar)** | +| **CrossRef** | gratis, polite pool | ✓ | ✓ (depositadas) | ✗ (solo conteo) | ✓ nativo | vía editores | resolución + refs (roadmap) | +| **OpenCitations** | gratis | ✗ | ✓ | ✓ (DOI→DOI) | ✓ | global | forrajeador, par de CrossRef | +| **DOAJ** | gratis (sin key p/ search) | ✓ (ES/PT) | ✗ | ✗ | parcial (~1/3) | **fuerte OA hispana** | **1ª Sur-global del piloto** | +| **SciELO** | gratis (ArticleMeta+CitedBy) | parcial (no full-text search) | ? | ✓ (CitedBy) | parcial | **núcleo Iberoamérica** | Sur-global alternativa | + +**Recomendación del piloto:** **S2** (2º backbone) **+ DOAJ** (1ª Sur-global: búsqueda real en +ES/PT). SciELO queda como alternativa fuerte si se prioriza grafo de citas iberoamericano +(tiene `CitedBy`) sobre facilidad de búsqueda. + +## Tensiones honestas (para el PO, no se deciden acá) + +1. **¿Cuántos proveedores y en qué orden?** Cada adaptador es código a mantener (C3, D4). + Recomendación tentativa: **S2 primero** (cubre los tres roles, es el pedido más fuerte + de usuarios y suma citas), y **una sola** fuente Sur-global de prueba — **DOAJ** según + el probe empírico — para validar el eje misión antes de invertir en varias. +2. **Conflicto y merge cross-proveedor.** Si el mismo paper viene de OpenAlex y S2 con + metadatos distintos, ¿quién gana? La identidad DOI-first colapsa el `id`, pero el + *merge de campos* necesita política (precedencia por fuente, o último que escribe). + Probable **ADR nuevo** (toca contrato de corpus / `normalize_and_dedup`, ADR 0031). +3. **Proveedor sin DOI** (mucho del Sur global). Cae al fallback `título+año`, más frágil + para dedup. ¿Aceptamos ruido de identidad a cambio de cobertura? Decisión de producto. +4. **Selección de proveedor por comando.** ¿`b2g seed --source s2`? ¿multi-fuente en una + corrida? ¿default configurable por workspace? Es superficie CLI nueva — encuadrar + contra el ADR de superficie agente-native (0.10.0). +5. **Forward citations sin proveedor que las dé** (caso CrossRef): obliga a emparejar con + OpenCitations. ¿Vale un proveedor que solo sirve emparejado? + +## Accionable (sin compromiso) + +1. **Verificar la criba con datos reales** — capacidades de API, licencia y cobertura ES de + cada candidato (sobre todo S2, CrossRef+OpenCitations y la capa Sur global). Candidato a + un `deep-research` con fuentes citadas; convertir el resultado en una matriz de decisión. +2. **Promover a Discussion** lo que cuaje de esta nota (note-first → Discussion): el debate + de *qué proveedores y en qué orden* vive ahí, no en la nota. +3. **ADRs que esto va a disparar** (anotar, no escribir aún): (a) **merge cross-proveedor** + (precedencia de campos sobre ADR 0031), (b) **selección de proveedor / multi-fuente** en + la superficie CLI. Cambios a contratos públicos → ADR antes de mergear (regla del repo). +4. **Decisión del PO**: **S2 decidido como 2º backbone — a implementar.** Pendiente: alcance + del piloto (recomendado **S2 + DOAJ**) y política para papers sin DOI (tensión 3). +5. **Reconfirmar** las capacidades de DOAJ/SciELO/CrossRef contra docs oficiales (el + deep-research las extrajo de fuente primaria pero no pasaron el voto adversarial final). + +## Síntesis + +El motor **ya tiene la puerta** (`Protocol Source`, identidad DOI-first, separación +Source/Enricher/Forager): agregar proveedores es implementar un contrato conocido, no +rediseñar. Los requerimientos se ordenan **por rol** (sembrar / forrajear / enriquecer) y +por cuatro ejes (acceso, encaje, misión, operabilidad). La criba preliminar dice que **no +hay reemplazo único de OpenAlex**: el camino es **composición por rol**, con S2 como +segundo backbone y una capa Sur-global para la misión hispana. Lo que falta antes de +decidir: **verificar** las APIs candidatas y que el PO fije el alcance del piloto y la +política de identidad sin DOI. diff --git a/docs/Notas/26-retroalimentacion-cli-agent-native.md b/docs/Notas/26-retroalimentacion-cli-agent-native.md new file mode 100644 index 0000000..fdc8169 --- /dev/null +++ b/docs/Notas/26-retroalimentacion-cli-agent-native.md @@ -0,0 +1,262 @@ +# 26 — Retroalimentación: ¿es bib2graph realmente *agent-native*? + +> **Género:** nota de retroalimentación / auditoría (nota primero; no es ADR ni doc +> canónico). Insumo para issues y, si cuaja el rumbo, para un ADR de posicionamiento. +> **Origen:** dos análisis **independientes** del CLI `b2g` contra el *Rubric for +> Agent-Native CLI Design* (los nueve principios del handbook), unificados acá: +> uno del PO y uno de un agente que auditó `src/bib2graph/` con tres barridos +> paralelos. Donde discreparon, se reconcilió **contra el código** (a prueba de `grep`). +> **Para qué:** saber, con evidencia `archivo:línea`, en qué ejes bib2graph es +> agent-native de verdad y cuáles son las tres grietas reales — separando lo que es +> *hueco* de lo que es *decisión de diseño por bajo blast radius*. +> **Auditoría as-built:** sobre `src/bib2graph/` en la rama `chore/retirar-exploracion` +> (estado 0.10.x). Las citas `archivo:línea` se verificaron contra el árbol. +> **Relacionadas:** `23-RETROALIMENTACION_bib2graph_agente.md` (fricción de uso real +> del mismo agente — el "último kilómetro"), `28-marco-software-donde-nos-paramos.md` +> (§2-bis: el Pilar 4 "CLI para agentes" es *fail-open advisory*, no *fail-closed*), +> `27-recibo-de-demo-functor-honesto.md` (el instinto del *functor honesto* que exige +> nombrar dónde el discurso cruza una frontera en silencio). + +--- + +## TL;DR + +bib2graph **es agent-native genuino en los ejes que importan para lo que es**: un CLI +de analítica local, determinista, sin blast radius destructivo multi-tenant. Lo es +**por construcción, no por vocabulario** — el posicionamiento "CLI = API para agentes" +(Nota 28, Pilar 4) se sostiene con `archivo:línea`, no con analogía prestada. + +El rubric pide no sumar los nueve en un puntaje, sino mirar **dónde dos grietas juntas +crean riesgo**. Tres grietas reales, en orden de palanca: + +1. **No hay introspección versionada de la superficie** (principio 9) — el agente que + arranca en frío no puede preguntarle a la herramienta "qué comandos/flags tenés y en + qué versión del contrato estás" por el mismo canal que usa para actuar; tiene que ir a + `docs/API.md` (el *hop* débil). +2. **El error de red no distingue reintentable de no-reintentable** (principio 3) — todo + cae en `NETWORK_ERROR`; es el **único hueco con daño documentado en uso real**: en la + Nota 23 el agente abandonó la CLI y pegó directo contra OpenAlex con `urllib`, + destruyendo la procedencia que es la razón de ser de la herramienta. +3. **Mutación precisa sin fricción** (interacción 8×7/4) — un `curate reject --ids …` + bien formado, self-contained y con exit 0 limpio muta el corpus de forma persistente + sin ninguna fricción ni declaración de blast radius. + +Los principios 4–7 (trust & safety) están **relajados por diseño** y es aceptable: no hay +borrado de recursos, no hay estado compartido, el daño es local y recuperable por snapshot. +El propio rubric lo dice en su *worked example*: un CLI de analítica local no necesita la +misma postura de trust que uno que borra producción. + +--- + +## Los nueve principios + +### I. Legibilidad + +**1. Salida estructurada, no narrada — `Sound`.** +Todo subcomando que devuelve datos expone `--json` vía el decorador compartido +`@json_option` (`cli/_options.py:69-91`), aplicado de forma pareja (`seed.py:388`, +`build.py:621`, `chain.py:345`, `read.py:103/168`, etc.), y emite un envelope versionado +`{schema, ok, command, exit_code, data, warnings, error}` con `ENVELOPE_SCHEMA_VERSION = "1"` +(`service/envelope.py:26`, `build_envelope` en `:29-59`). Se imprime una sola línea JSON con +`ensure_ascii=False` + `flush` — `jq` la consume sin preprocesar; UTF-8 forzado en la +frontera (`cli/__init__.py:82-95`). Sin *drift* por ancho de terminal: el modo humano usa +strings fijos (`emit_human`), no tablas. Único matiz benigno: un grupo sin subcomando +imprime *help* sin envelope (`skill.py:213`), pero eso no es un comando-que-devuelve-datos. + +**2. El contrato tiene una sola forma — `Sound`.** +Una sola flag de salida estructurada (`--json`, declarada una vez en `_options.py:85`); +sin variantes `--output`/`--pretty`. Activación alternativa uniforme por entorno +(`B2G_JSON` truthy, `_options.py:33-46`). Naming consistente: grupos noun-verb +(`read|curate|snapshot `) + verbos planos del ciclo, gobernado por ADR. Las +divergencias son **explícitas y justificadas**: `--format` aparece solo en `export` +(`export.py:123`) porque ahí el formato es del *archivo*, no de la salida del comando; y +`seed` exige exactamente uno de `--equation/--spec/--from-bib` (`seed.py:425-444`) — el +patrón que el rubric pide. La única erosión son 9 aliases deprecados (`inspect`→`read show`, +`enrich`→`chain/build`…) presentes hasta 0.11.0: inconsistencia transicional documentada +(ADR 0038), no incidental. + +**3. Outcome por exit code y taxonomía estable — `Sound`, con un caveat de granularidad.** +Exit codes 0–5 tipados y documentados (`service/errors.py:8-13`, ADR 0021), con función de +mapeo **pura** `code_for(exc)` (`service/errors.py:71-97`) — la política vive en un solo +lugar. 6 `error.code` semánticos (`USAGE_ERROR`, `DATA_ERROR`, `DEPENDENCY_ERROR`, +`NETWORK_ERROR`, `STORE_ERROR`, `B2G_ERROR`); el decorador `@handle_errors` (`cli/_errors.py:91-148`) +garantiza el envelope de error sin duplicar `try/except`. Tres clases de falla son +distinguibles sin leer stderr (uso→1, datos→2, dependencia→3, red→4, store→5). +**El caveat (donde los dos análisis discreparon, reconciliado):** estructuralmente es +`Sound`; pero **dentro** de `NETWORK_ERROR`/exit 4, no se distingue `429` (reintentable con +backoff) de `504`/query-demasiado-compleja (no-reintentable) — todo colapsa al mismo código +(`sources/openalex.py:150`, `cli/_errors.py:140-145`). Es el failure mode literal del +principio ("un retry loop no puede separar transitorio de permanente") y la Nota 23 lo vivió +(Pedido #3). El retry/backoff existe pero es **interno** (`openalex.py:70`, +`_RETRY_STATUS_CODES`), invisible al caller. + +### II. Trust & Safety *(cuadrante de baja relevancia para esta herramienta)* + +**4. Reversibilidad visible antes de comprometer — `Partial`.** +Existe: `chain --preview` es un dry-run real (estima crecimiento sin fetchear ni +transicionar, `chain.py:322-333`); `build` predice redes vacías con `reason`/`fix_command` +accionables (`build.py:312,445`); `curate dump`→`curate apply` es un round-trip offline +reversible mientras no se aplica (`curate.py:139,193`). Falta: no hay `--dry-run` en +`curate filter/accept/reject`, `snapshot create/restore` ni `init`; ninguno muestra +footprint antes de comprometerse. Y la **idempotencia existe pero no se declara**: +`curate apply` y los `Source.persist` son idempotentes (ADR 0009), pero el envelope no +expone `idempotent: bool` que le diga al agente "reintentá sin miedo". Mitigado fuerte por +bajo blast radius: store DuckDB local, sin `delete/reset/purge`, `snapshot restore` como red. + +**5. Secretos fuera del razonamiento — `Sound` en la superficie viva, residuo en el alias deprecado.** +*(Reconciliación de una contradicción entre los dos análisis, resuelta contra el código.)* +No requiere credenciales. La API key de OpenAlex es opcional y, en los comandos **vivos** +(`seed/chain/build`), entra **solo por env var** `OPENALEX_API_KEY` (`openalex.py:413`, +`api_key or os.environ.get(...)`) y viaja en header `Authorization: Bearer` (`openalex.py:431`), +nunca como arg ni en el envelope — el agente no la ve. **El residuo:** `--api-key` como flag +literal existe **solo en el alias deprecado `enrich`** (`enrich.py:102-105`), que se retira +en 0.11.0 (ADR 0038, #165). Es el anti-patrón del principio 5 (key en el contexto del +agente, eco-able por inyección), pero **acotado a una superficie que ya está muriendo**. +El `--email` del polite pool no es secreto (identificador de cortesía). + +**6. Canales de input con distinto peso de confianza — `Partial`.** +Validación mínima y **sin distinción de canal**: `--workspace/--spec/--from-bib/--from-corpus` +se tratan como `click.Path()` y se pasan a `Path(...)`; un valor que el agente rellenó desde +contenido externo se valida igual que una env var puesta por el humano. `click.Path(exists=True)` +valida existencia, no origen ni *path-traversal* (`seed.py:215`); la ecuación solo se valida +no-vacía (`seed.py:90`). Defensa **implícita, no declarada**: el walk-up de workspace tiene +superficie limitada (busca `workspace.json` hacia arriba, `workspace.py:282`), y los inputs +peligrosos (ecuación, CSV de curación) tienen daño ~0 porque OpenAlex sanitiza del lado +servidor y el FS es local single-user. El principio no se aplica, pero el blast radius lo +vuelve tolerable. + +**7. Riesgo escalonado, no plano — `Partial`.** +Hay tiering **funcional** pero no **legible**: lectura sin efecto (`status/validate/read/export`) +< escritura idempotente que transiciona el FSM (`seed/build/snapshot create`) < mutación +transversal persistente que NO transiciona (`curate accept/reject`, `curate.py`) < +irreversible (`snapshot restore` sobrescribe el corpus vivo; `init` sobre carpeta existente +lanza `WorkspaceExistsError` — defensa, no preview). Pero **nada en el contrato agrupa +comandos por blast radius**: no hay `--force`, ni confirmación, ni docstring "this is +destructive"; el lector lo deduce de la prosa. El extremo verdaderamente destructivo del +espectro (borrado) directamente **no existe**, así que la planicie es benigna — coincide con +el hallazgo de la Nota 28 §2-bis: *fail-open advisory* por diseño (ADR 0021). + +### III. Composabilidad & Estabilidad del contrato + +**8. Self-contained, no session-stateful — `Sound`, con un caveat de workspace ambiente.** +Cada comando es invocable en frío: papers por `--id` obligatorio con resolución id>doi>source_id +(`read.py:205`, ADR 0036); `read top` recomputa sin `build` previo (`reads.py:746`); cada +comando devuelve identificadores explícitos en `data` (`seed`→`papers_added/total_papers/round`, +`snapshot create`→`snapshot_dir/corpus_hash`). No hay "opera sobre el último creado"; el canal +entre invocaciones es **el archivo** (`library.duckdb` del workspace), no memoria de sesión — +ésta es la propiedad que hace a `b2g` sobrevivir la compactación de contexto. +**El caveat (donde los dos análisis discreparon):** la identidad del *recurso* es explícita y +`Sound`; pero **cuál workspace** es ambiente — precedencia `--workspace` > `B2G_WORKSPACE` > +walk-up desde cwd (`workspace.py:246-286`). Un agente que cambia de cwd sin flag opera +**silenciosamente sobre otra investigación**. La precedencia está documentada y es +overridable (eso lo deja en `Sound`), pero el modo ambiente es un residuo de estado implícito +que conviene volver **legible** (ver recomendaciones). + +**9. La interfaz se auto-describe y está versionada — `Partial`. (La grieta convergente.)** +La *salida* está versionada: `ENVELOPE_SCHEMA_VERSION = "1"` en cada envelope +(`service/envelope.py:26`) detecta drift de contrato; ADRs 0037–0040 registran cambios de +superficie. **Pero no hay auto-descripción por el mismo canal:** no existe `b2g schema` / +`b2g --describe` que vuelque comandos, flags y el JSON-schema del envelope. El agente que +arranca en frío debe leer `docs/API.md` en prosa — el *hop* extra no confiable que el +principio señala. Además: el shape del envelope está descrito en prosa y duplicado en el +docstring de `build_envelope` (sin JSON-schema publicado), y `--version` muestra la versión +del paquete, no la del contrato. Si la herramienta cambiara `data["papers_added"]` → +`data["n_added"]` sin que SemVer lo marque como breaking, no habría señal mecánica. + +--- + +## Tabla resumen + +| # | Principio | Veredicto | Evidencia ancla | +|---|-----------|-----------|-----------------| +| 1 | Salida estructurada, no narrada | **Sound** | `service/envelope.py:26`; `_options.py:69-91` | +| 2 | Una sola forma de contrato | **Sound** | `_options.py:85`; `seed.py:425-444`; `export.py:123` | +| 3 | Exit codes + taxonomía estable | **Sound** *(caveat: red 429≠504)* | `service/errors.py:71-97`; `openalex.py:150` | +| 4 | Reversibilidad visible | **Partial** | `chain.py:322`; sin dry-run en curate/snapshot/init | +| 5 | Secretos fuera del reasoning | **Sound** (vivo) / residuo deprecado | `openalex.py:413`; `enrich.py:102` | +| 6 | Canales con distinto trust | **Partial** | `seed.py:215`; sin tagging de canal | +| 7 | Riesgo tiered, no plano | **Partial** | tiering funcional sin grading legible; sin `--force` | +| 8 | Comandos self-contained | **Sound** *(caveat: workspace ambiente)* | `read.py:205`; `reads.py:746`; `workspace.py:246-286` | +| 9 | Auto-descripción versionada | **Partial** | `envelope.py:26` sí; sin `b2g schema` | + +--- + +## Interacciones (lo que el rubric pide priorizar) + +No se suma: se mira dónde **dos grietas juntas** crean un riesgo que ninguna sola tiene. + +1. **Sound (8) × Partial (7/4) — fricción ausente sobre acciones precisas.** Un + `curate reject --ids W1 --ids W2 …` es self-contained, sin estado de sesión, con envelope + versionado y exit 0 limpio — *y* muta el corpus de forma persistente, transversal, sin + confirmación. El rubric señala exactamente esto: **la composabilidad que vuelve la + herramienta placentera es lo que quita la fricción natural** que una herramienta menos + componible habría tenido. Bounded porque el daño es local y recuperable (snapshots, + procedencia append-only), pero el patrón está. + +2. **Sound (3) × caveat — el agente rutea alrededor del motor.** La peor interacción por + *consecuencia sistémica*, no por blast radius: `seed/chain` son las únicas operaciones + externas, lentas y falibles. Sin subcódigo reintentable, el agente reintenta a ciegas, y + la Nota 23 documenta el desenlace real — **abandonó la CLI y fue directo a OpenAlex con + `urllib`**, perdiendo la trazabilidad que es la razón de existir de la herramienta. Una + grieta de legibilidad fina (3) hace que el agente rutee alrededor del núcleo determinista. + +3. **Partial (9) × Sound (8) — el agente que arranca en frío.** La auto-descripción faltante + pesa **más** por la composabilidad: un agente puede levantar el tool en cualquier cwd y + orquestar varios comandos, pero no puede verificar programáticamente qué comandos existen, + qué flags aceptan, ni en qué versión del envelope está. Sumado al caveat de workspace + ambiente (8), puede orquestar en frío contra el corpus equivocado sin señal. + +**Lo que NO es problema** (la nota final del rubric): el CLI no toca producción multi-tenant, +no borra recursos remotos, no comparte credenciales. Los principios 4–7 pesan menos que en +una herramienta con blast radius real. Para un agente en una sesión de investigación larga, +la grieta de fondo es **9**: si la herramienta cambia un campo sin bump, el agente no se entera. + +--- + +## Recomendaciones priorizadas (por palanca, corregidas contra el código) + +Tres mejoras de bajo costo, atacando exactamente las interacciones de arriba. El orden es por +palanca real, no por cuál principio "puntúa peor". + +1. **Exponer `b2g schema` — introspección versionada de la superficie** *(cierra P9 + + interacción 3).* Subcomando meta que vuelca: lista de comandos, flags por comando, y el + JSON-schema del envelope actual con su `ENVELOPE_SCHEMA_VERSION`. Misma familia que + `skill add` (comando meta, fuera del ciclo, no transiciona FSM). Permite a un agente + arrancar en frío sin el *hop* a `docs/API.md`. Es la grieta convergente de los dos análisis. + +2. **Subcódigo de error de red `429` vs `504`** *(cierra el caveat de P3 + interacción 2 — la + de daño documentado).* Distinguir en `error.code` (o un `error.subcode`) `RATE_LIMITED` + (429, reintentable con backoff) de `UPSTREAM_TIMEOUT`/`QUERY_TOO_COMPLEX` (504, hay que + simplificar la query). Es el **Pedido #3 de la Nota 23** y el único hueco que demostró + expulsar al agente del motor. Fix chico (`openalex.py:150` ya distingue el status code + internamente), efecto grande. + +3. **Declarar idempotencia y blast radius en el envelope** *(cierra interacción 1 sin agregar + flags).* Agregar al `data` (aditivo, no breaking) `side_effect ∈ {none, transversal, + state_transition, destructive}` e `idempotent: bool` cuando aplique. Le da al agente la + señal que hoy tiene que deducir de la prosa, sin meter confirmación interactiva (que + mataría la autonomía — ADR 0021). Conecta con el "recibo" teorizado en la Nota 27. + +**Nota sobre la credencial (lo que *no* hace falta hacer):** la recomendación intuitiva +"mover `OPENALEX_API_KEY` a env var" **ya está hecha** en la superficie viva +(`openalex.py:413`). El único `--api-key` literal vive en el alias deprecado `enrich` +(`enrich.py:102`), que se retira en 0.11.0 — el footgun de P5 **se cierra solo** con la +deprecación ya planificada. Acción mínima: no re-exponer `--api-key` en los verbos vivos +(y, opcionalmente, adelantar el retiro del flag en `enrich`). + +--- + +## Pendientes (antes de graduar a ADR o abrir trabajo) + +- Decidir si esto justifica un **ADR de posicionamiento** ("bib2graph implementa el contrato + CLI-para-agentes; las grietas 3/8/9 son roadmap explícito, las relajaciones 4–7 son + decisión por blast radius") o si queda como nota-mapa. +- Abrir issues para las tres recomendaciones (candidatos: `b2g schema`, subcódigo de red, + `side_effect`/`idempotent` en envelope). Las tres caben sin romper el contrato de 10 verbos. +- Confirmar que ningún verbo vivo (`seed/chain/build`) re-introduzca `--api-key` al absorber + `enrich` en 0.11.0. + +--- + +*Unificación de dos auditorías independientes (PO + agente) contra el Rubric for Agent-Native +CLI Design. Evidencia `archivo:línea` verificada as-built. Sin datos personales.* diff --git a/docs/Notas/27-recibo-de-demo-functor-honesto.md b/docs/Notas/27-recibo-de-demo-functor-honesto.md new file mode 100644 index 0000000..ada6a11 --- /dev/null +++ b/docs/Notas/27-recibo-de-demo-functor-honesto.md @@ -0,0 +1,200 @@ +# 27 — El recibo de demo: bib2graph como functor honesto, el kernel de juicio mínimo y cómo hacer explícito el one-shot + +> **Fecha:** 2026-06-27. **Estado:** desarrollo de idea (note-first). Disparada por +> la lectura crítica de Evgeny Poberezkin, *"The Future of Software Engineering"* +> (feb-2026) cruzada con el estado real de la superficie CLI 0.10.0 +> ([ADR 0037](../decisiones/0037-superficie-cli-10-verbos-ciclo.md), +> [ADR 0038](../decisiones/0038-destino-verbos-huerfanos-0037.md)). +> +> **Tesis:** el artículo describe un futuro donde el software se "compila" por una +> cadena de functores (propósito → capacidad → diseño → código → deploy) y aposta a +> que eso requiere un *Artificial Intellect* que todavía no existe. **bib2graph ya +> tiene tres de las piezas de ese compilador funcionando en `dev`** —el ciclo como +> functor chain, `status` como verificador determinista en la frontera, y `maturity` +> como recibo— y **no necesita AGI para tenerlas, porque las apoya en verificación +> determinista, no en cumplimiento probabilístico de un LLM.** El one-shot agents-first +> (intencional, para demo) es el lugar donde esas piezas se podrían volver deshonestas +> —cruzar fronteras en silencio— y el trabajo es hacerlo **explícito**: que el demo +> deje recibo de lo que asumió. Engancha con la [Nota 05](05-ciclo-investigacion-humano.md) +> (fundamentación del ciclo) y la [Nota 20](20_ciclo_investigacion_hallazgos_teoricos.md) +> (hallazgos del corpus). + +--- + +## 0. El disparador + +El artículo de Poberezkin hace una apuesta fuerte y una observación correcta. La +observación: *lo difícil del software siempre fue especificar, no escribir código*; +con LLMs, especificar es **la única parte que sigue requiriendo una persona**. La +apuesta: el software del futuro se "compila" a través de una cadena de **functores** +—transformaciones que preservan estructura entre capas (propósito, capacidad, diseño, +código, criterios de aceptación, deploy)— y si cada functor adyacente es correcto, el +mapeo punta-a-punta es correcto *por un teorema de teoría de categorías, no por +conocimiento empírico*. Pero el artículo condiciona todo a un **AGI hipotético** que +sepa "verificar constraints en cada frontera de functor", y descarta los sistemas +actuales por "esconder el problema detrás de retries y orquestación determinista". + +Ahí el artículo se contradice solo: llama *esconder el problema* a la verificación +determinista cuando la usan los LLMs de hoy, y *el futuro* a la misma verificación +determinista cuando la usaría su AGI. **Es la misma arquitectura con dos nombres.** Y +esa contradicción es exactamente la grieta por donde bib2graph entra: el verificador +determinista en la frontera **no requiere AGI, ya está construido.** + +El segundo disparador es una aclaración del PO: el one-shot del ciclo agents-first es +**intencional, y es para demo** —que un LLM pueda correr el ciclo de punta a punta +para *mostrarlo*. Justamente por eso importa que sea **explícito**: un demo honesto no +es el que esconde dónde se saltó el rigor, es el que lo **declara**. + +--- + +## 1. bib2graph ya es el compilador de functores honesto + +El reporte de superficie (2026-06-27) confirma que tres de las seis piezas que el +artículo pone en el futuro ya están en `dev`: + +| Idea del artículo (futuro con AGI) | Pieza en bib2graph hoy | Dónde | +|---|---|---| +| Functor entre capas adyacentes | El ciclo `init→seed→chain→build→read`; cada verbo *es* un functor entre dos capas del ciclo de investigación | [ADR 0037 §verbos](../decisiones/0037-superficie-cli-10-verbos-ciclo.md) (tabla 82-94) | +| Verificación de constraints en la frontera del functor | `status.readiness` + `status.build_preview`: **función pura, determinista, fuente única con los proyectores**; predice si una red saldría vacía *sin proyectar el grafo* y da el `fix_command` exacto | `src/bib2graph/cli/commands/status.py:39-168`, `src/bib2graph/networks/facade.py:437-515` | +| El "recibo" de lo que se compiló y cómo | El bloque `maturity: {curated, scope, empty_networks}` que `build` estampa en el artefacto | [ADR 0037 §f](../decisiones/0037-superficie-cli-10-verbos-ciclo.md), [ADR 0038](../decisiones/0038-destino-verbos-huerfanos-0037.md) (P3) | + +Esto da vuelta el argumento del artículo. Poberezkin necesita un AGI porque cree que +verificar la frontera de un functor requiere *entender*. No requiere entender: requiere +un **predicado determinista sobre el estado del corpus**, que es justo lo que +`predict_build_preview` ya hace cuando dice *"0/15 papers con `keywords_id` → la red de +keywords saldría vacía → `b2g seed --resolve`"*. Eso es el oráculo en la frontera del +functor `chain → build`, y no tiene una sola línea de IA generativa (coherente con el +[ADR 0022](../decisiones/0022-producto-sin-ia-generativa.md)). + +**La consecuencia profunda:** el "moat" del que habla el artículo —cuando la generación +se vuelve commodity, el valor migra al verificador— bib2graph lo tiene del lado correcto. +El verbo que más valor concentra no es el que *genera* (build), es el que *rechaza o +advierte* (status). Esa es la apuesta arquitectónica correcta, y conviene nombrarla +como tal. + +--- + +## 2. La grieta: la verificación es información, no registro + +El reporte trae la frase clave: *"No hay gates programáticos —`status` expone la +información para que el agente decida no avanzar, pero el CLI no bloquea transiciones."* + +Esto es **correcto por diseño** (un gate duro mataría el demo, y mataría la autonomía +del agente que el ADR 0021 quiere preservar). Pero abre un hueco: cuando el one-shot +cruza una frontera en `readiness.ready == False` —porque un demo tiene que correr de +punta a punta sí o sí— ese cruce es **silencioso**. Y "silencioso" es exactamente la +palabra con la que el artículo condena al vibecoding: *el sistema esconde dónde se +rompió el rigor; nadie sabe qué hace más allá de cierto umbral*. + +El antídoto no es poner gates. Es hacer que **el cruce deje cicatriz**. La idea +unificadora: **generalizar el `maturity` block —que ya existe— de "¿se curó?" a un +recibo completo de lo que el one-shot asumió en cada frontera.** Tres campos nuevos, +cada uno aterrizando una tensión distinta del artículo. + +### 2.1 `crossed_red` — fronteras cruzadas en rojo *(verificación → registro)* + +Cada vez que el one-shot avanzó con `status.readiness.ready == False`, se estampa en +el recibo: **qué frontera** (p. ej. `chain` con 0/N seeds con `source_id`), **qué razón** +daba el readiness, y **qué `fix_command` se ignoró**. No bloquea —deja recibo. Esto +convierte el `readiness` advisory que ya existe en algo **auditable** sin cambiar su +naturaleza: la misma información, pero persistida como hecho del artefacto en vez de +impresa y olvidada. + +> Esto responde directo a la matemática de compliance del artículo (70%→50%→35% por +> nivel de delegación de LLMs). Esa cascada asume *fallas independientes y sin +> verificación entre niveles*. Con un recibo de `crossed_red`, las fronteras dejan de +> ser independientes: cada una declara su estado, y el límite ya no es 0.7ⁿ sino la +> tasa de falsos del verificador determinista —un problema mucho mejor. + +### 2.2 `assumed_judgment` — el kernel de juicio humano que el demo simula + +El one-shot saltea curación (`--scope all`, sin `accept`/`reject`) y elige +pregunta/fuentes por default. Esos son **exactamente** los puntos donde el Product +Owner es irreemplazable según el artículo —la "capa de sabiduría": decidir *qué +construir, para quién, qué trade-off es aceptable*. El error de diseño de casi todos +los sistemas human-in-the-loop es dejar al humano *en todas partes*. El trabajo de +ingeniería es el contrario: **hacer ese kernel lo más chico y crujiente posible**, y +que el demo **declare qué partes de ese kernel simuló**. + +El recibo lista, entonces: *"curación omitida (scope=all); N papers que un humano +probablemente habría revisado [heurística]; pregunta de investigación tomada por +default"*. Con esto, el kernel de juicio mínimo deja de ser un aura inanalizable y se +vuelve **una superficie con tipos**: el conjunto declarado de decisiones que solo un +humano toma, y que el one-shot marca como *simuladas* cuando corre solo. + +> Definir ese conjunto es, además, definir qué significa "Product Owner" en el flujo de +> bib2graph (engancha con [Nota 05](05-ciclo-investigacion-humano.md) y el rol del PO en +> [`/feature-cycle`](../../.claude) ). El humano no aprueba cada paso: responde en las +> fronteras marcadas como `assumed_judgment`. + +### 2.3 `orphans` — trazabilidad río arriba *(el functor de verdad)* + +Un functor "preserva estructura" solo si **nada queda colgando**: cada objeto de una +capa mapea a algo en la adyacente. `build_preview` ya detecta el huérfano **río abajo** +(red que *saldría* vacía). Falta el huérfano **río arriba**: nodos del grafo construido +que no trazan a ninguna seed ni a la pregunta de investigación. En una investigación +real eso es deuda silenciosa; en un demo es **la cicatriz visible de la velocidad**, y +es chequeable determinísticamente sobre el grafo que `build` ya produce. + +Acá el uso honesto de la idea categorial **no es** probar corrección punta-a-punta +(eso es el teatro del artículo, que depende de un `if` —que el sistema *sea* +formalizable como tipo— que nunca se cobra). El uso honesto es la **propagación de +cambios y la detección de huérfanos**: cuando algo cambia río arriba (una seed se +quita, la pregunta se reformula), qué nodos quedan sin sustento. Eso es trazabilidad, +no demostración —y es lo que un grafo de entidades-y-morfismos como el de bib2graph +sabe hacer. + +--- + +## 3. Por qué esto cierra el argumento + +Con los tres campos, **el one-shot deja de competir con el rigor y pasa a +instrumentarlo.** Es el mismo functor chain, corrido con todos los gates en verde por +default, pero que **imprime el recibo** de lo que asumió. Eso lo vuelve una herramienta +de demostración legítima en vez de un truco de vibecoding. + +Y de yapa, da gratis el modo no-demo. El **modo riguroso es el mismo pipeline con +`crossed_red` vacío y `assumed_judgment` resuelto** —porque un humano respondió en cada +frontera marcada. No hay dos arquitecturas (una "demo" y una "seria"): hay una sola, y +el recibo mide *cuánto humano tuvo*. El demo es el extremo `crossed_red = todo, +assumed_judgment = todo`; la investigación pulida es el extremo opuesto; todo lo demás +es un punto intermedio honesto y declarado. + +Esto es, exactamente, lo que el artículo dice que hace falta para que el software del +futuro no sea vibecoding —*"hacer explícito dónde se violan los constraints antes de +que se compongan"*— pero construido sobre lo que ya existe en `dev`, sin esperar al +*Artificial Intellect*. + +--- + +## 4. Qué sigue (no es código todavía) + +Esto es desarrollo de idea. El camino del flujo sería: + +1. **Esta nota** (hecho) — captura el argumento y lo engancha con el corpus teórico. +2. **Discusión / decisión**: si la idea del *recibo de demo* cuaja con el PO, graduar a + **ADR** el contrato del `maturity` extendido — toca [`docs/API.md`](../API.md) (campo + por contrato público), por lo que requiere ADR antes de mergear (regla de CLAUDE.md). + Candidato: extender el §f del ADR 0037 / P3 del ADR 0038 en vez de un ADR nuevo. +3. **Issues** acotados, en este orden de menor a mayor juicio humano involucrado: + - `crossed_red`: registrar cruces de `readiness.ready == False` en `maturity` + (cambio chico, fuente única ya existe en `status.py`). + - `orphans`: predicado determinista de huérfanos río arriba sobre el grafo de `build` + (paralelo a `predict_build_preview` en `facade.py`). + - `assumed_judgment`: lo más delicado —requiere **declarar primero el conjunto + canónico de decisiones-de-PO** (el kernel mínimo) antes de poder marcarlas como + simuladas. Probablemente su propia nota/ADR. + +### Preguntas abiertas + +- **¿`crossed_red` es por-corrida o acumulativo?** Un workspace que corrió el one-shot + y después se curó a mano, ¿borra el recibo o lo versiona? (Relaciona con `snapshot`.) +- **¿El kernel de juicio mínimo es fijo o por-dominio?** ¿"elegir la pregunta" es + siempre PO, o hay investigaciones donde una pregunta-default es aceptable? +- **¿Dónde vive el recibo?** ¿Solo en el artefacto de `build`, o `status` lo expone como + un cuarto campo del envelope (junto a `next_best_action`/`readiness`/`build_preview`) + para que el agente lo lea *antes* de avanzar? +- **Heurística de `assumed_judgment` sin IA**: ¿con qué predicado determinista se marca + "este paper probablemente lo habría rechazado un humano" sin caer en IA generativa + (ADR 0022)? Quizás no se marca el paper, solo se declara *"curación omitida"* y se + deja el juicio afuera. diff --git a/docs/Notas/28-marco-software-donde-nos-paramos.md b/docs/Notas/28-marco-software-donde-nos-paramos.md new file mode 100644 index 0000000..8b2d979 --- /dev/null +++ b/docs/Notas/28-marco-software-donde-nos-paramos.md @@ -0,0 +1,359 @@ +# 28 — El marco de software: dónde nos paramos + +> **Género:** nota de posicionamiento (nota primero; no es ADR ni doc canónico). +> **Origen:** charla PO ↔ agente sobre "unidad de trabajo / ciclo de trabajo" + un +> `/deep-research` con 5 ángulos de búsqueda, fuentes citadas y verificación. +> **Para qué:** saber *dónde nos paramos* y nombrar el marco de software que sostiene a +> bib2graph, más allá del dominio de investigación. Insumo para un futuro ADR/ensayo si cuaja. +> **Auditoría as-built (2026-06-28):** los §2 se contrastaron contra `src/bib2graph/` (el +> ejercicio del *functor honesto* de la Nota 27); el veredicto —qué sostiene el código vs. qué +> estira el vocabulario— vive en el nuevo **§2-bis**. +> **Relacionadas:** `27-recibo-de-demo-functor-honesto.md` (el instinto del functor honesto +> que vigila esta nota), `20_ciclo_investigacion_hallazgos_teoricos.md`, +> `NO-HACER-COMMIT-nota-separacion-alcance-bib2graph.md` (frontera bib2graph ↔ producto), +> `04-direccion-ia-in-the-loop.md`, `07-frontend-tool-for-thought.md`. + +--- + +## TL;DR + +No hay **un** nombre canónico que cubra todo bib2graph: hay **cuatro tradiciones de software +que convergen sobre el mismo principio a distinta granularidad**. El banner más preciso y +defendible: + +> **"Reproducibilidad direccionada por contenido aplicada al trabajo de conocimiento"** +> — en su forma operativa: **un *build system hermético* para la revisión de literatura, con +> núcleo funcional puro y CLI como API para agentes.** + +El principio único que ata las cinco piezas: + +> **transformación determinista (pura) + identidad por hash del contenido (input, transformación, +> entorno) + reuso/invalidación por esa clave.** + +Es, literalmente, lo que afirman Bazel y Nix para el *build* de software. bib2graph **traslada +ese patrón —maduro y formalizado— al artefacto de la revisión bibliográfica**, tomando el +`corpus_hash` como la *derivation/action key* de una revisión. + +Frase de arquitectura para tener a mano: + +> **bib2graph = Functional Core (Arrow puro) → Service Layer neutral de transporte → +> Ports & Adapters para N transportes, con identidad del corpus direccionada por contenido y +> procedencia append-only.** +> FCIS nombra el *centro*; Hexagonal nombra el *borde*; el build hermético nombra la +> *garantía*; "tools for thought determinista" nombra el *propósito*. + +--- + +## 1. El marco unificador (las cuatro tradiciones que convergen) + +Ninguna alcanza sola — y conviene nombrarlas juntas (síntesis de Yevtushenko: los patrones son +"suspiciously similar"; *"Ports and Adapters do not clarify how core is implemented, while +Functional Core - Imperative Shell does not clarify how shell should look like"*): + +- **Functional Core, Imperative Shell** (Bernhardt) → la **naturaleza del centro**: puro, + valor→valor. "Núcleo puro sobre tablas Arrow" es el functional core literal; los DataFrames + Arrow son los *"simple values as boundaries"*. +- **Hexagonal / Ports & Adapters** (Cockburn) → la **forma del borde**: puertos (Protocols: + `Source`/`Store`/`Projector`/`Enricher`) y adaptadores intercambiables. Intent canónico de + Cockburn: *"Allow an application to equally be driven by users, programs, automated test or + batch scripts"* = la promesa "muchos transportes (CLI/API/MCP) sobre el mismo servicio". +- **Build hermético / content-addressing** (Nix, Bazel) → la **garantía**: mismo input ⇒ mismo + output ⇒ mismo hash. +- **Unix-for-agents** (encuadre 2025–2026) → el **vocabulario externo legitimador**: la + herramienta determinista es la *seam* (costura) entre la capa no-determinista (el + planificador/LLM) y la determinista (el ejecutor). + +--- + +## 2. Los 5 pilares + +### Pilar 1 — Arquitectura de núcleo puro (la forma del código) + +- **Autores/obras:** Functional Core, Imperative Shell (Gary Bernhardt, *Boundaries*, SCNA + 2012); Hexagonal / Ports & Adapters (Alistair Cockburn, 2005); Clean/Onion; Repository + + Service Layer + Unit of Work (Percival & Gregory, *Architecture Patterns with Python* / + cosmicpython). +- **Cita ancla:** *"The shell can call the core, but the core cannot call the shell"* (Kenneth + Lange, fiel a Bernhardt). Core = "immutable values and pure functions"; shell = "side-effectful, + imperative stuff". +- **Cómo sostiene a bib2graph:** el motor se testea con valores (Arrow in → Arrow out), **sin + mocks**; los Protocols son los *puertos* en versión Python; el `Store` ≈ Repository/UoW con + log inmutable; la capa `service/` es el Service Layer agnóstico de transporte; "CLI = API para + agentes" es un *primary adapter* cuyo puerto es el protocolo JSON/exit-code. **"Sin IA + generativa" cae por la regla de dependencia:** lo no-determinista es shell/adaptador, nunca core. + +### Pilar 2 — Build systems herméticos (el sustento del determinismo) + +- **Autores/obras:** build hermético (Bazel); gestión funcional de paquetes (Nix, tesis de + Dolstra *"The Purely Functional Software Deployment Model"*); caching causal de pipelines (Koji, + arXiv 1901.01908); caching en experimentos de IR (arXiv 2504.09984); dbt (DAG incremental). +- **Cita ancla:** Bazel — *"a hermetic build system always returns the same output by isolating + the build from changes to the host system"*; y el supuesto que lo habilita (IR 2504.09984): + *"the same input will yield the same output"*. +- **Cómo sostiene a bib2graph:** el `corpus_hash` es **el *store path* de Nix / la *action key* + de Bazel** — identidad por contenido, no por ubicación ni timestamp. **[CALIBRACIÓN as-built + → §2-bis: la *identidad* por contenido es real (`backends/memory.py:65-99`); pero el + *reuso/cache-hit* por esa clave —lo que hace de Bazel/Nix un *build system*— NO está + construido: el código detecta staleness (`is_networks_cache_stale`) y **siempre recomputa**.]** + La frontera hermética + (Protocols, CLI stateless) aísla el efecto del núcleo determinista. **Caveat decisivo (IR):** el + no-determinismo (GPU/LLM) **rompe** el supuesto de pureza que habilita el cache por hash; + mantener el motor determinista *es la condición* para que el direccionamiento por contenido sea + sólido. + +### Pilar 3 — Procedencia e inmutabilidad (identidad ≠ tiempo) + +- **Autores/obras:** Datomic / "database as a value" (Rich Hickey); Event Sourcing + CQRS (Greg + Young / Fowler); Merkle DAG y content-addressing (Git, IPFS); W3C PROV (PROV-DM/O/N), con + extensiones ProvONE y ProvCaRe. +- **Cita ancla:** IPFS — *"Any change in a node would alter its identifier and thus affect all + the ascendants in the DAG, essentially creating a different DAG"* y *"two nodes with the same + CID univocally represent exactly the same DAG"*. Datomic: la base "accumulates facts, rather + than updates places, and... the past is immutable". +- **Cómo sostiene a bib2graph:** el `corpus_hash` es **content-addressing Merkle aplicado al + corpus** ("mismo `corpus_hash` ⇒ misma revisión reproducible") — convierte la reproducibilidad + en **propiedad estructural, no en promesa**. La procedencia append-only es Datomic/Event + Sourcing: no se edita, se **acreta**; el workspace en un `corpus_hash` dado es un *valor + inmutable* consultable *as-of*. W3C PROV es el vocabulario para **expresar** esa procedencia + hacia afuera (Entity = registro/nodo, Activity = `enrich`/`project`, Agent = `Source`/`Enricher`). +- **[CALIBRACIÓN as-built → §2-bis]** Tres matices que el código obliga a precisar: (1) el + `corpus_hash` es un **sha256 plano** de la tabla serializada (`backends/memory.py:65-99`) — + *content-addressed*, **no** un Merkle DAG (no hay composición jerárquica de hashes); (2) la + **procedencia** sí es append-only (`_merge_provenance`), pero el **corpus** se **reemplaza** + (`overwrite_corpus`, DELETE+INSERT), no se acreta; (3) **no hay query *as-of***: el "valor + inmutable en un `corpus_hash`" se materializa por **snapshot parquet congelado**, no por viaje + temporal estilo Datomic. +- **[INCIERTO]** el wording exacto de las relaciones PROV (`wasGeneratedBy`, `used`, + `wasDerivedFrom`, `wasAttributedTo`) y la cita literal de Hickey ("a fact... cannot be updated, + only superseded") **no se verificaron contra fuente primaria** — confirmar antes de citar textual. + +### Pilar 4 — Herramientas para agentes (la CLI como contrato) + +- **Autores/obras:** Jim Clark/Docker ("MCP: tools for agents, not API"); Ugo Enyioha (8 + principios de CLI-para-agentes); Anthropic ("Code execution with MCP"); Deepak Babu Piskala + (arXiv 2601.11672, filesystem como sustrato unificador); Jannik Reinhard (CLI vs MCP, eficiencia + de tokens). +- **Cita ancla:** Clark — *"Treat tools as deterministic executors, treat agents as planners and + evaluators"* (reglas: "deterministic, idempotent, fail closed, machine-checkable outcomes"). + Enyioha: *"If a human would use a CLI for it, the agent should too."* +- **Cómo sostiene a bib2graph:** la *seam* determinista/no-determinista de Clark **es** la + frontera bib2graph (ejecutor) ↔ producto-con-IA (planificador). Los principios de Enyioha (JSON + a stdout, exit codes con semántica fija, idempotencia, dry-run) mapean **1:1** con "CLI = API + para agentes" y con el trabajo ya hecho (ADR 0037/0038, `--json` unificado #151/#168): + **bib2graph no sigue una moda, implementa el patrón canónico.** Anthropic respalda "filtrar/ + transformar datos en código determinista antes de que lleguen al modelo" = el núcleo Arrow puro. + Piskala da respaldo académico al "estado durable en archivos" (workspace + `corpus_hash`), no en + la conversación. Reinhard aporta el "determinismo aprendido" (modelos entrenados en miles de + millones de líneas de terminal) y datos de eficiencia (hasta ~35× menos tokens que MCP). + +> **[CALIBRACIÓN as-built → §2-bis]** El mapeo con Clark es 1:1 en **tres** de sus cuatro +> atributos —*deterministic*, *idempotent*, *machine-checkable*— pero **no en *fail closed***: +> el CLI es *fail-open advisory* (`status.readiness` avisa; `cycle.py` permite las transiciones +> igual; ningún comando bloquea). Y **no es un descuido**: es decisión de diseño (un gate duro +> mataría el demo y la autonomía del agente, ADR 0021), con su antídoto ya teorizado en la +> **Nota 27** (el *recibo* `crossed_red` que vuelve cicatriz el cruce silencioso). Además, +> `--dry-run` existe **solo** en `chain --preview`, no como principio genérico del CLI. + +### Pilar 5 — Tools for thought determinista (el propósito) + +- **Autores/obras:** Engelbart ("Augmenting Human Intellect", 1962); Matuschak & Nielsen ("How + can we develop transformative tools for thought?"); Matuschak ("sciences of the artificial" de + Simon); marimo (notebook reactivo como DAG); ASReview LAB v.2 (PMC12416088). +- **Cita ancla:** marimo — *"reproducible by default"*, *"no hidden state"*, *"deterministic + execution"* (vía análisis estático, "possible for us to implement with 100% correctness"). + Matuschak & Nielsen: "insight through making", combinar el **rigor** de la investigación con la + iteración de producto. +- **Cómo sostiene a bib2graph:** ubica a bib2graph en el linaje Engelbart/Matuschak-Nielsen, pero + en la **rama determinista del oficio** — materializa la mitad "rigor" del loop que casi nadie + cierra. **marimo es el isomorfismo técnico directo:** *"reproducible by default, not by + discipline"* es casi literal para el pitch. **ASReview es el "vecino honesto":** comparte + transparencia, procedencia y humano-en-el-centro, pero su núcleo es **ML probabilístico** (active + learning) y por eso solo logra resultados *"identical OR near-identical"*; bib2graph se diferencia + por **determinismo duro garantizado por content-addressing**. + +--- + +## 2-bis. Calibración contra el código (auditoría as-built, 2026-06-28) + +> Antes de que esto cuaje en ADR/ensayo (§7), se auditó el **código real** (`src/bib2graph/`) +> contra las afirmaciones falsables del §2 — el ejercicio que pide la Nota 27 (el *functor +> honesto*): nombrar dónde el discurso cruza una frontera en silencio. **Veredicto: el espinazo +> se sostiene en el código; el vocabulario prestado de Nix/Bazel/Datomic/Clark estira en tres +> puntos.** Esto es lo que hay que decir con precisión para que el ensayo sea a prueba de `grep`. + +| Pilar | As-built | Qué sostiene el código | Dónde el vocabulario estira | +|---|---|---|---| +| **1 — Núcleo puro** | ✅ cumple | regla de dependencia real (el núcleo importa sin `duckdb`/`click`/`fastapi`); funciones puras Arrow→Arrow; `service/` sin transporte; CLI de 3 capas | menor: `Preprocessor` es clase concreta, no `Protocol` (5/6 puertos sí lo son) | +| **2 — Build hermético** | ⚠️ parcial | `corpus_hash` por contenido, excluye timestamps y `resolution` (`backends/memory.py:65-99`) | **no hay reuso/invalidación por la clave**: detecta staleness y avisa, pero **siempre recomputa**. Es un *staleness checker*, no un build system con cache-hit | +| **3 — Procedencia / inmutabilidad** | ⚠️ parcial | procedencia **append-only** real (`_merge_provenance`) | `corpus_hash` = **sha256 plano** (no Merkle DAG); el **corpus se reemplaza** (DELETE+INSERT), solo la procedencia acreta; **no hay `as-of` query**, solo snapshots congelados | +| **4 — CLI para agentes** | ⚠️ mayormente | JSON-stdout puro, exit codes 0–5 tipados, idempotencia, stateless (`service/envelope.py`, `service/errors.py`) | **"fail closed" NO se cumple**: es *fail-open advisory* (`cycle.py` transiciones permisivas). `--dry-run` solo en `chain --preview`, no genérico | +| **5 — Determinista, sin IA generativa** | ✅ cumple | cero imports de LLM; scent bibliométrico determinista; Louvain seedeado del hash; reloj en la frontera | — | + +**Las tres calibraciones para el ensayo (frases defendibles, no aspiracionales):** + +1. **Pilar 2** → "corpus **direccionado por contenido** con **detección de staleness**", no + "build system con reuso". El cache-hit por hash (estilo Bazel/Nix) es **roadmap, no as-built**: + la identidad por contenido es real; el *reuso* por contenido no está construido. +2. **Pilar 3** → "hash **plano** content-addressed" (no Merkle DAG) + "**corpus replace / + procedencia append-only**" (híbrido honesto, no inmutabilidad pura) + "viaje en el tiempo + **por snapshots**, no `as-of` query (no es Datomic)". +3. **Pilar 4** → "ejecutor determinista + idempotente + **verificación *advisory* en la + frontera**", **no** "fail closed". Acá la nota se ata sola con la **Nota 27**: el *fail-open* + **es decisión de diseño** (un gate duro mataría el demo y la autonomía del agente, ADR 0021), + y su antídoto honesto ya está teorizado —el **recibo** (`crossed_red`) que vuelve cicatriz el + cruce silencioso. El marco **ya es consciente de su propia grieta**; solo el Pilar 4 la + enunciaba con demasiada confianza al pegarle el "fail closed" de Clark. + +**Lo que esto NO toca:** el espinazo —Functional Core + determinismo duro + sin IA generativa + +identidad por contenido + CLI-as-API— **es real y verificable con `archivo:línea`**. Es ~80% del +marco y se sostiene. Lo que sobra es analogía prestada que promete máquinas (cache-hit, `as-of` +query, gate duro) que son roadmap o decisión-contraria-deliberada — no as-built. + +--- + +## 3. Prior art y huecos (honesto) + +**Quién está cerca en cada eje:** + +- **Arquitectura (FCIS + Hexagonal + Service Layer):** *cosmicpython* (Percival & Gregory) es la + referencia Python de facto del esqueleto Repository+UoW+Service Layer+Ports&Adapters — lo más + cercano al andamiaje de bib2graph. **Pero su core es un domain model OO (clases ricas), NO un + functional core columnar sobre Arrow.** `ruiconti/cosmic` une FCIS+hexagonal+CQRS+DDD en una + webapp (prueba de concepto de la fusión exacta, pero web/CQRS, no batch determinista ni Arrow). +- **Build hermético / content-addressing:** Nix/Guix y Bazel/Buck tienen el patrón completamente + formalizado, *en software*. En datos/ML: dbt (DAG + incremental + manifest), Koji (1901.01908), + pyterrier-caching/IR (2504.09984). DVC/Pachyderm/lakeFS acercan content-addressing a datasets + **[INCIERTO: no verificados en esta sesión]**. +- **Procedencia inmutable:** Datomic es la implementación canónica de "accretion-only + tiempo + first-class" (DB de propósito general, no open-source, no apunta a reproducibilidad científica). + IPFS/Git/Merkle DAGs: content-addressing maduro a nivel de blobs. ProvONE/ProvCaRe y workflows + científicos (Taverna, VisTrails, Kepler): provenance para reproducibilidad, sobre pipelines + genéricos. +- **CLI-para-agentes:** Claude Code, Cursor y agentes CLI-nativos hacen la filosofía, pero son + agentes de código genéricos, no motores de dominio. `git`/`docker`/`gh`/`jq` son prior art del + *patrón*, no del *contenido*. +- **Tools for thought / dominio bibliométrico:** notas enlazadas (Roam/Obsidian/Tana) sin motor + determinista; notebooks reactivos (marimo, linaje Observable) con motor pero genéricos; revisión + sistemática (ASReview, Rayyan, Covidence) con núcleo ML/manual; mapeo de citas (Connected Papers, + ResearchRabbit, Inciteful, Litmaps) que usan métodos bibliométricos/de red y "generally don't use + language models" **[INCIERTO: vía búsqueda, no fetch directo]**, pero son SaaS cerrados, sin + workspace local durable, sin `corpus_hash`, sin procedencia append-only, exploratorios más que + pipeline reproducible. + +**El hueco que ocupa bib2graph** (consistente en los cinco reportes): nadie combina, +**específicamente para revisión de literatura**, las cuatro propiedades a la vez: + +1. motor **100% determinista** (no ML, no generativo); +2. corpus como **unidad durable direccionada por contenido** (`corpus_hash`); +3. **procedencia append-only** auditable; +4. **CLI como API para agentes** (subprocess/JSON/exit-codes/stateless). + +Cada actor existente cae en una sola canasta: el ecosistema funcional-puro asume OO; el ecosistema +dataframe asume scripts imperativos sin puertos; el mundo PROV tiene el vocabulario pero rara vez +la garantía estructural por hash; Datomic/IPFS tienen la garantía estructural pero no el encuadre +de revisión de literatura; las tools-for-thought son notas (sin motor), notebooks (genéricos) o +revisión con ML (probabilística). + +> **"Make/Nix para una revisión de literatura" — un tools-for-thought determinista bibliométrico — +> está vacante.** No se encontró prior art que lo nombre así. + +**Honestidad sobre lo que NO es nuevo:** el patrón build-hermético, el content-addressing y la +CLI-para-agentes están todos formalizados y maduros *en sus dominios de origen*. **El aporte de +bib2graph es la composición y el traslado de dominio, no la invención de las piezas.** Matiz +narrativo: el discurso 2025-2026 sobre herramientas-para-agentes es **ingenieril** (tokens, +determinismo), **no epistémico**; el ángulo "antídoto al sesgo del related work" (#187) **no +aparece en ninguna fuente** — es diferencial narrativo propio, no respaldo externo. +**[INCIERTO:** si existe un proyecto académico bibliométrico que ya adopte explícitamente el +contrato CLI-para-agentes; no apareció.] + +--- + +## 4. Dónde nos paramos (frases-ancla, precisas y defendibles) + +1. **bib2graph es un *build system hermético para la revisión de literatura*:** el `corpus_hash` + direccionado por contenido es a un corpus lo que el *store path* de Nix o la *action key* de + Bazel son a un build — mismo contenido, mismo grafo, verificable. *(matiz as-built §2-bis: la + **identidad** por contenido es real; el **reuso/cache-hit** por contenido —lo que completa la + analogía con el build— es roadmap, no as-built.)* +2. **El determinismo no es una promesa de proceso sino una propiedad estructural:** porque el + núcleo son funciones puras sobre tablas Arrow, mismo input ⇒ mismo output ⇒ mismo hash. + *"Reproducible by default, not by discipline"* (en el sentido de marimo). +3. **La IA generativa queda fuera del motor por arquitectura, no por preferencia:** lo + no-determinista rompe el supuesto de pureza que habilita el direccionamiento por contenido, así + que el LLM es siempre adaptador/planificador, nunca núcleo (la *seam* de Clark). +4. **La procedencia se acreta, no se sobrescribe:** identidad ≠ tiempo (Datomic/Merkle/Event + Sourcing) — el workspace en un `corpus_hash` dado es un valor inmutable y auditable; siempre se + puede responder "¿de dónde salió este nodo o arista?". *(matiz as-built §2-bis: la + **procedencia** se acreta; el **corpus** se reemplaza; el "valor inmutable" se materializa por + **snapshot**, no por `as-of` query.)* +5. **La CLI es la API:** contrato estable (JSON a stdout, exit codes, idempotencia, stateless) para + que un agente la componga como compone `git` o `docker` — bib2graph implementa el patrón canónico + "tools for agents, not API", no una moda. + +--- + +## 5. Fuentes (consolidadas, por tema) + +**Tema 1 — Arquitectura núcleo puro** +- https://alistair.cockburn.us/hexagonal-architecture +- https://www.destroyallsoftware.com/talks/boundaries +- https://kennethlange.com/functional-core-imperative-shell/ +- https://dev.to/siy/functional-core-with-ports-and-adapters-3m0g +- https://github.com/cosmicpython/book/blob/master/preface.asciidoc +- https://github.com/ruiconti/cosmic +- (`cosmicpython.com/book/preface` → HTTP 403; verificado vía espejo GitHub) + +**Tema 2 — Build systems herméticos** +- https://bazel.build/basics/hermeticity *(leída)* +- https://en.wikipedia.org/wiki/Nix_(package_manager) *(leída)* +- https://arxiv.org/abs/1901.01908 *(abstract leído)* +- https://arxiv.org/html/2504.09984v1 *(leída)* +- https://edolstra.github.io/pubs/phd-thesis.pdf **[INCIERTO: referenciada, no fetcheada]** +- https://www.getdbt.com/blog/data-transformation-in-data-warehouse **[INCIERTO: solo búsqueda]** + +**Tema 3 — Procedencia e inmutabilidad** +- https://vvvvalvalval.github.io/posts/2018-11-12-datomic-event-sourcing-without-the-hassle.html +- https://www.infoq.com/articles/Datomic-Information-Model/ +- https://docs.ipfs.tech/concepts/merkle-dag/ +- https://blogs.ncl.ac.uk/paolomissier/2021/02/07/w3c-prov-some-interesting-extensions-to-the-core-standard/ + +**Tema 4 — Herramientas para agentes** +- https://www.docker.com/blog/mcp-misconceptions-tools-agents-not-api/ +- https://dev.to/uenyioha/writing-cli-tools-that-ai-agents-actually-want-to-use-39no +- https://www.anthropic.com/engineering/code-execution-with-mcp +- https://arxiv.org/html/2601.11672v1 +- https://jannikreinhard.com/2026/02/22/why-cli-tools-are-beating-mcp-for-ai-agents/ +- https://www.eficode.com/blog/unix-principles-guiding-agentic-ai-eternal-wisdom-for-new-innovations **[INCIERTO: no fetcheada en profundidad]** + +**Tema 5 — Tools for thought determinista** +- https://numinous.productions/ttft/ +- https://andymatuschak.org/sdac/ +- https://pmc.ncbi.nlm.nih.gov/articles/PMC12416088/ (ASReview LAB v.2) +- https://marimo.io/blog/dataflow +- https://github.com/marimo-team/marimo +- https://onlinelibrary.wiley.com/doi/10.1111/ijmr.12381 **[INCIERTO: no fetcheada]** +- http://musingsaboutlibrarianship.blogspot.com/2024/06/all-about-citation-chasing-and-tools.html **[INCIERTO: no fetcheada]** + +--- + +## 6. Pendientes de verificación (antes de citar textual o graduar a ADR) + +> El lado **código** de los §2 ya se auditó contra `src/bib2graph/` (2026-06-28) → ver **§2-bis**. +> Lo de abajo son los pendientes **bibliográficos** (citas textuales y prior art). + +- Wording literal de las relaciones **W3C PROV** contra la spec PROV-DM. +- Cita textual de **Hickey** ("a fact... cannot be updated, only superseded") contra la charla + *The Database as a Value*. +- **DVC/Pachyderm/lakeFS** como content-addressing de datasets (no verificados aquí). +- Tesis de **Dolstra** (leer la fuente primaria) y página de **dbt**. +- Que **Connected Papers / ResearchRabbit / Inciteful / Litmaps** "no usan LLM" (vía Aaron Tay, + sin fetch directo). +- Buscar prior art académico bibliométrico que ya adopte el **contrato CLI-para-agentes**. + +--- + +## 7. Próximo paso sugerido (no ejecutado) + +Si esto cuaja como rumbo y no solo como mapa: candidato a **graduar un ADR** que fije el +posicionamiento ("bib2graph = build hermético para revisión de literatura") y/o un ensayo +(Medium) reusando el §4. Antes, cerrar el §6. Nota primero — esto es el mapa, no la decisión.