Introducción a Decision Gate
A primera vista
Qué: Ejecutar un escenario mínimo de Decision Gate localmente Por qué: Ver el ciclo de vida completo: definir -> iniciar -> evaluar Quién: Desarrolladores que integran Decision Gate en flujos de trabajo de CI/CD, agentes o cumplimiento Requisitos previos: Familiaridad con JSON-RPC 2.0 y curl
Modelo Mental: Ciclo de Vida del Escenario
La puerta de decisión evalúa puertas utilizando condiciones (verificaciones de evidencia). El ciclo de vida es:
1. scenario_define -> registers a ScenarioSpec
2. scenario_start -> creates a RunState (new run)
3. scenario_next -> evaluates current stage and returns a DecisionRecord
Salidas clave de la API:
scenario_definedevuelve{ scenario_id, spec_hash }.scenario_startdevuelve elRunStatecompleto.scenario_nextdevuelve{ decision, packets, status }(unNextResult).
¿Qué es un Escenario?
Un escenario es una definición de flujo de trabajo compuesta por:
- Stages: Ordered steps in the workflow. Think of stages as the top-level Etapas: Pasos ordenados en el flujo de trabajo. Piensa en las etapas como la secuencia de nivel superior por la que te mueves a medida que avanza una ejecución.
- Gates: Decision points inside a stage. A stage can include one or more Puertas: Puntos de decisión dentro de una etapa. Una etapa puede incluir una o más puertas que deben ser superadas para avanzar.
- Conditions: Evidence checks used by gates. Each gate evaluates one or more Condiciones: Comprobaciones de evidencia utilizadas por los gates. Cada gate evalúa una o más condiciones para decidir si se aprueba.
- Providers: Evidence sources (builtin or MCP). Conditions don’t fetch data Proveedores: Fuentes de evidencia (integradas o MCP). Las condiciones no obtienen datos por sí mismas; piden a los proveedores evidencia para evaluar.
Los proveedores pueden ser:
- Integrado:
time,env,json,http - MCP externo: cualquier herramienta que implemente el protocolo
evidence_query
Inicio Rápido
Paso 0: Obtén la CLI
Si instalaste el CLI, utiliza decision-gate. Si estás ejecutando desde el código fuente, utiliza cargo run:
# Installed binary
decision-gate --help
# From source (repo checkout)
cargo run -p decision-gate-cli -- --help
Prueba de humo de un solo comando: scripts/bootstrap/quickstart.sh (bash/WSL) o scripts/bootstrap/quickstart.ps1 (PowerShell) ejecuta el flujo completo de definir → iniciar → siguiente → ejecutar paquete → prechequeo con IDs únicos.
Paso 1: Elegir un Preset
Elija una configuración preestablecida de configs/presets/ (detalles en preset_configs.md). Para esta guía, utilice Quickstart-Dev para que la primera ejecución sea sin fricciones.
Otros ajustes preestablecidos:
- Recomendado por defecto: solo local + mapeo principal explícito.
- Endurecido: se requiere autenticación de portador + firma de esquema.
- Container-Prod: autenticación de portador + terminación TLS ascendente (línea base del contenedor).
Si deseas editar la configuración, primero copia el ajuste preestablecido:
cp configs/presets/quickstart-dev.toml decision-gate.toml
Notas:
- El id del espacio de nombres predeterminado
1está bloqueado a menos quenamespace.allow_default = truey el id del inquilino esté listado ennamespace.default_tenants. - Para enlaces HTTP/SSE que no son de bucle inverso, Decision Gate requiere
--allow-non-loopbackmás TLS oserver.tls_termination = "upstream"y autenticación no local. Consulte security_guide.md. - Consejo de Windows: PowerShell/CMD no soportan
curlen múltiples líneas al estilo bash. Utilice un comando de una sola línea o la cadena aquí@'... '@de PowerShell.
Paso 2: Iniciar el Servidor MCP
# Installed binary:
decision-gate serve --config configs/presets/quickstart-dev.toml
# From source (repo checkout):
# cargo run -p decision-gate-cli -- serve --config configs/presets/quickstart-dev.toml
Paso 3: Definir un Escenario
Este escenario se basa en una verificación de tiempo: time.after(timestamp).
Si utiliza la configuración Hardened: añada -H 'Authorization: Bearer <token>' a cada curl, y cambie a un espacio de nombres no predeterminado (por ejemplo, namespace_id: 2) porque allow_default = false.
curl -s http://127.0.0.1:4000/rpc \
-H 'Content-Type: application/json' \
-d '{
"jsonrpc": "2.0",
"id": 1,
"method": "tools/call",
"params": {
"name": "scenario_define",
"arguments": {
"spec": {
"scenario_id": "quickstart",
"namespace_id": 1,
"spec_version": "v1",
"stages": [
{
"stage_id": "main",
"entry_packets": [],
"gates": [
{
"gate_id": "after-time",
"requirement": { "Condition": "after" }
}
],
"advance_to": { "kind": "terminal" },
"timeout": null,
"on_timeout": "fail"
}
],
"conditions": [
{
"condition_id": "after",
"query": {
"provider_id": "time",
"check_id": "after",
"params": { "timestamp": 1700000000000 }
},
"comparator": "equals",
"expected": true,
"policy_tags": []
}
],
"policies": [],
"schemas": [],
"default_tenant_id": 1
}
}
}
}'
Semántica del tiempo: time.after devuelve true solo si trigger_time > timestamp (estrictamente mayor). La igualdad devuelve false.
Respuesta (envuelta en MCP):
{
"jsonrpc": "2.0",
"id": 1,
"result": {
"content": [
{
"type": "json",
"json": {
"scenario_id": "quickstart",
"spec_hash": { "algorithm": "sha256", "value": "<hex>" }
}
}
]
}
}
Paso 4: Iniciar una Ejecución
curl -s http://127.0.0.1:4000/rpc \
-H 'Content-Type: application/json' \
-d '{
"jsonrpc": "2.0",
"id": 2,
"method": "tools/call",
"params": {
"name": "scenario_start",
"arguments": {
"scenario_id": "quickstart",
"run_config": {
"tenant_id": 1,
"namespace_id": 1,
"run_id": "run-1",
"scenario_id": "quickstart",
"dispatch_targets": [],
"policy_tags": []
},
"started_at": { "kind": "unix_millis", "value": 1710000000000 },
"issue_entry_packets": false
}
}
}'
Nota: los valores de run_id deben ser únicos. Si vuelve a ejecutar esta guía, cambie run_id (por ejemplo, run-2) o elimine el estado de ejecución local (decision-gate.db por defecto).
Respuesta (envuelta en MCP): scenario_start devuelve el RunState completo dentro de result.content[0].json.
{
"jsonrpc": "2.0",
"id": 2,
"result": {
"content": [
{
"type": "json",
"json": {
"tenant_id": 1,
"namespace_id": 1,
"run_id": "run-1",
"scenario_id": "quickstart",
"spec_hash": { "algorithm": "sha256", "value": "<hex>" },
"current_stage_id": "main",
"stage_entered_at": { "kind": "unix_millis", "value": 1710000000000 },
"status": "active",
"dispatch_targets": [],
"triggers": [],
"gate_evals": [],
"decisions": [],
"packets": [],
"submissions": [],
"tool_calls": []
}
}
]
}
}
Paso 5: Evaluación de la Puerta de Decisión
curl -s http://127.0.0.1:4000/rpc \
-H 'Content-Type: application/json' \
-d '{
"jsonrpc": "2.0",
"id": 3,
"method": "tools/call",
"params": {
"name": "scenario_next",
"arguments": {
"scenario_id": "quickstart",
"request": {
"run_id": "run-1",
"tenant_id": 1,
"namespace_id": 1,
"trigger_id": "trigger-1",
"agent_id": "agent-1",
"time": { "kind": "unix_millis", "value": 1710000000000 },
"correlation_id": null
}
}
}
}'
Con time.after y timestamp = 1700000000000, la verificación devuelve true porque 1710000000000 > 1700000000000.
Opcional: añade "feedback": "trace" dentro de arguments para obtener el estado de la puerta/condición cuando lo permita la política de retroalimentación del servidor.
Respuesta (envuelta en MCP):
{
"jsonrpc": "2.0",
"id": 3,
"result": {
"content": [
{
"type": "json",
"json": {
"decision": {
"decision_id": "decision-1",
"seq": 1,
"trigger_id": "trigger-1",
"stage_id": "main",
"decided_at": { "kind": "unix_millis", "value": 1710000000000 },
"outcome": { "kind": "complete", "stage_id": "main" },
"correlation_id": null
},
"packets": [],
"status": "completed"
}
}
]
}
}
Solución de problemas
El resultado de la puerta es hold
Si una puerta no puede ser probada como verdadera o falsa, el resultado de la decisión será mantener y la respuesta incluirá un SafeSummary. Para solicitudes no locales, scenario_next por defecto es retroalimentación solo de resumen; en modo solo local, el valor por defecto es trace. Siempre puedes solicitar feedback: "trace" (si está permitido) o usar precheck para iteraciones rápidas.
{
"result": {
"content": [
{
"type": "json",
"json": {
"decision": {
"outcome": {
"kind": "hold",
"summary": {
"status": "hold",
"unmet_gates": ["after-time"],
"retry_hint": "await_evidence",
"policy_tags": []
}
}
}
}
}
]
}
}
Cómo depurar con precisión:
- Exporta el runpack con
runpack_exporte inspeccionagate_evalsy los errores de evidencia en el manifiesto. - Utilice
evidence_query(si la política de divulgación lo permite) para reproducir la llamada del proveedor y ver suEvidenceResult.
Autenticación Requerida
Si configuras [server.auth], incluye el encabezado de autenticación apropiado:
curl -s http://127.0.0.1:4000/rpc \
-H 'Content-Type: application/json' \
-H 'Authorization: Bearer YOUR_TOKEN' \
-d '{ ... }'
Próximos Pasos
- condition_authoring.md: escribir condiciones y comparadores precisos
- json_evidence_playbook.md: recetas de evidencia JSON
- llm_native_playbook.md: flujos de trabajo de prechequeo para agentes LLM
- security_guide.md: endurecimiento de producción (autenticación, TLS, firmas, anclajes)