feat(minga): multi-lenguaje en parser — Python, TypeScript, JavaScript, Go
Minga deja de ser Rust-only. Cualquiera de los cinco dialectos
(Rust + 4 nuevos) se ingresa al CAS por su AST normalizado, hashea
estructuralmente, sincroniza por DHT como cualquier nodo. La
auto-deteccion por extension hace que minga ingest archivo.{py,ts,js,go}
"simplemente funcione".
API nueva en minga_core::parse:
- Funciones por dialecto: python, typescript, javascript, go (~6 LOC
c/u sobre el parse_with comun). Mas la rust existente.
- Enum Dialect con parse(source) y name() para logging.
- detect_by_extension(ext) -> Option<Dialect>: rs/py/pyi/ts/js/mjs/
cjs/go (case-insensitive). None para extensiones desconocidas.
Wire en minga-cli:
- cmd_ingest deja de hardcodear parse::rust — usa
detect_dialect(file)?.parse(...).
- initial_scan + cmd_watch cambian is_rs_file -> is_supported_source.
- CliError::UnsupportedLanguage { path, extension } nuevo, lista las
extensiones reconocidas en el mensaje.
Notas sobre hashing:
- Hashing estructural (cas::hash_node) funciona para todos. NO es
alpha-equivalente.
- Hashing alpha-equivalente (alpha::hash_node_alpha) sigue siendo
Rust-only — cada lenguaje tiene reglas distintas para binder vs
constructor; implementacion per-language queda como work futuro
(requiere conocimiento profundo de cada gramatica).
- Sanity test structural_hash_distinguishes_languages verifica que
"x = 1" parseado como Python != JS — las gramaticas no comparten
kinds, hashes salen distintos. Importante para evitar colisiones.
Deps nuevas (workspace + minga-core):
- tree-sitter-python 0.23, tree-sitter-typescript 0.23 (modo
LANGUAGE_TYPESCRIPT, no TSX), tree-sitter-javascript 0.23,
tree-sitter-go 0.23.
Tests: 9 nuevos en parse::tests (parse basico para 5 dialectos +
detect_by_extension canonical/case-insensitive + name() +
structural_hash_distinguishes_languages). 108 verdes en minga-core,
10 en minga-cli, sin regresion.
Pendientes: alpha-hashing per-language; alpha-Rust documentados en
alpha.rs (if let, while let, let-else, let-chains, or_pattern con
bindings).
This commit is contained in:
@@ -6,6 +6,76 @@ ratio/diff ver `git show <sha>`.
|
||||
|
||||
## 2026-05-09
|
||||
|
||||
### feat(minga): multi-lenguaje en parser — Python, TypeScript, JavaScript, Go
|
||||
Minga deja de ser Rust-only. Cualquiera de los cinco dialectos
|
||||
(Rust + 4 nuevos) se ingresa al CAS por su AST normalizado, hashea
|
||||
estructuralmente, sincroniza por DHT como cualquier nodo. La
|
||||
auto-detección por extensión hace que `minga ingest archivo.py` o
|
||||
`.ts` o `.go` "simplemente funcione".
|
||||
|
||||
API nueva en `minga_core::parse`:
|
||||
- Funciones por dialecto (~6 LOC c/u sobre el `parse_with` común):
|
||||
`python`, `typescript`, `javascript`, `go`. Más la `rust` existente.
|
||||
- Enum `Dialect` con `parse(source) -> Result<SemanticNode>` y
|
||||
`name() -> &'static str` para logging.
|
||||
- `detect_by_extension(ext) -> Option<Dialect>`: mapea `rs`/`py`/
|
||||
`pyi`/`ts`/`js`/`mjs`/`cjs`/`go` (case-insensitive). `None` para
|
||||
extensiones desconocidas — el caller decide si es error o se
|
||||
ignora silente.
|
||||
|
||||
Wire en `minga-cli`:
|
||||
- `cmd_ingest` deja de hardcodear `parse::rust` — usa
|
||||
`detect_dialect(file)?.parse(...)`. Acepta `.py`, `.ts`, `.js`,
|
||||
`.go` además de `.rs`.
|
||||
- `initial_scan` y `cmd_watch` cambian `is_rs_file` → `is_supported_source`
|
||||
para incluir todas las extensiones soportadas en el filtro.
|
||||
- `CliError::UnsupportedLanguage { path, extension }` nuevo, con
|
||||
mensaje que lista las extensiones reconocidas.
|
||||
|
||||
Notas sobre hashing:
|
||||
- El AST normalizado (`SemanticNode`) descarta whitespace y
|
||||
comentarios — propiedad universal de tree-sitter (extras). Misma
|
||||
lógica para los 5 dialectos.
|
||||
- Hashing **estructural** (`cas::hash_node`) funciona para todos:
|
||||
dos textos semánticamente equivalentes-por-estructura producen el
|
||||
mismo hash. NO α-equivalente (las variables ligadas distinguen).
|
||||
- Hashing **α-equivalente** (`alpha::hash_node_alpha`) sigue siendo
|
||||
Rust-only: cada lenguaje tiene reglas distintas para qué es
|
||||
binder vs. constructor (def/lambda en Python, arrow functions en
|
||||
TS/JS, func + closures en Go). Implementación per-language queda
|
||||
como work futuro — requiere conocimiento profundo de cada
|
||||
gramática y no se plantilla genéricamente.
|
||||
- Sanity test `structural_hash_distinguishes_languages` verifica
|
||||
que `x = 1` parseado como Python ≠ parseado como JavaScript: las
|
||||
gramáticas no comparten kinds y los hashes salen distintos.
|
||||
Importante para evitar colisiones cuando el mismo source se
|
||||
ingresa bajo dialectos distintos.
|
||||
|
||||
Deps nuevas (workspace + minga-core):
|
||||
- `tree-sitter-python = "0.23"`
|
||||
- `tree-sitter-typescript = "0.23"` (sólo el modo `LANGUAGE_TYPESCRIPT`,
|
||||
no TSX — bumpear a TSX es agregar otro dialecto cuando se necesite).
|
||||
- `tree-sitter-javascript = "0.23"`
|
||||
- `tree-sitter-go = "0.23"`
|
||||
|
||||
Tests:
|
||||
- 9 nuevos en `parse::tests`: parse básico para los 5 dialectos
|
||||
(Python con type hints, TS con tipos, JS sin tipos, Go con
|
||||
package declaration), `detect_by_extension` canonical +
|
||||
case-insensitive, `dialect_name`, `structural_hash_distinguishes_languages`.
|
||||
- 108 tests verdes en minga-core (39 → 48 unit + integration tests
|
||||
pre-existentes intactos).
|
||||
- 10 tests verdes en minga-cli (sin regresión en el path Rust;
|
||||
el refactor a `detect_dialect`/`is_supported_source` no rompe
|
||||
nada).
|
||||
|
||||
Pendientes futuros del changelog:
|
||||
- α-hashing per-language (Python: def/lambda/comprehensions;
|
||||
TS/JS: function/arrow/destructuring; Go: func/closure). Trabajo
|
||||
profundo, scope independiente.
|
||||
- α-Rust pendientes documentados en `alpha.rs`: `if let`,
|
||||
`while let`, `let-else`, let-chains, `or_pattern` con bindings.
|
||||
|
||||
### feat(brahman-handshake): multi-key identity — rotación de session sin perder peer_id lógico
|
||||
Cierra el último pendiente del plan de red P2P. Hasta ahora, rotar
|
||||
la keypair libp2p de un nodo cambiaba su `peer_id`, lo que
|
||||
|
||||
Reference in New Issue
Block a user