Protocolo del Proveedor de Evidencia
A primera vista
Qué: Protocolo JSON-RPC 2.0 para proveedores de evidencia externos (MCP) Por qué: Permitir que Decision Gate llame a fuentes de evidencia personalizadas sin cambios en el núcleo Quién: Desarrolladores de proveedores, ingenieros de integración, implementadores de MCP Requisitos previos: JSON-RPC 2.0 y evidence_flow_and_execution_model.md
Cómo Decision Gate Llama a los Proveedores
- Decision Gate llama una herramienta:
evidence_query. - Las llamadas son siempre
tools/callconname = "evidence_query". - La puerta de decisión no depende de
tools/listen tiempo de ejecución; las capacidades del proveedor se cargan desdecapabilities_pathen la configuración.
Los proveedores aún deben implementar tools/list para la compatibilidad con MCP y las plantillas de SDK, pero Decision Gate no depende de ello.
Configuración del Proveedor Externo
Los proveedores externos utilizan type = "mcp" y deben declarar capabilities_path:
[[providers]]
name = "git"
type = "mcp"
# stdio transport
command = ["/usr/local/bin/git-provider", "--repo", "/repo"]
capabilities_path = "contracts/git.json"
[[providers]]
name = "cloud"
type = "mcp"
# HTTP transport
url = "https://evidence.example.com/rpc"
allow_insecure_http = false
capabilities_path = "contracts/cloud.json"
# Optional auth + timeouts
# auth = { bearer_token = "YOUR_TOKEN" }
# timeouts = { connect_timeout_ms = 2000, request_timeout_ms = 10000 }
Los proveedores integrados utilizan type = "builtin" y no son servidores MCP. Los nombres de los proveedores deben ser únicos; los identificadores integrados (time, env, json, http) están reservados y no pueden ser utilizados por proveedores MCP.
Tool Call: evidence_query
Solicitud (JSON-RPC)
{
"jsonrpc": "2.0",
"id": 1,
"method": "tools/call",
"params": {
"name": "evidence_query",
"arguments": {
"query": {
"provider_id": "file-provider",
"check_id": "file_size",
"params": { "path": "report.json" }
},
"context": {
"tenant_id": 1,
"namespace_id": 1,
"run_id": "run-123",
"scenario_id": "ci-gate",
"stage_id": "main",
"trigger_id": "commit-abc",
"trigger_time": { "kind": "unix_millis", "value": 1710000000000 },
"correlation_id": null
}
}
}
}
Respuesta (JSON-RPC)
{
"jsonrpc": "2.0",
"id": 1,
"result": {
"content": [
{
"type": "json",
"json": {
"value": { "kind": "json", "value": 1024 },
"lane": "verified",
"error": null,
"evidence_hash": null,
"evidence_ref": { "uri": "dg+file://evidence-root/report.json" },
"evidence_anchor": {
"anchor_type": "file_path_rooted",
"anchor_value": "{\"path\":\"report.json\",\"root_id\":\"evidence-root\",\"size\":1024}"
},
"signature": null,
"content_type": "application/json"
}
}
]
}
}
Importante: evidence_anchor.anchor_value es una cadena. Si necesita datos de anclaje estructurados, codifíquelos como JSON canónico y almacene la cadena JSON. Para file_path_rooted, incluya los campos escalares root_id y path.
Estructura de EvidenceQuery
{
"provider_id": "string",
"check_id": "string",
"params": "any" // optional
}
provider_idcoincide con el nombre del proveedor en la configuración.check_ides el nombre de la capacidad del proveedor (no el ID de condición del escenario).paramses específico del proveedor; puede omitirse o sernull.
Estructura de EvidenceContext
{
"tenant_id": 1,
"namespace_id": 1,
"run_id": "run-123",
"scenario_id": "ci-gate",
"stage_id": "main",
"trigger_id": "commit-abc",
"trigger_time": { "kind": "unix_millis", "value": 1710000000000 },
"correlation_id": null
}
El contexto es proporcionado por Decision Gate y está disponible para los proveedores para consultas deterministas (por ejemplo, verificaciones en un momento dado).
Estructura de EvidenceResult
{
"value": { "kind": "json|bytes", "value": "any" } | null,
"lane": "verified|asserted",
"error": { "code": "string", "message": "string", "details": "object|null" } | null,
"evidence_hash": { "algorithm": "sha256", "value": "hex" } | null,
"evidence_ref": { "uri": "string" } | null,
"evidence_anchor": { "anchor_type": "string", "anchor_value": "string" } | null,
"signature": { "scheme": "ed25519", "key_id": "string", "signature": [0, 1, 2] } | null,
"content_type": "string" | null
}
Notas:
value.kind = "bytes"utiliza un array JSON de enteros0..255.signature.signaturees un array JSON de bytes (la serializaciónVec<u8>).- Si falta
evidence_hash, Decision Gate lo calcula a partir devalueantes de la verificación. - Si
evidence_hashestá presente, debe coincidir con el hash canónico devalueo la respuesta será rechazada.
Manejo de Errores
Los proveedores deben devolver un EvidenceResult con error establecido para fallos esperados (archivos faltantes, parámetros inválidos, etc.).
Si el proveedor devuelve un error JSON-RPC, Decision Gate lo trata como una falla del proveedor y lo presenta como code = "provider_error" en su lado.
Notas de Transporte
stdio
- Decision Gate genera el proveedor utilizando
command = [..]. - Los mensajes están enmarcados con encabezados
Content-Length.
HTTP
- Decision Gate envía un
POSTJSON-RPC a laurlconfigurada. - El token de portador opcional se puede configurar a través de
auth.bearer_token.
Glosario
EvidenceQuery: Solicitud del proveedor { provider_id, check_id, params }. EvidenceResult: Respuesta del proveedor (valor + metadatos). MCP: Protocolo de Contexto del Modelo (llamadas a herramientas JSON-RPC 2.0). Provider Contract: Archivo JSON que declara verificaciones, esquema de parámetros, esquema de resultados y comparadores permitidos.