Transacciones y Operaciones
Las transacciones son la unidad atómica de cambio en Asset Core. Cada transacción contiene una secuencia de operaciones que se ejecutan juntas o no se ejecutan en absoluto. Este es el contrato central que hace que Asset Core sea determinista y auditable.
Problema que este concepto resuelve
Los cambios de estado complejos a menudo requieren múltiples actualizaciones coordinadas. Sin atomicidad, los sistemas se desvían porque se cometen cambios parciales que ya no coinciden con el estado previsto.
- Creando un contenedor y poblándolo
- Transferencia de activos entre ubicaciones
- Agregar una instancia y colocarla
Sin transacciones atómicas, estos cambios de múltiples pasos podrían fallar a mitad de camino, dejando el sistema en un estado inconsistente. Asset Core resuelve esto agrupando operaciones en transacciones con una semántica de todo o nada.
Asset Core utiliza un vocabulario de operación fijo porque define la superficie matemática mínima para las transiciones de estado. Cada llamador—humano, servicio o agente—utiliza las mismas operaciones; la gobernanza determina cuáles puede invocar un llamador. El conjunto acotado hace que la auditoría y las herramientas sean manejables sin sacrificar la expresividad.
Ideas principales
Estructura del Commit
Una solicitud de confirmación contiene una lista de operaciones. El sobre es intencionadamente uniforme para que pueda ser validado, reproducido y auditado de manera consistente en todos los dominios.
{
"actor_id": "lab-operator-17",
"operations": [
{ "op": "CreateContainer", "args": { ... } },
{ "op": "AddFungible", "args": { ... } }
],
"idempotency_key": "optional-unique-key",
"metadata": { "experiment": "phase-1" }
}
Las operaciones se ejecutan en orden dentro de la transacción. Si alguna operación falla, todo el commit se revierte.
Operación Sobre.
Cada operación tiene la misma estructura de sobre:
{
"op": "OperationName",
"args": { ... }
}
op: El identificador de la operación (por ejemplo,CreateContainer)args: Argumentos específicos de la operación
Esta estructura uniforme facilita la composición y el procesamiento de operaciones de manera programática.
Las 24 Operaciones
Asset Core define exactamente 24 operaciones en 5 dominios. Este pequeño vocabulario cerrado es lo que hace que la aplicación automática de políticas y la auditoría sean manejables.
| Dominio | Operaciones |
|---|---|
| Contenedor | CreateContainer, RemoveContainer |
| Balance | AddFungible, RemoveFungible, MoveFungible, TransferFungible, TransferMany, Distribute, MoveMany, MergeStacks, ConsolidateStacks |
| Instancia | AddInstance, MoveInstance, RemoveInstance, BurnInstance, Attach, Detach |
| Ranura | PlaceInSlot, RemoveFromSlot, SwapSlots |
| Esquema | RegisterClass, RegisterClassShape, RegisterClassContinuousShape1d, RegisterClassContinuousShape2d |
¿Por qué exactamente 24? Porque ese es el conjunto mínimo que cubre el espacio de operación para sistemas de estado espacial sin perder expresividad.
Cada operación se encuadra en una taxonomía de 4 dimensiones: dominio (qué tipo de entidad), acción (qué tipo de cambio), alcance (entidad única o múltiple) y reversibilidad (¿se puede deshacer o es destructiva?). Esta taxonomía no es decorativa; es la forma en que se construye la gobernanza.
Este vocabulario cerrado también es crítico para la gobernanza. Una API sin límites (SQL arbitrario, scripting de propósito general) significa que los llamadores pueden realizar operaciones que no anticipaste y que no puedes auditar. Un conjunto de operaciones fijo significa que puedes:
- Lista blanca por dominio: “Este agente solo puede modificar saldos, no instancias”
- Lista negra de operaciones destructivas: “Este agente puede moverse pero no quemar”
- Auditar exhaustivamente: “Muéstrame cada operación que realizó este actor”
La restricción es una característica. Cuando necesitas un comportamiento de nivel superior, compones operaciones: combinas múltiples operaciones en una transacción. Los patrones comunes de múltiples operaciones están documentados en Recipes, pero la lista no es exhaustiva. Si tu dominio tiene un comportamiento fuera del modelo, mantén esa lógica en tu aplicación y compromete los cambios de estado resultantes a través de operaciones.
Este conjunto fijo proporciona:
- Auditoría: Cada posible cambio de estado es conocido
- Seguridad: No mutaciones arbitrarias
- Consistencia: Las mismas operaciones funcionan en todos los entornos
Sistema de Etiquetas
Las operaciones se categorizan en cuatro dimensiones. Esta taxonomía no es metadatos de documentación; es la base para la gobernanza.
¿Por qué existe esto? Cuando le otorgas a un llamador permiso para manipular el estado de AssetCore, necesitas un control granular. “Puede modificar cualquier cosa” es demasiado amplio. Las listas de permitidos largas son frágiles y difíciles de mantener. El sistema de etiquetas te ofrece filtrado semántico: “puede crear y mover instancias, pero no puede destruir” o “solo puede modificar saldos, no contenedores.”
Las cuatro dimensiones:
Dominio: Qué tipo de entidad se ve afectado
container,balance,instance,slot,schema
Acción: Qué tipo de cambio
crear,destruir,mover,enlazar,consolidar
Alcance: Cuántas entidades
único,múltiple
Reversibilidad: ¿Se puede deshacer?
reversible,destructive,neutral
Cómo esto te ayuda:
-
Permisos del agente: Lista blanca por dominio + acción. “Este agente puede mover instancias pero no puede quemarlas” =
domain:instance, action:move, reversibility:reversible. -
Consultas de auditoría: “Muéstrame todas las operaciones destructivas en las últimas 24 horas” = filtrar el registro de eventos por
reversibility:destructive. -
Generación de herramientas: El manifiesto de operaciones (archivo JSON) incluye etiquetas. Puedes generar definiciones de herramientas de agente programáticamente: “Crea una herramienta para cada operación reversible de alcance único.”
Ejemplo: El catálogo de herramientas MCP utiliza estas etiquetas para agrupar operaciones en superficies de herramientas seguras. Los agentes obtienen assetcore_move_instance (reversible, de ámbito único) pero no assetcore_burn_instance (destructiva) a menos que se les otorgue explícitamente.
Idempotencia
La opción idempotency_key permite reintentos seguros. En producción, es un control de fiabilidad principal, no una característica de conveniencia.
- La primera solicitud con una clave se ejecuta normalmente
- Las solicitudes posteriores con la misma clave devuelven la respuesta en caché
- Previene commits duplicados de reintentos de red
Siempre use claves de idempotencia para cargas de trabajo en producción.
Cómo encaja en el sistema
Flujo de Ejecución
- El cliente envía una solicitud de confirmación
- Escribir daemon que analiza y valida
- Las operaciones se ejecutan en secuencia (la validación del tipo de contenedor ocurre aquí; ver Containers and Assets)
- Los eventos se registran para cada operación
- Los eventos se sellan en un lote
- El lote se añade al registro de confirmaciones del backend (ver Modelo de Ejecución)
- El cliente recibe una respuesta de éxito
Reversión en caso de fallo
Si alguna operación falla:
- La ejecución se detiene en la operación fallida.
- El registro de deshacer se aplica en orden inverso
- El estado se restaura a la pre-transacción
- El cliente recibe una respuesta de error
No se pueden ver compromisos parciales para los lectores.
Generación de Eventos
Cada operación genera eventos que:
- Describir el cambio de estado
- Llevar el estado posterior para la repetición
- Se agrupan en el lote de transacciones
Los eventos son el registro autoritativo (la durabilidad depende del backend); las operaciones son el formato de solicitud.
Invariantes clave y garantías
Atomicidad
Todas las operaciones en una transacción tienen éxito o fallan juntas. Esta es la garantía que previene la corrupción parcial del estado.
Sin atomicidad, una falla en la operación 5 de 10 deja las operaciones 1-4 comprometidas y 6-10 no ejecutadas. Su estado es ahora internamente inconsistente: un contenedor creado pero nunca poblado, una transferencia medio ejecutada, una instancia movida pero su referencia padre obsoleta. La depuración requiere reconstruir “lo que debería haber sucedido”, lo cual es a menudo imposible. Los usuarios ven un estado corrupto, las operaciones fallan inesperadamente y la confianza se erosiona.
AssetCore aplica la atomicidad a través de un registro de deshacer (ver Modelo de Ejecución):
- No se visible ejecución parcial (las consultas nunca ven estados intermedios)
- La reversión restaura el estado exacto anterior (reproduce el registro de deshacer en reversa)
- Las respuestas de error utilizan los Detalles del Problema RFC 9457 con códigos estables (indica QUÉ operación falló y por qué)
La respuesta de error te indica qué operación falló y por qué, pero el estado permanece limpio. Lo que ganas: confianza en que las transacciones fallidas no dejan rastro, sin necesidad de limpieza manual después de fallos, la consistencia interna es una garantía, no un esfuerzo. Lo que cedes: no puedes “confirmar lo que tuvo éxito y omitir lo que falló”. Eso no es un error, es el diseño. Si necesitas un progreso parcial, divide la transacción en confirmaciones más pequeñas con puntos de control explícitos.
Preservación de Pedidos
Las operaciones se ejecutan en el orden en que aparecen en el arreglo. Esto parece obvio, pero tiene implicaciones sutiles para la corrección.
Las operaciones posteriores ven los efectos de las anteriores dentro de la misma transacción. Así es como puedes CreateContainer en la operación 1 y AddFungible a ese contenedor en la operación 2; el ID del contenedor del resultado de la operación 1 es visible de inmediato. Sin la preservación del orden, tendrías que dividir estas en transacciones separadas con coordinación manual.
AssetCore garantiza la ejecución secuencial:
- Las operaciones posteriores ven los efectos de las anteriores (dependencias satisfechas en secuencia)
- Las dependencias se satisfacen secuencialmente (sin ejecución paralela dentro de una transacción)
- No hay reordenamiento ni optimización que cambie la semántica (el tiempo de ejecución no reorganiza por rendimiento)
Esto es crítico para el determinismo: si el tiempo de ejecución reordena operaciones por rendimiento, dos transacciones idénticas podrían producir diferentes secuencias de eventos dependiendo de las heurísticas del tiempo de ejecución. La preservación del orden hace que la ejecución de transacciones sea una función pura del array de entrada. Lo que ganas: ejecución predecible, capacidad para componer operaciones con dependencias, reproducción determinista. Lo que cedes: el tiempo de ejecución no puede paralelizar automáticamente operaciones independientes dentro de una transacción, pero la mayoría de las transacciones son lo suficientemente pequeñas como para que esto no importe.
Determinismo
Dada una estado idéntico y una secuencia de operaciones idéntica, la ejecución produce eventos idénticos en bytes. Esto es lo que hace posible la reproducción.
El determinismo a nivel de transacción se basa en las garantías de determinismo del tiempo de ejecución (ver Modelo de Tiempo de Ejecución). Las operaciones no deben depender de un estado externo: no se permiten lecturas del reloj del sistema, no se genera números aleatorios, no se realizan llamadas a API externas. Todo lo que afecta la ejecución fluye a través de los argumentos de la operación o del estado actual.
AssetCore garantiza una ejecución determinista:
- Dado un estado y operaciones idénticos (mismo estado del mundo, mismo array de operaciones)
- Los eventos serán idénticos en bytes (misma secuencia, mismos payloads)
- Permite la reproducción y verificación (reconstruir el estado a partir del registro, probar qué sucedió y cuándo)
Lo que esto permite: depuración de viaje en el tiempo (repetir hasta cualquier punto e inspeccionar), recuperación ante desastres (reconstruir proyecciones a partir del registro de confirmaciones), auditoría forense (probar qué sucedió y cuándo). Lo que se sacrifica: no se pueden llamar a APIs externas ni usar marcas de tiempo de las operaciones; todo debe ser determinista. Si necesitas tiempo de reloj o datos externos, inclúyelos como argumentos de operación (capturados en el momento de la confirmación) en lugar de obtenerlos durante la ejecución.
Vocabulario Fijo
Las 24 operaciones son el conjunto completo. No se pueden definir operaciones personalizadas ni extender el vocabulario en tiempo de ejecución.
Esto parece una limitación hasta que te das cuenta de que es la base para la auditabilidad y la seguridad del agente. Cada posible cambio de estado encaja en una de 24 categorías semánticas. Ese es un espacio manejable para la aplicación de políticas. Sin esta restricción, un agente de IA podría construir transiciones de estado arbitrarias que nunca has considerado. Con ella, puedes enumerar cada tipo de operación posible, adjuntar políticas a cada una y auditar de manera exhaustiva.
AssetCore impone un vocabulario fijo:
- Las 24 operaciones están completas (sin operaciones personalizadas, sin extensión de tiempo de ejecución)
- Los cambios complejos componen múltiples operaciones en una transacción (ver Recetas para patrones comunes)
- Esta restricción es una característica: hace posible la gobernanza
Lo que ganas: espacio de operación auditable (conocer cada tipo de cambio posible), seguridad del agente (vocabulario limitado = sin sorpresas), semántica consistente en todos los entornos (mismas operaciones en todas partes). Lo que cedes: flexibilidad para definir operaciones específicas del dominio. Si algún comportamiento no se mapea directamente, mantén esa lógica fuera del tiempo de ejecución y utiliza Asset Core para las transiciones de estado que sí lo hagan. Este es el mismo compromiso que usar SQL (lenguaje de consulta fijo) frente a código arbitrario: la restricción permite herramientas y garantías.
Ver también
- Transacciones - referencia de estructura JSON
- Referencia de Acción - Detalles completos de la operación
- Prevuelo y Compromiso Inverso - Validación no mutante y semántica de deshacer
- Recetas - Patrones comunes de múltiples operaciones