Strata — Binario standalone strata
Cumple
propuesta-lenguaje-strata.md:49"un solo binario: compilador+LSP+runner". Estado: implementado 2026-09-22 —prototype/strata.spec:1,prototype/strata_entry.py:1,prototype/.github/workflows/binary.yml:1,prototype/dist/strata34M(UPX),prototype/pyproject.toml:7strata-lang==0.1.1.
Resumen
Strata se distribuye en tres formas equivalentes (mismo strata/cli.py:1084 main()):
pip install strata-lang— wheel149Ktwine check PASSED(prototype/pyproject.toml:6)uv tool install strata-lang— atajo 0 costo- Binario standalone
strata—prototype/dist/strata34Mcon UPX (_duckdb.so 58M→34Mcomprimido),venv 143Mtotal. Sin UPX esperado80–120M(prototype/docs-site/guide/binary-standalone.md:7histórico) ghcr.io/tzinny-dev/strata:0.1.1— Docker reproducible (prototype/Dockerfile:1)
El binario ya existe y pasa smoke help/build/compile --dialect postgres/run --seed/bench en binary.yml. Recomendación actual: usar binario para distribución; pip/uv siguen válidos para desarrollo.
1. Bloqueos — estado cerrado (Fase 0)
| Bloqueo | Evidencia | Fix aplicado |
|---|---|---|
fcntl.flock POSIX only | strata/exec.py:11 try: import fcntl / exec.py:166 fallback | Cerrado 5572426: exec.py:11 try/except ImportError + exec.py:173 portalocker fallback + exec.py:190 warning si falta. Windows .exe no crashea (fail-open con warning). |
Path(__file__) y recursos | strata/bench.py:26 Path(__file__).parent.parent / "bench" | Cerrado 5572426: bench.py:33 sys.frozen/_MEIPASS con fallback a source tree. strata.spec:4 datas=[('examples','examples'),('bench','bench'),('LICENSE','.'),('README.md','.')] + collect_data_files('strata'). |
| Imports dinámicos | strata/cli.py:54 import psycopg2, adapters.py:92 __import__ | Cerrado 0cc832c: strata.spec:13 hiddenimports=['duckdb','psycopg2','yaml','strata.adapters','strata.bench','strata.dbcompat','strata.analysis','portalocker']. |
duckdb binario nativo | _duckdb.so 58M | Cerrado 0cc832c: PyInstaller copia .so via collect_data_files; alpine/musl descartado (glibc only). |
information_schema / duckdb_views() | strata/dbcompat.py:92 pg_views | No bloqueó binario; CI binario smoke usa Postgres efímero si psycopg2 disponible (binary.yml no lo exige aún — ver §3). |
2. Herramientas comparadas — decisión tomada
| Tool | Tipo | Pro | Contra | Para Strata |
|---|---|---|---|---|
| PyInstaller | bundle intérprete+zip | Más maduro, hook duckdb existente, 1 comando pyinstaller strata.spec | 90M sin UPX / 34M con UPX, cada OS build nativo, UPX rompe firma macOS | Elegido — implementado 0cc832c |
| Nuitka | Python→C→EXE | Binario 30% más rápido/pequeño, mejor UPX, respeta __file__ | Compila 12k líneas → 15–25 min/build, rompe psycopg2 C-ext sin --include-package-data | Descartado — no necesario con PyInstaller validado |
| PyOxidizer | Rust empaquetador | Single file real, sin _MEIPASS temp | Config Rust, hook duckdb manual, menos doc | Descartado |
| pex / shiv / uv tool | zipapp | No es standalone (requiere python3.12) | No cumple spec literal, pero uv tool install strata ya funciona | Interino vigente para dev |
3. Roadmap — implementado
Fase 0 — Preparación ✅ 5572426
strata/exec.py:11→try: import fcntl+exec.py:173portalockerfallback.strata/bench.py:33→sys.frozen/_MEIPASScon fallback source tree.strata.spec:4datascentralizado;pyproject.toml:53no requierepackage-dataextra (wheel usainclude=strata*, binario usadatas).
Fase 1 — POC PyInstaller ✅ 0cc832c (2 días)
Spec canónico prototype/strata.spec:1 (no CLI ad-hoc):
pip install pyinstaller
pyinstaller strata.spec --noconfirm
./dist/strata --help
./dist/strata build examples/daily_orders.strata
./dist/strata compile examples/daily_orders.strata --dialect postgres
./dist/strata run examples/daily_orders.strata --seed -o /tmp/demo.duckdb
du -sh dist/strata # real 34M UPX, 80–110M sin UPXValidación: dist/strata test examples/daily_orders.strata --seed + bench deben igualar pytest (ver §5 pendiente).
Fase 2 — CI matrix ✅ f88769d (prototype/.github/workflows/binary.yml:1)
Matrix ubuntu/macos/windows (binary.yml:14), setup-python 3.12, pyinstaller strata.spec, smoke help/build/compile/run/bench, upload-artifact por OS, release con attest-build-provenance + softprops/action-gh-release (binary.yml:162).
Tiempo CI 90s → ~270s (×3 OS).
Fase 3 — Hardening ✅ 6dedf62 (parcial)
strata.spec:33upx=True+binary.yml:35upx-uclen ubuntu +sha256sum+ gate>120Mwarn (binary.yml:108).binary.yml:88codesign --sign -ad-hoc (sinDeveloper ID— ver §5 pendiente). Para prod:bashAñadir como# macOS (requiere Apple Developer Program $99/año, secret APPLE_CERT + APPLE_CERT_PASSWORD) security import certificate.p12 -k ~/Library/Keychains/login.keychain codesign --sign "Developer ID Application: Tzinny (TEAMID)" --deep --timestamp --options runtime dist/strata xcrun notarytool submit dist/strata --apple-id "$APPLE_ID" --password "$APPLE_APP_PASSWORD" --team-id "$TEAMID" --wait xcrun stapler staple dist/strata # Windows (EV cert + AzureSignTool/signtool, secret WINDOWS_CERT) signtool sign /fd SHA256 /tr http://timestamp.digicert.com /td SHA256 /f cert.pfx /p "$CERT_PASSWORD" dist/strata.exeif: startsWith(github.ref,'refs/tags/v')steps enbinary.ymlconsecrets.APPLE_CERT/secrets.WINDOWS_CERT.strata/lsp.py:18ya expuesto comostrata lsp(cli.py:50) y empaquetado viacollect_data_files.
4. Costos y riesgos — actualizados
- Tamaño:
58Msolo_duckdb.so→ binario34Mcon UPX (CHANGELOG.md:30),~85Msin UPX.pip+Docker(ghcr.io/tzinny-dev/strata:0.1.1) sigue vigente para CI. - Mantenimiento: cada bump
duckdbopsycopg2-binary(pyproject.toml:24) obliga a rebuild triple + re-firma (automatizado enbinary.ymlontag v*). - WASM/playground
docs/warehouse-adapters.md:69descartado — mismo costo que binario sin demanda probada. - Distribución:
install.sh:1+homebrew/strata-lang.rb:1operativos, pendientes: firma real Developer ID yREPLACE_SHA256automático (ver §5).
5. Decisión tomada + deuda restante
- Hecho 2026-09-22:
PyPI strata-lang 0.1.1+binary.ymlmatrix triple +ghcr.io/tzinny-dev/strata:0.1.1+install.sh+homebrew. - Validar: 5 entrevistas con demo
strata lineage-diff(market/market-validation.md:141) — pendiente producto. - Deuda abierta (no bloquea uso, ver detalle abajo):
- Firma real:
binary.yml:88ad-hoc → requiereAPPLE_CERT/signtoolpara Gatekeeper/SmartScreen (coste99$/año). - Homebrew SHA:
strata-lang.rb:10REPLACE_SHA256manual → automatizar enbinary.yml:release. - Equivalencia binario==pytest: falta gate
dist/strata testvspytest(binary-standalone.md:60histórico). - UPX portabilidad: validar en
ubuntu:20.04(kernel<5.10rompeduckdb). - arm64:
install.sh:33soloamd64→ añadirmacos-14/linux arm64cuando haya demanda.
- Firma real:
Actualizado 2026-09-23. Fuente: prototype/ CHANGELOG.md:25 Fase 0-4 cerrada, dist/strata 34M, pytest 529 tests 83% en 3.12.