fluid-core/schemas/routing-policy.schema.json
tegwick fbbf56df7a Add FLUID wire contract schemas
Nine JSON Schemas covering the five record types from the schema spec,
plus backend requirements, feedback, the revision descriptor, routing
policy and the telemetry envelope. These are the integration boundary:
readable without any fluid-core code, so adapters may be written in any
language.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_014KmVxhJ35tCo7rE7UnLwWu

Assistant: claude-code
Assistant-Model: opus
Assistant-Process: 1116572@bnt-lap001
Assistant-Session: 8ba9bb93-a72a-4883-b189-2499cce5c400
2026-09-04 01:55:47 +02:00

71 lines
3.1 KiB
JSON

{
"$schema": "https://json-schema.org/draft/2020-12/schema",
"$id": "https://fluid.dev/schemas/routing-policy.schema.json",
"title": "FLUID routing policy",
"description": "Deterministic routing written by the experiment controller and consumed by the revision router. The controller never touches traffic itself; this separation keeps experimental intent out of the runtime decision mechanism (ArchitectureBlueprint.md section 17).",
"type": "object",
"properties": {
"routing_policy": {
"type": "object",
"properties": {
"schema_version": { "$ref": "common.schema.json#/$defs/schemaVersion" },
"id": { "type": "string", "minLength": 1 },
"interface": { "$ref": "common.schema.json#/$defs/interfaceId" },
"generation": {
"type": "integer",
"minimum": 0,
"description": "Monotonic. The router ignores a policy older than the one it holds."
},
"issued_at": { "$ref": "common.schema.json#/$defs/timestamp" },
"issued_by": { "$ref": "common.schema.json#/$defs/actor" },
"default_revision": {
"$ref": "common.schema.json#/$defs/revisionId",
"description": "Where a request lands when no earlier resolution step matched."
},
"rules": {
"type": "array",
"description": "Evaluated in order; the first matching rule wins. Matching must be a pure function of the request and its cohort assignment.",
"items": {
"type": "object",
"properties": {
"cohort": { "$ref": "common.schema.json#/$defs/cohortId" },
"tenant": { "type": "string" },
"experiment": { "$ref": "common.schema.json#/$defs/experimentId" },
"allocation": {
"type": "object",
"description": "Revision id to traffic share. Shares must sum to 1. Assignment of a given consumer must be stable across requests.",
"propertyNames": { "$ref": "common.schema.json#/$defs/revisionId" },
"additionalProperties": { "$ref": "common.schema.json#/$defs/unitInterval" },
"minProperties": 1
},
"sticky_by": {
"enum": ["consumer_id", "tenant", "correlation_id", "none"],
"default": "consumer_id",
"description": "What keeps a long-lived consumer on one side of an experiment."
}
},
"required": ["allocation"],
"additionalProperties": false
}
},
"signature": {
"type": "object",
"properties": {
"algorithm": { "enum": ["ed25519"] },
"key_id": { "type": "string", "minLength": 1 },
"value": { "type": "string", "contentEncoding": "base64" }
},
"required": ["algorithm", "key_id", "value"],
"additionalProperties": false
}
},
"required": ["schema_version", "interface", "generation", "default_revision", "rules"],
"additionalProperties": false
}
},
"required": ["routing_policy"],
"additionalProperties": false
}