Snapcontext

Latest version: v6.37.0

Safety actively analyzes 1029930 Python packages for vulnerabilities to keep your Python projects secure.

Scan your dependencies

Page 1 of 18

6.37.0

> **Política de compatibilidad: `PRE_RELEASE_PRODUCT`.** Se mantiene la
> declaración de 6.36.0: no consta adopción externa, por lo que no existe un
> contrato público de compatibilidad establecido por terceros. Los cambios
> descritos abajo son aditivos (superficies nuevas, parámetros opcionales) y
> no eliminan ni re-typian ninguna superficie previa, lo que sustenta la
> clasificación **MINOR** y no MAJOR.

**Alcance:** el canal WORK (`.work/`) completo —contenedor documental,
lector/escritor de estado y motor de verificación de verdicts—, dos
correcciones de la frontera de ejecución, y la identidad pública del
proyecto. 15 commits desde `v6.36.0` (`72aeb79`).

Added — Canal WORK (`.work/`)

- **`work_context.py`**: contenedor `.work/<id>/` con los documentos canónicos
`state.md`, `decisions.md` y `assertions.md`. Escritor atómico (temporal en el
mismo directorio + `os.replace`): si algo falla antes del reemplazo, el
contenido anterior queda intacto.
- **`work_verdict.py`**: adaptador Git de solo lectura (`GitAnchor` con
`tree_sha`, `CurrentGitState`), productor canónico `producir_verdict()` y
evaluador puro `evaluar_validez_verdict()` (`VALID` / `OBSOLETE` /
`UNDETERMINED`). Si Git no es observable lanza `EstadoGitIndisponibleError`
y **nunca** degrada a un estado de validez.
- **`work_obsolencia.py`**: `detectar_obsolescencia()` explícita, append-only e
idempotente. La obsolescencia significa únicamente que el contenido efectivo
del árbol dejó de coincidir con el `tree_sha` que produjo la verificación.
- **Herramientas MCP nuevas**:
- `work_state` — lee `state.md` de un trabajo. Solo lectura, no pide permiso.
- `work_state_update` — actualiza campos declarativos. Es una capacidad de
mutación: **requiere permiso explícito**.
- **`ReactAgent(work_id=…)`**: el agente ReAct (F4) puede vincularse a un
trabajo del canal WORK; al ejecutar, captura el estado Git previo, produce el
`Verdict`, evalúa su validez y persiste la última verificación. El resultado
F4 incorpora las claves `verdict`, `validity` y `verificacion_persistida`
(más `*_error` si procede). **Cambio aditivo**: las claves y semántica
preexistentes no cambian.
- **`.work` excluido del contexto PROJECT** (B11-E): añadido a las listas de
directorios ignorados de `graph_rag.py`, `graph_lsp_integrator.py` y
`seguridad.py`, y a la exclusión del staging automático de Git.
- **Excepciones nuevas** en `exceptions.py`: `ContratoEstadoInvalidoError`,
`EstadoGitIndisponibleError` (expone `motivo`) y `AutoridadInsuficienteError`.

Security

- **Frontera de ejecución CONTAINER ahora vinculante**: la rama `CONTAINER`
ya no delega en `_envolver_sandbox`, que devolvía el comando intacto cuando
el sandbox explícito no estaba activo. Un comando clasificado como `sandbox`
se ejecutaba **sin aislamiento y sobre el árbol equivocado**; con este
cambio la decisión de política gobierna la ejecución. Se elimina además la
sustitución del directorio solicitado por `Path.cwd()`. Sin fallback
silencioso a host.
- **Política de autoridad fail-closed** al escribir estado: los campos
protegidos del mandato (como `veredictos_obsoletos`) se rechazan **antes**
que la allowlist genérica y **ninguna** autorización los salva;
`ciclo_de_vida` y `cierre_estado` exigen `autorizacion=True`. La decisión se
toma sobre la operación completa, por lo que nunca hay escritura parcial.
- **CI**: la auditoría de dependencias (`pip-audit`) deja de ser
`continue-on-error` y pasa a **bloqueante**, al medirse 0 advisories sobre el
grafo de dependencias declarado.

Fixed

