Saltar a contenido

Changelog

Todos los cambios notables de bib2graph se documentan acá. El formato sigue Keep a Changelog, y este proyecto adopta Semantic Versioning (ver VERSIONING.md).

Este changelog lo gestiona release-please (ya conectado; ver VERSIONING.md y ADR 0006): su PR de release actualiza esta sección desde los Conventional Commits y bumpea pyproject.toml. Al mergear ese PR se crea el tag vX.Y.Z y el GitHub Release. Las secciones por debajo de [0.3.0] son el historial previo a la conexión del tooling (se mantuvieron a mano); de acá en adelante las gestiona el bot.

0.11.0 (2026-07-01)

Features

  • service: resolver público id→DOI/URL (resolve_doi/resolve_url) (#212) (#236) (91ff6b2)

Bug Fixes

  • curate: apply tolera CSV con BOM UTF-8 (Excel-Windows) (#238) (#239) (81d96c7)

Documentation

  • add glossary to close issue #208 completely (219d52d)
  • add glossary to close issue #208 completely (10452f8)
  • add tutorial and guide for documentation improvements (cb1bdfb)
  • add tutorial and guide for documentation improvements (cef4168)
  • add tutorial and guide for documentation improvements (bc6ee77)
  • adr: 0043 posiciona el contrato agent-native del CLI (a25333b)
  • adr: 0043 posiciona el contrato agent-native del CLI (7a12a98)
  • exponer tutoriales y guías en el nav + arreglar enlace roto (4cd2291)
  • exponer tutoriales y guías en el nav + arreglar enlace roto (d363182)
  • fix language and add CLI foundation, remove vendor locking (9619b51)
  • fix language and add CLI foundation, remove vendor locking (cf9d64c)
  • notas: publicar notas 20, 23-28 (renumera recibo a 27, marco a 28) (de87de1)
  • notas: publicar notas 20, 23-28 (renumera recibo a 27, marco a 28) (ebe1069)
  • restructure guides — 5 acotadas vs. 1 monolítica (0add9e6)
  • restructure guides — 5 acotadas vs. 1 monolítica (1f55e94)
  • restructure tutorials — quick start (5min) + complete (3-4h) (bfa7850)
  • restructure tutorials — quick start (5min) + complete (3-4h) (e80bec1)

0.10.2 (2026-06-30)

Bug Fixes

  • sources: error accionable ante 429 de OpenAlex en seed y chaining (#210) (a2a8106)
  • sources: error accionable ante 429 de OpenAlex en seed y chaining (#210) (c05090f)
  • test: idempotencia bit-a-bit pegaba a OpenAlex en vivo (flake en CI) (#219) (de14401)

Performance Improvements

  • stores: upsert masivo Arrow en DuckDBStore.persist (#211) (#226) (08258ee)

0.10.1 (2026-06-30)

Bug Fixes

  • export: escribir CSV en utf-8-sig (BOM) para Excel-Windows (#216) (66339a7)

0.10.0 (2026-06-28)

⚠ BREAKING CHANGES

  • cli: se elimina el subcomando b2g gui y el extra [gui]; el wheel ya no vendorea frontend.

Features

  • build: absorber networks via --spec + --scope/--min-weight + diagnóstico red-vacía (#159) (#169) (c4aee24)
  • chain: absorber monitor como chain --since (forrajeo incremental) (#158) (#176) (6541663)
  • cli: --json unificado por decorador + B2G_JSON env + stdout puro enforced (#151) (#168) (214d230)
  • cli: absorber enrich en chain/build (#162) (#178) (df9fea2)
  • cli: aliases de retrocompat con aviso de deprecación + entry-point bib2graph (#165) (#180) (d4cdf0b)
  • cli: grupo noun-verb read {list,stats,show} absorbiendo inspect (#156) (#170) (d00fe8c)
  • cli: maturity-stamp en artefactos one-shot (build/snapshot/read top) (#160) (#173) (8697144)
  • cli: retirar la GUI local (api/SPA/b2g gui) — fuera del foco de la librería (#197) (fa19291)
  • cli: status como mapa — next_best_action, readiness y preview por-red (ADR 0037 §e) (#153) (726272b)
  • read: read top — centrales + co-citación con título (salida de investigación) (#157) (#171) (b66ac4a)
  • skill: distribuir skill de Claude Code end-user vía b2g skill add (#188) (#192) (29b3f13)
  • skill: salida agéntica explícita en skill add (ruta + cómo opera + leelo) (#194) (9c81be8)

Bug Fixes

  • provenance: persistir manifest.enrichers vía enricher_log (#141) (#198) (c489064)

Performance Improvements

  • test: eliminar build redundante en idempotencia de comunidades (~-24%) (#189) (50a9f68)

Documentation

  • adr: 0037 — superficie CLI 0.10.0 (10 verbos agents-first que mapean el ciclo) (#150) (35099b1)
  • adr: 0038 — destino de los 5 verbos huérfanos del 0037 (10 verbos verificable) (#154) (a8af1e5)
  • alinear docs vivos al presente de v0.10.0 (#191) (#199) (bc36b2c)
  • api: consolidar superficie CLI 0.10.0 + enmiendas ADR 0025/0031/0038 (#166) (#181) (fc7c9b6)
  • notas: Nota 21 — descomposición de la suite de tests para poda (#184) (#185) (272d87c)

0.9.0 (2026-06-25)

Features

  • cli: preview del crecimiento del chaining antes del fetch (#89) (#144) (e89e1ec)
  • networks: cablear assortativity_attribute + composición (#90) (#143) (27fce62)

Bug Fixes

  • provenance: b2g filter registra el filtro (manifest + procedencia) (#126) (#140) (3eb20da)
  • seed: cerrar el backend clonado correcto en reseed (#93) (#142) (d0a3239)

Documentation

  • README install (uv recomendado) + limpieza de AI_DISCLOSURE (#133) (5bb99f9)
  • sincronizar PRD/ARCHITECTURE con el 0.8 (Tier 1 — hechos) (#135) (49ecdbe)

0.8.0 (2026-06-22)

⚠ BREAKING CHANGES

  • core: la columna openalex_id del corpus se renombra a source_id y el id canónico cambia de prefijo oa: a doi:/src:. service/reads.get_paper devuelve source_id (rompe la GUI a propósito, #117). Workspaces legacy necesitan re-key.

Features

  • backends: tabla lateral external_ids (ADR 0036, infra opción C) (#118) (ec55c77)
  • cli: b2g resolve + seed --from-bib --resolve — flujo BibTeX e2e (#110, #112) (#123) (aeda285)
  • core: identidad source-agnóstica — source_id + DOI ancla (ADR 0036) (#119) (4a5d982)
  • networks: keyword_filter en NetworkSpec para sub-redes temáticas (#116) (b58d200), closes #113

Documentation

  • adr: 0036 identidad source-agnóstica (DOI ancla, source_id genérico) (#114) (3777e33)
  • adr: graduar 0035 a Aceptada (ingesta doble puerta + resolución DOI) (#122) (8bd5257)
  • api: sincronizar API.md/ARCHITECTURE con source_id (ADR 0036) (#121) (9d35628)
  • encuadre flujo biblioteca + ADRs 0032-0035 (Propuesta) (#106) (814bd45)
  • notas: 19 — QA del CLI, límites y análisis de superficie (sesión 0.8) (#128) (1fc6d91)
  • notas: sesiones e2e — anomalías ML (14) + hueco capa lectura/análisis (15) (#107) (39dd14d)

0.7.0 (2026-06-18)

Features

  • api: API local FastAPI + b2g gui + service/curate (G3) (6cca1e0)
  • build: wheel incluye el frontend (force-include) + job CI frontend (G5) (f90a0f6)
  • gui: MVP de la GUI local (G1–G5) — capa de servicios + API + frontend + empaquetado (feed3e4)
  • gui: SPA frontend D-2 "Observatorio" + wiring del token (G4) (c40c81d)
  • service: capa de servicios neutral; CLI como adaptador (G1) (e9ea4b7)
  • service: lecturas read-only para la GUI (G2) (fc80c5d)

Bug Fixes

  • build: force-include rompía el editable install sin frontend (.gitkeep) (0ac9c77)
  • gui: GET / devolvía 422 en vez de servir la SPA (9ed70b1)

Documentation

  • api: documentar capa service/ (API.md §0 + AGENTS estructura) (4c57f45)
  • documentar API local (G3 AS-BUILT) (87f3fca)
  • documentar frontend G4 (AS-BUILT) (5d1913e)
  • documentar lecturas service/ (G2 AS-BUILT) (7b57f6a)
  • G5 AS-BUILT + MVP GUI completo (G1–G5) (460d398)
  • gui: preparar terreno GUI — capa de servicios + ADR 0027/0028 + TARGET (#98) (6ff6d20)
  • roadmap: roadmap del MVP GUI (tramo 05, hitos G1–G5) (d73d472)

0.6.0 (2026-06-18)

⚠ BREAKING CHANGES

  • cli: la opción global --store se elimina por completo del CLI. Pasarla produce el error estándar de Click ("No such option: --store"). El modo degenerado (.duckdb suelto sin workspace.json) deja de resolverse: la única unidad de persistencia es la carpeta con workspace.json. Un .duckdb legacy se adopta con b2g init ..

Features

  • cli: eliminar --store y el modo degenerado; workspace única forma canónica (#75) (#85) (a5e46a2)
  • networks: b2g build --corpus-scope (filtrar redes por curación) (#56) (#82) (cb3df4b)
  • preprocess: auto normalize+dedup en ingesta, rapidfuzz core, b2g thesaurus (#88) (#94) (d09aeae)

Bug Fixes

  • curate: --dump excluye semillas; agrega --scope y columnas de revisión (#72, #58, #59) (#81) (daf268c)
  • foraging: backward chaining deja de persistir placeholders fantasma (#54) (#79) (e26ec2b)
  • foraging: forward chaining materializa metadata real (#78) (#80) (ec640d9)

Documentation

  • ejemplo YAML, clusters.csv solo redes de paper, curación auto opt-in; versiona notas 11/13 (#73, #74, #65) (#83) (3e3429e)
  • features: corregir B3 — el scent es bibliométrico (R4), no frecuencia de enlace (#91) (8c8e81b)
  • features: escenarios BDD/Gherkin por historia de usuario (PRD §7) + freshness PRD (#87) (cac4c5f)
  • roadmap: B3 scent — R4 hecho, no pendiente (traza + banner) (#92) (1a53115)
  • sanear coherencia de artefactos de entrada (README, conteos, residuos) (#70) (984edc8)

0.5.0 (2026-06-17)

Features

  • cli: b2g curate — dump + import de curación por CSV (#22, #26) (#44) (04bce5a)
  • cli: equation.yaml cargable (seed --spec) + b2g restore offline (9a, #33) (#51) (23436ef)
  • examples: valoraciones reproducible 100% por CLI (Ciclo B) (#67) (be75b4a)
  • examples: workspace valoraciones + gate de reproducibilidad R2 (9b, cierra #33) (#52) (c7dfba7)
  • foraging: forward chaining batcheado con cap por semilla (#21) (#42) (58a394d)
  • networks: capa declarativa NetworkSpec YAML + b2g networks (Hito 9) (#47) (8d15c24)
  • networks: capa decorate — labels + atributos legibles en nodos (#25) (#43) (9c4597c)
  • networks: tabla de clusters a CSV (#31) (#46) (49cf28b)
  • seed: b2g seed --from-bib + filtro de año real (#50, Ciclo 10) (#53) (f4d3b8a)
  • sources/cli: seed --max-results + negaciones --exclude (#14, #30) (#45) (882e7fa)
  • workspace: snapshot/export por ambiente + aviso de staleness (#32) (#49) (861daa9)
  • workspace: workspace por investigación — b2g init + resolución ambiente (ADR 0029) (#41) (23bf94e)

Bug Fixes

  • sources: filtro --exclude mal-formado en OpenAlex (#30) (#66) (8c9ea88)

Documentation

  • API.md §7.1, ADR 0014 nota AS-BUILT, AGENTS (437), ROADMAP. Cierra #25. (9c4597c)
  • arch: ADR 0029 workspace por investigación (Propuesta) + propagación (#40) (37cce84)
  • mover notas de referencia a docs/Notas/ + gitignore datos de usuario (#27) (87e66a6)
  • notas: commitear Nota 09 (sesión QA — ecología de valoraciones) (#36) (ca43163)
  • notas: explorar frontend tool-for-thought + revisión de referentes (#24) (4f50b95)
  • notas: Nota 10 — tensiones RESUELTAS + mapeo a issues (#35) (0a2cbe8)
  • notas: Nota 12 — encuadre de arquitectura GUI (decisiones A-G propuestas) (#37) (dcee48d)
  • notas: síntesis de contextualización GUI (descomposición 07/08/09) (#28) (e4de811)
  • roadmap: reevaluación pre-GUI — Hitos 1–9 hechos, 10 a la GUI, 11 descartado (#48) (af34a82)

0.4.0 (2026-06-16)

Features

  • enrichers: costura Enricher + resolución references→DOI (Hito 8a) (#10)
  • enrichers: co-citación end-to-end poblando cited_by_id (Hito 8b — completa el Hito 8) (#11)
  • preprocessors: dedup fuzzy determinista con rapidfuzz (Hito 7) (#12)

Bug Fixes

  • ci: fijar release-please target-branch a main (#16) (314774f)

0.3.2 (2026-06-16)

Documentation

  • agents: documentar el flujo GitFlow-lite en AGENTS.md + crear CLAUDE.md (#8) (76254a7)
  • arch: ADR 0024 (orden D3 vía _seq) + saneamiento de coherencia (e6f0e51)
  • contributing: documentar el flujo GitFlow-lite (dev/main) + CI en dev (665988c)
  • contributing: flujo GitFlow-lite (dev/main) + CI en dev (1e17869)

0.3.1 (2026-06-16)

Documentation

  • ROADMAP a carpeta + saneamiento de coherencia y enlaces (82e69c3)
  • ROADMAP a carpeta + saneamiento de coherencia y enlaces (7aa0a4e)

[Unreleased]

[0.3.0] - 2026-06-16

Remediación R1–R5 + cleanup. Cierra la brecha AS-BUILT↔TARGET del red-team (Nota 06): identidad≠procedencia (hash determinista), ciclo de dominio cycle.py, scent bibliométrico sin IA generativa, robustez/hardening, comando monitor. El corpus_hash cambia a propósito (breaking interno) — de ahí el corte v0.3.

Modelo nuevo bloqueado por el PO (2026-06-15) tras el red-team del AS-BUILT v0.2 (Nota 06): el producto no usa IA generativa (ADR 0022); capa base constants/models/schemas única (ADR 0023); enmiendas a 0008/0011/0016/0017/0020/0021. La tanda de remediación R1–R5 del roadmap lo implementa antes de los Hitos 7–11. Esta sección documenta el diseño nuevo; el código se entrega por hito R.

Added (cleanup pre-v0.3 — 2026-06-16)

  • Comando b2g monitor (12° subcomando): re-chequea OpenAlex por citantes nuevos del corpus (forward chaining), mergea los candidatos nuevos a la biblioteca viva y transiciona a MONITORED (paso 8 del ciclo, Ellis). data = {new_candidates, total_papers, loop_state, round}, envelope schema="1"; --email para el polite pool; sin corpus/estado previo → DataError (exit 2). Con esto MONITORED deja de ser inalcanzable (cierra el seguimiento de R3/R5). ADR 0021 (enmienda) / 0016.

Changed (cleanup pre-v0.3 — 2026-06-16)

  • Alias LoopState = CycleState RETIRADO: el código usa solo CycleState (de bib2graph.cycle); se eliminó de backends/duckdb.py y stores/duckdb.py (cierra la recomendación "a retirar pre-1.0" de R3). Una sola clase para el concepto del ciclo.

Fixed (cleanup pre-v0.3 — 2026-06-16)

  • merge de DuckDBBackend ya NO interpola ids crudos en el SQL (footgun de la Nota 06, backends/duckdb.py:417,423): se reemplazó el ... id IN ('<id>',...) ORDER BY CASE id WHEN ... por leer las filas y ordenar en Python por orden de aparición antes de reinsertar. Orden determinista D3 preservado; sin SQL construido con datos. (La alternativa CTE quedó descartada.) ADR 0013 (AS-BUILT).

Changed (modelo / docs — diseño objetivo)

  • El producto NO usa IA generativa (ADR 0022, Hito R4 ✅ 2026-06-16): el information scent del forrajeo deja de ser una heurística de frecuencia de enlace y pasa a scent bibliométrico determinista que consume el primitivo collect_item_to_papers de los proyectores, sin LLM ni embeddings. As-built: backward = fuerza de co-citación con el corpus; forward = fuerza de citación directa al corpus (señal primaria; el AS-BUILT inicial midió acoplamiento puro y degeneraba a 0 con referencias ralas → corregido a citación directa dentro de R4: forward_score(Y) = |{ref ∈ Y.references_id : ref ∈ corpus_ids}|); centralidad diferida. Un solo sentido de "AI-in-the-loop": el desarrollo es asistido por IA; el producto no.
  • Identidad ≠ procedencia (ADR 0017 enmendado, Hito R2 ✅ 2026-06-16): el corpus_hash se computa solo sobre contenido bibliográfico (excluye provenance/timestamps; incluye curation_status); el reloj se inyecta desde la frontera CLI (accept/reject/filter pasan decided_at), con un fallback datetime.now(UTC) para uso como librería (no afecta la identidad); Louvain corre con random_state derivado del content-hash → snapshot reproducible bit a bit. (resolution de Louvain diferido a Hito 9, NetworkSpec.)
  • Ciclo = FSM cíclico de dominio (cycle.py, ADR 0016 enmendado, Hito R3 ✅ 2026-06-16): SEEDED→FORAGED→FILTERED→BUILT→MONITORED con reseed (loop-back a SEEDED + contador de ronda, acumula) de primera clase. El enum de estados sale del backend a bib2graph.cycle (dominio puro; el backend solo persiste — columna round en loop_state_log; alias transicional LoopState = CycleState, a retirar pre-1.0); seed con estado previo se trata como reseed; chain/filter/build derivan su destino de apply_transition (fuente única). Curación transversal visible en b2g status: campos curation_available/round aditivos que mantienen schema="1" (ADR 0021 enmendado). MONITORED está en el modelo, sin comando que lo dispare aún.
  • Capa base de vocabulario + modelos (ADR 0023): constants.py (Col/CurationStatus/ NetworkKind) como fuente única de literales; ProvenanceEvent(BaseModel) con parseo que falla ruidoso; PaperRowCORPUS_SCHEMA de una sola fuente (Hito R1).

Removed (diseño objetivo)

  • explain_candidate, foraging/explain.py y el extra [llm] eliminados (ADR 0022, Hito R4 ✅ 2026-06-16): el producto no usa IA generativa (verificable: el import falla, el extra no está en pyproject.toml).
  • La "máquina de tensiones" (antigua "inserción de IA nº2") se retira del producto —no se difiere a v2, se borra (ADR 0008 enmendado). El fallback semántico/LLM del thesaurus también se retira (ADR 0011 enmendado): el thesaurus es curado y determinista.

Fixed (Hito R5 ✅ 2026-06-16)

  • UTF-8 en la frontera CLI (cli/__init__.py:main_force_utf8()): el envelope --json (ensure_ascii=False) y --help dejan de corromper acentos en Windows cp1252 (Nota 06 RAÍZ 3).
  • Fin del O(n²) en carga: los cuatro loaders (seed/load OpenAlex, BibTeX, Forager) usan el bulk Corpus.from_arrow (+ helper _rows_with_ids) en vez del loop add_paper/_clone que re-upserteaba la tabla entera por fila.
  • fetch_citing con retry/backoff ante 429/5xx (exponential backoff, 3 intentos). (El batching por OR queda diferido —mejora de performance, el N+1 persiste pero ahora es resiliente al rate-limit—; ver ROADMAP Hito R5.)
  • Footguns de la Nota 06 colapsados/eliminados: rama muerta de OSError en _errors.py; except Exception de detect_communities (facade.py) que enmascaraba fallos; param muerto g de cocitation_quality_report; Literal duplicado de NetworkSpec.kindNetworkKind (fuente única).

Changed (cambios de comportamiento — Hito R5 ✅ 2026-06-16)

Endurecen el contrato (la Nota 06 los pidió: "sin no-ops silenciosos"). No tocan schema="1" ni los exit codes externos; sí cambian qué pasa ante entradas inválidas. - Filtros PRISMA LANZAN ante campo/operador desconocido (ValueError accionable). Antes era un no-op silencioso (return True → no filtraba, escondiendo el error). - status/validate ya NO auto-crean el store ante un typo en --store (open_store_readonlyStoreError si el archivo no existe). Antes creaban un .duckdb vacío en silencio. - .bib con error de parseo grave LANZA ValueError; un .bib vacío / con entradas sin título → UserWarning. Antes se tragaba en silencio. - AttributeError ya no se mapea a exit 3 en @handle_errors: la capacidad-de-source-faltante se convierte en DependencyError (exit 3) con un pre-check hasattr en el comando chain; un AttributeError genuino se propaga limpio (no se disfraza de "capacidad no disponible"). - Manifest.lib_version desconocida = "unknown" (antes "0.0.0"): no se inventa una versión falsa que mienta sobre la reproducibilidad.

Tanda de remediación R1–R5 COMPLETA (2026-06-16). Próximo: Hito 7 (deduplicación fuzzy, extra [dedup]).

[0.2.0] - 2026-06-15

Hitos 5 y 6. Forrajeo + CLI agente-native: el flujo seed → chain → filter → build → export corre de una ecuación a un GraphML sin escribir código, sobre la biblioteca viva. v0.2 con capacidades completas del flujo (no del producto: co-citación end-to-end y explain_candidate/[llm] quedan como stubs/futuros). Tag local anotado v0.2.0 (publicación pendiente).

Added

  • Forrajeo (Forager: chaining backward/forward, ranking por information scent = frecuencia de enlace —heurística determinista, no IA/LLM—, preview sin red, filtros PRISMA que marcan rejected, Preprocessor + thesaurus multilingüe). explain_candidate (extra [llm]) es stub. ADR 0008/0011/0020.
  • CLI agente-native b2g (cli/): 11 subcomandos (seed/chain/filter/ accept/reject/build/export/snapshot/status/inspect/validate), envelope --json versionado, exit codes 0–5, --store global sin estado, transiciones LoopState automáticas. ADR 0021.

[0.1.0] - 2026-06-15

Hitos 1–4 (+ rework 1.5). Pipeline mínimo end-to-end: de una ecuación de búsqueda a las redes bibliométricas desde código Python, sobre una biblioteca viva en DuckDB. Tag local anotado v0.1.0 (publicación pendiente).

Added

  • Núcleo Corpus (tabla canónica Arrow + Pydantic v2): identidad estable (id), merge idempotente, accept/reject con provenance (log de eventos), snapshot/CorpusSnapshot con corpus_hash reproducible. ADR 0013.
  • TabularBackend (Protocol) + InMemoryBackend (núcleo puro) y DuckDBBackend (biblioteca viva por defecto: mutación por SQL, LoopState, single-writer); DuckDBStore como fachada de costura. El núcleo no importa duckdb (carga perezosa). ADR 0015/0016/0019.
  • Redes (networks/): proyectores (acoplamiento, co-citación, co-autoría, instituciones, co-word), analizadores (métricas, centralidad, comunidades, asortatividad, calidad), exportadores GraphML/CSV, Networks.quick. ADR 0014.
  • Costuras Source (OpenAlexSource con traducción de ecuación + reporte de límites; BibtexSource, extra [bibtex]). ADR 0007/0012/0017/0018.
  • 2º giro (ADR 0015–0019): Corpus sobre TabularBackend, máquina de estados del lazo (LoopState), reproducibilidad por snapshot sellado, Source agnóstico (mínimo universal vs enriquecimiento), concurrencia single-writer.
  • Migración a uv como gestor del proyecto (lockfile, .python-version, dev-dependencies); docs/decisiones/registro-ia.md (decisiones tomadas por la IA); ADR 0012–0020; reescritura de PRD/ARCHITECTURE/API/ROADMAP/README.

Changed

  • OpenAlex es el backbone de datos (ADR 0007); BibTeX pasa a Source secundaria. Persistencia por defecto: biblioteca viva DuckDB como backend del Corpus (ADR 0009/0015); el snapshot es un export sellado, no el modelo.

Deprecated

  • Snapshot inmutable / InMemoryStore / ParquetStore como persistencia por defecto (premisa de ADR 0003 y de la versión previa de 0006): superados por la biblioteca viva en DuckDB. ParquetStore queda declarado, no implementado.