Este es el primer documento que se consulta cuando se pide “estado del proyecto”. Antes que CHANGELOG, antes que ROADMAP. Lo que está acá es lo próximo a hacer, ordenado por prioridad real (no aspiracional).
Cuando una tarea se cierra, se mueve a CHANGELOG con la entrada formal. No se borra de acá hasta entonces.
📍 Estado al 2026-06-15 (cierre del dĂa) — quĂ© quedĂł despuĂ©s de 15 pushes consecutivos
Si solo vas a leer una sección de este documento cuando volvés al proyecto, leé esta.
Sesión 2026-06-15 cerró 15 pushes consecutivos que terminaron de pagar la deuda post-P5, agregaron 3 redes property-based, alinearon a ANSI un error legacy, y entregaron 2 features SQL-estándar grandes (SAVEPOINT + sessions HTTP).
Lo entregado, agrupado por intenciĂłn:
- CosmĂ©ticos del optimizer: R7 (EXPLAIN P5c sugiere re-ANALYZE), R9 (COUNT DISTINCT sobre JOIN — cierra ADR-0066 Gap 1), R10 (EXPLAIN reconoce PK/Ăndice en USING/NATURAL JOIN).
- Calibraciones: R2 (INDEX_BREAKEVEN 0.20→0.10 con bench data + env var), R3+R3-cont (P5D_SWAP_THRESHOLD instrumentado, sweep inconcluso → 2.0 stays).
- Alineamiento ANSI: UPDATE/DELETE WHERE pk no-existe → 0 filas (no
[GBY-3006]). - Fix de bench: warmup swallow-error + fix OOM (48 GB pre-alloc cartesiano en JOIN — bug pre-existente destapado por R3-cont en CI).
- 3 redes property-based zero-deps (cada una con seed reproducible):
- M3 sobre el planner cost-based (P5c/P5d/R6).
- Pager proptest sobre
begin/commit/rollback+ INTEGRITY CHECK. - M4 fuzz parser — 1h limpia / 503.8M iters / 0 panics (evidencia).
- DiagnĂłstico: M6 (EXPLAIN ANALYZE compara
est.matchvsactualcon clasificación GOOD/MILD/HIGH/MATCH). - TCL SQL-estándar: M12 (SAVEPOINT/ROLLBACK TO/RELEASE ANSI SQL:2003).
- Server HTTP: M13 (sessions cross-request via
X-Gabysql-Session— habilita ORMs).
Suite local: 828 verde + 4 ignored (818 integration + 4 server E2E + 3 planner proptest + 3 pager proptest). CI verde en 5 runners. gabybench all 12.9 min, 71 queries, 0 SKIPs. ADRs activos: 0001–0090.
Lo que viene cuando vuelvas (todos son pushes independientes; los 5 highest-leverage técnicos están cerrados):
- Demo pública de Fase 5 (§6 abajo) — sigue siendo la palanca real para que el repo “sea visto”. El motor está sólido (mejor que nunca); el gateway MCP + vector search + audit con razón semántica son lo distintivo vs. SQLite/Postgres. Requiere repo separado + setup de agente (Claude/Cursor/etc.) — no es 1-push lineal.
- Comparador entre runs de gabybench (§1) — el CI sube
bench/results.jsonpor commit pero no hay diff automático contra baseline. Sin esto, una regresión de 50% en una query no falla el push. ~300 LOC. - M5 — multi-column stats / correlation (§6.5) — resuelve la asunción de independencia AND que R6 mitigó parcialmente. PostgreSQL tiene
CREATE STATISTICSdesde 10. Bump de VERSION, ~600 LOC. - M9 — base table reorder para INNER JOIN chains (§6.5) — hoy P5d solo swap step current. Reorder global requiere refactor de
build_join_scope. ~600 LOC, riesgo medio.
Lo que sigue NO conviene abrir antes: cargo fuzz real en CI Linux (la versiĂłn hand-rolled M4 ya cubre la lĂnea de README; el coverage-guided es nice-to-have de Fase 6). M11 (WAL-mode opt-in) es Fase 6 tambiĂ©n — requiere repensar single-writer.
đź§ Sobre el contexto operativo (leer antes de las prioridades)
Tres cosas que enmarcan toda esta lista. Si las olvido en una próxima conversación, recordármelas.
-
gabysqles uno de varios proyectos en desarrollo paralelo del autor. No es la Ăşnica cosa que compite por tiempo. Las prioridades de este documento aplican cuando se trabaja engabysql, no son un mandato calendárico. No hay “deberĂas estar haciendo X esta semana”; hay “cuando agarres el proyecto, lo siguiente es X”. - Las prioridades acá son recomendaciones tĂ©cnicas, no estratĂ©gicas absolutas. Vienen del análisis del estado del motor + del plan declarado de usarlo en un proyecto comparativo. Pero:
- El mercado/tecnologĂa/uso de DBs cambia de formas que nadie predice. Un proyecto puede tomar tracciĂłn por un tweet, por un caso de uso no anticipado, por estar listo cuando algo más se rompe.
- Una recomendación técnica correcta no implica que ignorar la recomendación sea error. El criterio del autor sobre cuándo arrancar el proyecto comparativo, cuándo hacer público qué, y qué priorizar de la vida en general es de él, no de la lista.
- El orden de la lista puede invalidarse rápido. Disparadores que justifican reordenar sin culpa:
- Aparece interés externo concreto (alguien probó algo, pidió algo).
- El proyecto comparativo se acerca o se aleja en el calendario.
- Una decisión técnica de otro proyecto del repositorio toca cosas que
gabysqltambién necesita. - Sale algo nuevo en el ecosistema (Rust stdlib, MCP spec, modelos LLM accesibles localmente) que cambia el costo de una de las fases.
- Aparece pereza/aburrimiento con una tarea — válido, se salta o se reordena.
🔥 Prioridad alta — recomendaciones técnicas
Vienen del balance honesto del estado actual + del análisis post-Fase 3 (ANALISIS_POST_P5.md). Son las cosas que, si las hacés cuando trabajes en este proyecto, mueven más el dial.
1. Construir gabybench mĂnimo — âś… entregada
gabybench mĂnimoEstado al 2026-06-11: cerrada. Existe como binario src/bin/gabybench.rs, soporta modo all (10 DBs, ~10 min) y modo smoke (microblog+orders_lines, ~1-2 min). CI corre el smoke en cada push y sube bench/results.json como artifact (job bench). Ver ADR-0075.
Lo que falta de esta lĂnea (al 2026-06-15):
R2— âś… entregada (ADR-0081): 0.20 → 0.10 + env var override.R3— âś… cerrada con outcome explĂcito (ADR-0082 + ADR-0085): sweep inconcluso, default 2.0 stays.- Comparador entre runs: el CI sube artifacts pero no hay diff automático contra baseline. Sin esto, una regresiĂłn de 50% en una query no falla el push. ĂšNICA lĂnea pendiente del gabybench original.
2. Cobertura SQL para comparaciones realistas — ✅ entregada
Estado al 2026-05-26: cerrada. JOINs ANSI completos (INNER/LEFT/RIGHT/FULL/CROSS/USING/NATURAL + index-loop optimization) entregados antes de la sesión 2026-05-25; WHERE completo (E1+E2+E3), agregados single-table, DML masivo (J), UPSERT/RETURNING (J2), funciones escalares + aritméticos (G1+G2+G3), subqueries (H), set ops + VALUES (I), DDL extendido (K1+K2) en sesiones 2026-05-25 y 2026-05-26. La superficie SQL operacional clásica está completa.
Pendiente residual (al 2026-06-11):
UPDATE ... FROM— no implementado.EXCLUDED.colen UPSERT — no implementado.— ✅ cerrada 2026-06-15 por R9 (ADR-0079).COUNT(DISTINCT col)sobre JOINORDER BY a, b(multi-col) — descubierto en R8 (2026-06-11): el parser solo acepta single-col.- Ninguno bloquea el proyecto comparativo.
3. Fuzz testing + property tests — âś… entregada en 3 redes (mayorĂa cerrada)
Qué:
— âś… entregada 2026-06-15 (ADR-0087). Hand-rolled (libFuzzer/AFL choca con Windows+GNU+ADR-0001); 1h limpia = 503.8M iters, 0 panics. Evidencia:cargo fuzzsobreparse(...)— 1 hora mĂnima sin panic niunwrapfallidodocs/fuzz/FUZZ-RUN-2026-06-15.md. PrĂłxima mejora:cargo fuzzreal en CI Linux + fuzz sobreexec().— âś… entregada 2026-06-15 (ADR-0086). 3 invariantes (commit visibility, rollback discards, chained tx integrity), ~5100 ops random por corrida.proptestsobre el Pager— âś… entregada 2026-06-15 (ADR-0084). Hand-rolled zero-deps, 240 comparaciones por corrida sobre P5c/P5d/R6.proptestsobre planner- Extender los 3 crash tests sintĂ©ticos actuales a 10+ escenarios. Pendiente.
Por qué importa: SQLite tiene millones de horas de fuzz acumuladas. M4 cierra la primera hora con evidencia citable. M3 + Pager proptest son las redes de seguridad para iterar planner + storage con confianza.
Lo que sigue siendo nice-to-have (no urgente):
cargo fuzzreal en CI Linux (libFuzzer coverage-guided). M4 hand-rolled ya cubre la lĂnea de README; coverage-guided subirĂa el bar.- Fuzz sobre
exec()además deparse(). Costoso por bench. - Extender los 3 crash tests sintéticos actuales a 10+ escenarios.
4. Reparaciones del análisis post-P5 — abiertas
De ANALISIS_POST_P5.md, las que quedan abiertas tras la sesiĂłn 2026-06-11:
| # | Item | Esfuerzo |
|---|---|---|
INDEX_BREAKEVEN con bench data |
— | |
| — | ||
| R5 | TRUNCATE TABLE limpia stats — bloqueado por implementar TRUNCATE como statement | parte de bloque mayor |
| — | ||
COUNT(DISTINCT col) sobre JOIN |
— | |
| — |
Tensiones abiertas tras la sesión 2026-06-15 (de las 9 originales del análisis post-P5):
- 2.6 — RIGHT/FULL JOIN heurĂstica imprecisa en EXPLAIN (documentado en ADR-0073; mitigado parcialmente por R10 sobre USING/NATURAL, pero RIGHT/FULL siguen aproximando).
- 2.9 — P5d swap puede cambiar orden de filas sin ORDER BY (deuda documentada; M3 defiende usando sort en Rust para el test, no resuelve la deuda original).
Las 7 restantes (2.1–2.5, 2.7, 2.8) quedaron cerradas en esta sesión y la anterior.
🟡 Prioridad media — cosas que mueven la aguja del proyecto
5. Re-evaluar el modelo single-writer
QuĂ©: hoy el motor es estrictamente single-writer (Mutex global en server.rs + file lock cross-process). Eso es defendible mientras el proyecto sea de aprendizaje, pero el proyecto comparativo va a sufrir porque cualquier benchmark concurrente da nĂşmeros peores que SQLite (que soporta lectores concurrentes vĂa WAL-mode).
Opciones:
- A: aceptar la limitaciĂłn y elegir benchmarks single-writer. Honesto pero limita la comparativa.
- B: implementar lectores concurrentes con snapshot isolation simple. Requiere repensar el Pager. Es esencialmente parte del WAL-mode de ADR-0018 (Propuesta).
- C: implementar MVCC. Demasiado grande para este momento del proyecto.
Por qué medio y no alto: porque depende del scope que tome el proyecto comparativo. Si vas a comparar OLTP serio, esto es alto. Si vas a comparar features distintivas (vector search, audit, schema rico), esto importa menos.
Esfuerzo: opciĂłn A: 0 (decisiĂłn). OpciĂłn B: 1 ADR + ~600 LOC + tests. OpciĂłn C: rewrite parcial.
6. Demo pĂşblica de Fase 5 (MCP gateway + vector search + audit)
Qué: un repo o gist con un agente Claude/Cursor/etc. usando gabysql-mcp para hacer algo concreto — RAG sobre PDFs, audit log consultable, query asistida — y un README que muestre que funciona.
Por qué importa: para “llamar la atención” eventualmente (la razón por la que el repo es público), la diferenciación real está en el MCP gateway. No en el motor. El motor es decente; el gateway con vector search integrada y audit log con reason semántico es lo que no tiene ninguna otra DB del nicho. Pero hoy nadie ve eso porque no hay una demo simple.
Esfuerzo: 1 intervenciĂłn + setup de un agente real para probarlo. Probablemente un repo separado en GitHub que linkee de vuelta.
6.5 Mejoras del optimizer/stats — del análisis post-P5
Items que NO son reparaciones (no hay nada roto), pero amplĂan lo entregado en la sesiĂłn 2026-06-10/11:
| # | Item | Por qué importa | Esfuerzo |
|---|---|---|---|
| M1 | Auto-ANALYZE (scheduler que dispare cuando la tabla cambia >X%) | Hoy las stats son manuales. R1 detecta stale, pero el usuario tiene que mirar EXPLAIN y actuar. Auto-ANALYZE cierra el loop. | 1 push grande (~600 LOC + jobs infra) |
| — |  | ||
| M5 | Multi-column stats (correlaciĂłn) | Resuelve la asunciĂłn de independencia de P5c. PostgreSQL CREATE STATISTICS. ReemplazarĂa R6 conceptualmente. |
1 push grande (~600 LOC + bump VERSION) |
est.match vs actualactual.bias con clasificaciĂłn GOOD/MILD/HIGH/MATCH para queries scan-only. |
— |  | |
| M7 | Hints SQL (/*+ INDEX(t, idx) */) |
Override per-query del cost model. Estándar en Oracle/MySQL/SQL Server. | 1 push (~400 LOC, requiere parser changes) |
| M8 | Prefix matching sobre composite indexes (WHERE a=X con Ăndice (a,b)) |
Hoy cae a FullScan. Requiere cambio de layout on-disk a lexicographic tuple-bytes. | 1 push grande (~800 LOC + bump VERSION) |
| M9 | Base table reorder para INNER JOIN chains (P5d extendido) | Hoy P5d solo swap el step current. Reorder global requiere refactor de build_join_scope. |
1 push (~600 LOC, riesgo medio) |
| M11 | WAL-mode opt-in (ADR-0018) | Habilita lectores concurrentes. Espacio comparativo serio vs SQLite. | 1 push grande |
| — |  | ||
/tx/{begin,commit,rollback} + /exec con session header. Single-slot global; multi-session diferido a Fase 6 con WAL-mode. |
— |  |
🔵 Prioridad baja — diferido con razón
7. Las fases β–ζ de AGENDA_INVESTIGACION.md
Plan-as-data, schema semántico, embedded variants, time-travel, migration como conversaciĂłn — todo eso sigue siendo el norte conceptual del proyecto, pero viene despuĂ©s de Fase α y de las prioridades altas de este documento. Sin benchmarks y sin cobertura SQL real, esas fases serĂan castillos sobre arena.
Mantener en AGENDA_INVESTIGACION.md como north star. No mover acá hasta que las prioridades altas cierren.
🏛️ Notas de proceso
- Cómo se agrega una tarea: si surge algo durante una intervención que no se puede cerrar en el mismo bloque, va acá antes de cerrar el commit. La idea es que este documento sea el único lugar donde “lo que falta” vive — no en TODOs comentados en el código, no en mensajes sueltos, no en la cabeza.
- CĂłmo se cierra una tarea: cuando la entrega vive en
main, se mueve a CHANGELOG.md con la entrada formal de la intervenciĂłn y se borra de acá. - CĂłmo se reordenan prioridades: cualquier momento, sin justificar. La prioridad alta de hoy puede ser media mañana si el contexto cambia. Los disparadores tĂpicos están en §đź§.
- CĂłmo se vetan recomendaciones: si una tarea acá deja de tener sentido (ej: “ya no voy a hacer el proyecto comparativo, gabybench pierde el motivo principal”), se mueve a una secciĂłn “💤 archivadas” con una lĂnea de por quĂ©. No se borra silencioso — el por-quĂ© del veto es informaciĂłn Ăştil despuĂ©s.
- Cuándo el asistente debe callarse: cuando el aporte de seguir empujando una recomendación es marginal respecto al ruido. Si una conversación entra en loop sobre la misma prioridad, se anota acá como “punto de fricción no resuelto” y se pasa a otra cosa.
đź”— Referencias
- AGENDA_INVESTIGACION.md — el norte conceptual (qué clase de DB queremos entender).
- ROADMAP.md — historial de lo entregado en Fase 1 y Fase 2.
- CHANGELOG.md — entradas formales de cada intervención cerrada.