- **Staging de un paso**: `git add . ":(exclude).work"` se clasificaba como
`sandbox` porque el `(` del pathspec magic se interpretaba como metacarácter
de shell, con lo que el staging viajaba al contenedor y el commit se
ejecutaba en el host sobre un índice vacío («nothing to commit» y un
diagnóstico engañoso). El staging se ejecuta ahora por argv con
`shell=False`; si el argv no fuera `directo` se aborta explícitamente.
- **Tipos del work context**: alineación de tipos con valores opcionales.
- **Mypy**: el gate de calidad vuelve a estar en verde.
- **Mensajes de instalación**: `configuracion.py` y `diagnostico.py` ya no
recomiendan extras que no existen (`snapcontext[anthropic]`,
`snapcontext[interactive]`, `snapcontext[embeddings]`, `snapcontext[lsp]`) y
pasan a indicar el paquete a instalar directamente.
- **Packaging**: `work_context`, `work_verdict` y `work_obsolencia` se
declaran en `[tool.setuptools] py-modules`. Sin ellos, el wheel publicado no
contenía el canal WORK y las herramientas `work_state` / `work_state_update`
fallaban en una instalación limpia. `verify_release.py` los incluye ahora en
`MODULOS_WHEEL` para que el invariante I10 detecte su ausencia en el futuro.

Changed

- **Metadata de identidad pública**: `pyproject.toml` corrige el nombre del
autor (mojibake `Nicolás` → `Nicolás Bruna`) y añade `[project.urls]` con
`Homepage` y `Repository`. El `plugin.xml` de JetBrains pasa de vendor
«SnapContext Contributors» a **Nicolás Bruna Fuentealba** (`nicobrunaf.dev`),
con descripción reescrita y enlaces al perfil público.
- **Documentación de publicación**: `docs/RELEASE.md` documenta que parte del
metadata del listing de JetBrains vive fuera del repositorio (descripción
editada desde la UI, vendor, enlaces, versión publicada) y añade la
verificación post-release de JetBrains. `PUBLISHING.md` queda como nota
histórica y remite a `docs/RELEASE.md` como autoridad vigente.
- **Instalación documentada**: el README deja de anunciar extras inexistentes y
explica que `--lsp` usa servidores LSP externos ya instalados en `PATH`.

Limitaciones conocidas

- **XPU / Intel Arc serie B**: el backend (`backend_xpu.py`) no detecta
específicamente «Arc B» ni «Battlemage»; comprueba `torch.xpu` e IPEX de
forma genérica. El soporte de Battlemage **depende de `ipex-llm>=2.2.0`**,
una dependencia externa. Los tests de integración real se saltan sin GPU
Intel. La capacidad es, por tanto, *parcialmente* soportada y delegada en el
proveedor de la librería.
- El canal WORK no implementa lifecycle, ratificación, resolución de conflictos
ni descubrimiento de trabajos: solo el formato físico seguro de los
documentos. La obsolescencia es explícita, sin daemon, polling ni watcher.

6.36.0

- **R-1 — Discord puede encolar tareas `tests` / `pr_review` que el worker después
deniega.** El usuario recibe una confirmación de encolado de algo que no llegará
a ejecutarse. Es comportamiento conocido, **no resuelto en 6.36.0** y **diferido
al siguiente release**. No debe interpretarse como una capacidad operativa
válida.
- **R-3** (P3) — un test puede producir volumen excesivo de salida en ciertas
ejecuciones focalizadas (higiene de CI / disco). Deuda **post-release**.
- **R-4** (P3) — `_TAREAS_API` registra owner/contexto que la ruta in-process no
consume para revalidar. Deuda arquitectónica **post-release**, sin bypass.

Fixed
- TOCTOU en `_validar_ruta_segura`: la validación y la apertura ahora son atómicas.
- Symlinks que apuntan fuera del proyecto ya no se siguen (`O_NOFOLLOW`).
- Cobertura: añadidos 21 tests en `tests/test_file_safety.py`.
- `mcp_client`: `KeyError` no manejado en `_enviar`/`_esperar_respuesta` al
reutilizar un proceso muerto tras un fallo de `stdin`.
- `mcp_client.list_tools`: valida el tipo de los elementos y filtra los que no
son `dict`; cobertura del módulo 22% → 87%.
- Baseline de esta release: **3130 passed, 43 skipped, 0 failed**.

