{ "$schema": "https://json-schema.org/draft/2020-12/schema", "$id": "https://railiance.local/schemas/railiance-app.schema.json", "title": "Railiance app.toml contract", "type": "object", "additionalProperties": false, "required": [ "schema_version", "app", "source", "platform", "secrets", "observability", "rollback", "stages", "checks" ], "properties": { "schema_version": { "const": "railiance.app.v1" }, "app": { "type": "object", "additionalProperties": false, "required": [ "id", "name", "repo", "owner", "criticality", "description" ], "properties": { "id": { "type": "string", "pattern": "^[a-z0-9][a-z0-9-]*$" }, "name": { "type": "string", "minLength": 1 }, "repo": { "type": "string", "minLength": 1 }, "owner": { "type": "string", "minLength": 1 }, "criticality": { "enum": [ "low", "medium", "high", "critical" ] }, "description": { "type": "string", "minLength": 1 } } }, "source": { "type": "object", "additionalProperties": false, "required": [ "revision", "artifact", "digest_policy" ], "properties": { "revision": { "type": "string", "minLength": 1 }, "artifact": { "enum": [ "image", "helm-chart", "bundle", "manifest", "other" ] }, "digest_policy": { "enum": [ "required", "preferred", "not-applicable" ] } } }, "platform": { "type": "object", "additionalProperties": false, "required": [ "dependencies" ], "properties": { "dependencies": { "type": "array", "items": { "$ref": "#/$defs/dependency" } } } }, "secrets": { "type": "object", "additionalProperties": false, "required": [ "references" ], "properties": { "references": { "type": "array", "items": { "$ref": "#/$defs/secretReference" } } } }, "observability": { "type": "object", "additionalProperties": false, "required": [ "health_endpoints" ], "properties": { "health_endpoints": { "type": "array", "minItems": 1, "items": { "$ref": "#/$defs/healthEndpoint" } }, "metrics": { "type": "array", "default": [], "items": { "$ref": "#/$defs/observationReference" } }, "logs": { "type": "array", "default": [], "items": { "$ref": "#/$defs/observationReference" } } } }, "rollback": { "type": "object", "additionalProperties": false, "required": [ "strategy", "command", "verification" ], "properties": { "strategy": { "enum": [ "helm-revision", "image-digest", "traffic-shift", "manual-runbook", "none" ] }, "command": { "type": "string", "minLength": 1 }, "verification": { "type": "string", "minLength": 1 } } }, "stages": { "type": "object", "additionalProperties": false, "required": [ "stage1", "stage2", "stage3" ], "properties": { "stage1": { "$ref": "#/$defs/stage1" }, "stage2": { "$ref": "#/$defs/stage2" }, "stage3": { "$ref": "#/$defs/stage3" } } }, "checks": { "type": "array", "minItems": 1, "items": { "$ref": "#/$defs/check" } } }, "$defs": { "stageName": { "enum": [ "stage1", "stage2", "stage3" ] }, "dependency": { "type": "object", "additionalProperties": false, "required": [ "name", "kind", "required", "stage", "evidence" ], "properties": { "name": { "type": "string", "minLength": 1 }, "kind": { "enum": [ "postgres", "redis", "object-store", "identity", "state-hub", "inter-hub", "network", "other" ] }, "required": { "type": "boolean" }, "stage": { "$ref": "#/$defs/stageName" }, "evidence": { "type": "string", "minLength": 1 } } }, "secretReference": { "type": "object", "additionalProperties": false, "required": [ "name", "route", "target", "stage", "required" ], "properties": { "name": { "type": "string", "minLength": 1 }, "route": { "type": "string", "minLength": 1 }, "target": { "type": "string", "minLength": 1 }, "stage": { "$ref": "#/$defs/stageName" }, "required": { "type": "boolean" } }, "not": { "anyOf": [ { "required": [ "value" ] }, { "required": [ "token" ] }, { "required": [ "password" ] }, { "required": [ "secret" ] }, { "required": [ "private_key" ] }, { "required": [ "kubeconfig" ] } ] } }, "healthEndpoint": { "type": "object", "additionalProperties": false, "required": [ "name", "url", "stage", "expected_status" ], "properties": { "name": { "type": "string", "minLength": 1 }, "url": { "type": "string", "minLength": 1 }, "stage": { "$ref": "#/$defs/stageName" }, "expected_status": { "type": "integer", "minimum": 100, "maximum": 599 } } }, "observationReference": { "type": "object", "additionalProperties": false, "required": [ "name", "reference", "stage" ], "properties": { "name": { "type": "string", "minLength": 1 }, "reference": { "type": "string", "minLength": 1 }, "stage": { "$ref": "#/$defs/stageName" } } }, "check": { "type": "object", "additionalProperties": true, "required": [ "id", "type", "stage", "description", "required" ], "properties": { "id": { "type": "string", "minLength": 1 }, "type": { "enum": [ "command", "http", "kubernetes", "helm", "metric", "log", "manual" ] }, "stage": { "$ref": "#/$defs/stageName" }, "description": { "type": "string", "minLength": 1 }, "required": { "type": "boolean" } } }, "stage1": { "type": "object", "additionalProperties": false, "required": [ "enabled", "namespace", "release", "commands", "checks", "evidence", "requires_approval" ], "properties": { "enabled": { "type": "boolean" }, "namespace": { "type": "string", "minLength": 1 }, "release": { "type": "string", "minLength": 1 }, "commands": { "type": "array", "items": { "type": "string", "minLength": 1 } }, "checks": { "type": "array", "items": { "type": "string", "minLength": 1 } }, "evidence": { "type": "array", "items": { "type": "string", "minLength": 1 } }, "requires_approval": { "type": "boolean" } } }, "stage2": { "type": "object", "additionalProperties": false, "required": [ "enabled", "namespace", "release", "commands", "checks", "evidence", "requires_approval", "canary_mode", "observation_minutes" ], "properties": { "enabled": { "type": "boolean" }, "namespace": { "type": "string", "minLength": 1 }, "release": { "type": "string", "minLength": 1 }, "commands": { "type": "array", "items": { "type": "string", "minLength": 1 } }, "checks": { "type": "array", "items": { "type": "string", "minLength": 1 } }, "evidence": { "type": "array", "items": { "type": "string", "minLength": 1 } }, "requires_approval": { "type": "boolean" }, "canary_mode": { "enum": [ "weighted", "header", "path", "shadow", "isolated" ] }, "observation_minutes": { "type": "integer", "minimum": 1 }, "traffic_percent": { "type": "integer", "minimum": 0, "maximum": 100 } } }, "stage3": { "type": "object", "additionalProperties": false, "required": [ "enabled", "namespace", "release", "commands", "checks", "evidence", "requires_approval", "promotion_mode", "previous_stable" ], "properties": { "enabled": { "type": "boolean" }, "namespace": { "type": "string", "minLength": 1 }, "release": { "type": "string", "minLength": 1 }, "commands": { "type": "array", "items": { "type": "string", "minLength": 1 } }, "checks": { "type": "array", "items": { "type": "string", "minLength": 1 } }, "evidence": { "type": "array", "items": { "type": "string", "minLength": 1 } }, "requires_approval": { "type": "boolean" }, "promotion_mode": { "enum": [ "traffic-shift", "release-replace", "selector-switch", "workflow" ] }, "previous_stable": { "type": "string", "minLength": 1 } } } } }