{ "$schema": "https://json-schema.org/draft/2020-12/schema", "$id": "https://railiance.dev/schemas/rail.schema.json", "title": "Railiance rail declaration", "description": "Normative shape for declarations/rail.yaml in every rail-* repo. Authored by railiance-master under RMASTER-WP-0021-T04 from the two live rails and docs/rail-composition-contract.md. Codifies current practice; it does not tighten the rail family beyond what both live declarations already carry.", "type": "object", "additionalProperties": false, "required": [ "kind", "rail_id", "repo", "ownership_repo", "contract_version", "composition_kind", "execution_architecture", "readiness_state", "required_substrate_capabilities", "supported_rollout_modes" ], "properties": { "kind": { "const": "execution-rail", "description": "Fixed discriminator. Both live rails already agree on this value." }, "rail_id": { "$ref": "#/$defs/railSlug", "description": "Canonical identifier for the rail. Must equal the repo slug." }, "repo": { "$ref": "#/$defs/repoSlug", "description": "The rail-* repo holding this declaration." }, "ownership_repo": { "$ref": "#/$defs/repoSlug", "description": "The ownership-axis repo accountable for this execution contract. Both live rails name railiance-cluster." }, "contract_version": { "$ref": "#/$defs/semver", "description": "Version of this rail contract. A derived rail pins the base contract with base_rail_contract, which is a separate field." }, "composition_kind": { "enum": ["base", "derived"], "description": "base owns a complete workload execution contract for a substrate class. derived inherits a versioned base-rail contract and owns only its specialization. See docs/rail-composition-contract.md and ADR-0005." }, "execution_architecture": { "type": "string", "minLength": 3, "description": "The operations architecture this rail names, e.g. kubernetes, knative-serving-on-kubernetes. Free-form on purpose: a new rail is justified by new semantics, not by an enum update." }, "readiness_state": { "enum": ["declared", "installed", "verified", "production-approved", "deprecated"], "description": "Readiness of the rail contract itself, matching docs/rail-composition-contract.md. Distinct from rapp readiness_state (draft/declared/deployed/verified/retired) and from reef lifecycle_state. Do not unify the three vocabularies without a separate decision." }, "required_substrate_capabilities": { "type": "array", "minItems": 1, "uniqueItems": true, "items": { "type": "string", "minLength": 1 }, "description": "Capabilities the substrate must publish before this rail is usable. This is the live name; the bootstrap contract's older substrate_prerequisites label is retired in favour of this field." }, "supported_rollout_modes": { "type": "array", "minItems": 1, "uniqueItems": true, "items": { "type": "string", "minLength": 1 }, "description": "Rollout modes this rail supports, e.g. stage1-run, revision-canary." }, "default_for": { "type": "array", "minItems": 1, "uniqueItems": true, "items": { "type": "string", "minLength": 1 }, "description": "Workload classes this rail is the default for. Present on the base rail today; optional so a derived rail is not forced to claim default status." }, "compatibility_notes": { "$ref": "#/$defs/notes", "description": "Human-readable caveats. Never load-bearing." }, "base_rail": { "$ref": "#/$defs/railSlug", "description": "Required on derived rails. The rail whose contract is inherited." }, "base_rail_contract": { "$ref": "#/$defs/semver", "description": "Required on derived rails. Exact contract_version of the base rail this derivation is written against. Ranges are not pins." }, "inherited_semantics": { "type": "array", "minItems": 1, "uniqueItems": true, "items": { "type": "string", "minLength": 1 }, "description": "Required on derived rails. Semantics taken from the base contract rather than restated." }, "overridden_semantics": { "type": "array", "minItems": 1, "uniqueItems": true, "items": { "type": "string", "minLength": 1 }, "description": "Required on derived rails. The only semantics this rail owns. If this list is empty the derived rail has no reason to exist." }, "compatibility_constraints": { "type": "array", "minItems": 1, "items": { "type": "string", "minLength": 1 }, "description": "Required on derived rails. Constraints a substrate or binding must satisfy to use this derivation." }, "source_documents": { "type": "array", "minItems": 1, "items": { "$ref": "#/$defs/sourceDocument" } } }, "allOf": [ { "description": "A derived rail must name its base contract and the semantics it inherits or overrides.", "if": { "properties": { "composition_kind": { "const": "derived" } }, "required": ["composition_kind"] }, "then": { "required": [ "base_rail", "base_rail_contract", "inherited_semantics", "overridden_semantics", "compatibility_constraints" ] } }, { "description": "A base rail must not carry derived-only fields. Those fields would imply an inheritance it does not have.", "if": { "properties": { "composition_kind": { "const": "base" } }, "required": ["composition_kind"] }, "then": { "not": { "anyOf": [ { "required": ["base_rail"] }, { "required": ["base_rail_contract"] }, { "required": ["inherited_semantics"] }, { "required": ["overridden_semantics"] }, { "required": ["compatibility_constraints"] } ] } } } ], "$defs": { "repoSlug": { "type": "string", "pattern": "^[a-z0-9]+(-[a-z0-9]+)*$", "minLength": 2 }, "railSlug": { "type": "string", "pattern": "^rail-[a-z0-9]+(-[a-z0-9]+)*$" }, "semver": { "type": "string", "pattern": "^(0|[1-9]\\d*)\\.(0|[1-9]\\d*)\\.(0|[1-9]\\d*)$" }, "notes": { "type": "array", "items": { "type": "string", "minLength": 1 }, "description": "Human-readable caveats. Never load-bearing: nothing may depend on parsing a note." }, "sourceDocument": { "type": "object", "additionalProperties": false, "required": ["repo", "path"], "properties": { "repo": { "$ref": "#/$defs/repoSlug" }, "path": { "type": "string", "minLength": 1 } } } } }