Changed
- **BREAKING (comportamiento)**: el modelo de decisión del sandbox cambió de
blocklist a **default-deny**, con clasificación en 3 niveles
(`sandbox_utils.clasificar_comando`):
1. *Allowlist*: comandos sin metacaracteres de shell (`| ; > & $(...) \``
`$VAR`) cuyo binario base está en `sandbox_allowlist_binarios` →
ejecución directa (fricción cero).
2. *Default-deny*: cualquier otro comando (pipes, redirecciones, expansión
de variables, binarios fuera de la allowlist, casos explícitos como
`eval`, `base64 -d | sh`, `mkfs`, `shred`, `truncate`, escrituras a
`/dev/*`) → sandbox Docker obligatorio, sin confirmación adicional más
allá de la que ya aplique `permisos.json`.
3. *Blocklist legacy* (`es_comando_peligroso`, intacta): defensa en
profundidad — ya no decide sandbox sí/no; si un comando la matchea se
muestra un warning más explícito (con el patrón que disparó) antes de
confirmar.
- **BREAKING (procesos en background)**: `_lanzar_proceso_fondo` (estado.py)
sin sandbox activo aplica ahora la misma clasificación: los comandos que
antes corrían simplemente por no estar en la blocklist (p. ej.
`flutter run`) **se rechazan** si su binario no está en la allowlist.
- Nueva clave de configuración `sandbox_allowlist_binarios` (nivel superior
de `~/.snapcontext/config.json`; ejemplo en `config.example.json`): lista
de binarios con ejecución directa. Si se define **sobrescribe completa** la
lista por defecto (no hace merge). Por defecto:
`ls, cat, head, tail, wc, stat, file, diff, tree, grep, rg, git, pytest,
ruff, mypy, black, isort, npm, pip, pip3, echo, which, date`.
- `--no-sandbox` sigue forzando ejecución directa, pero los comandos fuera de
la allowlist ya no pasan en silencio: piden confirmación explícita
mostrando el motivo (y abortan en modo `--auto`/stdin no interactivo).
- Motivación: la blocklist regex anterior era trivialmente evadible
(`echo <b64> | base64 -d | sh`, `python -c 'shutil.rmtree("/")'`,
`find / -delete`, `eval "$VAR"`, heredocs, expansión de variables). Tests
nuevos en `tests/test_sandbox_inteligente.py` (un caso por evasión,
allowlist con metacaracteres, `--no-sandbox` y gate de background).

Migración
- Comandos de tu flujo habitual que antes corrían directo y ahora piden sandbox o
confirmación, revisa `sandbox_allowlist_binarios` en tu `~/.snapcontext/config.json`
y añade los binarios específicos de tu stack (p. ej. `flutter`, `dart`, `cargo`, `go`).
Recuerda que la lista definida **reemplaza** la por defecto: copia primero
la lista base de `config.example.json` y agrega los tuyos.
- Escrituras: convierte en relativas las rutas absolutas dentro del proyecto.
- Gateway Web: arranca con `--workspace-root` explícito si no es loopback, y genera
la credencial con `preparar_credencial_inicio()` (permisos `0600`).
- **Sin migración posible** (restricciones por diseño en 6.36.0): ejecución remota,
instalación remota de plugins y los tipos de tarea `tests`/`pr_review`.

6.35.3

Fixed
- Tests: mock de input() con valor válido en test_plan_012 (evita bucle infinito)
- Tests: mockear _confirmar_accion en test_modo_inteligente (evita OSError de pytest)
- Permisos: capturar OSError además de EOFError en _confirmar_accion
- Permisos: límite de 3 intentos inválidos antes de denegar (defensa en profundidad)

6.35.2

Fixed
- CI: configurar git user/email en integration tests (fix tests de commit)
- Test: mock correcto de _actualizar_clave_configuracion en test_api_360
Changed
- Coverage: fail_under solo en workflow (fuente única de verdad)
- README: badges dinámicos de version y license (shields.io)

6.35.1

Fixed
- CI: eliminar classifier de licencia Apache para cumplir PEP 639
(setuptools ≥77 ya no permite classifier + license expression juntos).
El campo `license = "Apache-2.0"` sigue siendo la fuente de verdad.

6.35.0

Changed
- **BREAKING (legal)**: Relicencia de MIT a Apache License 2.0.
Versiones anteriores (<6.35.0) permanecen bajo MIT (ver LICENSE.MIT).
- Motivo: protección explícita de patentes y adopción empresarial.

Page 1 of 18

© 2026 Safety CLI Cybersecurity Inc. All Rights Reserved.