extends: - "spectral:oas" formats: - "oas3" rules: stella-info-title: description: "OpenAPI info.title must be present" message: "Add a descriptive `info.title`" given: "$.info.title" severity: error then: function: truthy stella-info-version: description: "OpenAPI info.version must be present" message: "Set `info.version` (SemVer or release tag)" given: "$.info.version" severity: error then: function: truthy stella-servers-https: description: "Servers should use https" given: "$.servers[*].url" severity: warn then: function: pattern functionOptions: match: "^https://" operation-operationId-required: description: "Every operation must have an operationId" message: "Add an `operationId` for this operation" given: "$.paths[*][*]" severity: error then: field: operationId function: truthy stella-2xx-response-examples: description: "Every 2xx response must include at least one example" message: "Add an example or examples block to 2xx responses" given: "$.paths[*][*].responses[?(@property.match(/^2\\d\\d$/))].content.*" severity: error then: function: schema functionOptions: schema: anyOf: - required: [examples] - required: [example] stella-pagination-params: description: "Collection GETs (list/search) must expose limit/cursor parameters" message: "Add limit/cursor parameters for paged collection endpoints" given: "$.paths[*][get]" severity: warn then: function: schema functionOptions: schema: type: object properties: operationId: type: string allOf: - if: properties: operationId: pattern: "([Ll]ist|[Ss]earch|[Qq]uery)" then: required: [parameters] properties: parameters: type: array allOf: - contains: anyOf: - required: ['$ref'] properties: $ref: pattern: 'parameters/LimitParam$' - required: [name, in] properties: name: const: limit in: const: query - contains: anyOf: - required: ['$ref'] properties: $ref: pattern: 'parameters/CursorParam$' - required: [name, in] properties: name: const: cursor in: const: query stella-idempotency-header: description: "State-changing operations returning 201/202 should accept Idempotency-Key headers" message: "Add Idempotency-Key header parameter for idempotent submissions" given: "$.paths[*][?(@property.match(/^(post|put|patch)$/))]" severity: warn then: function: schema functionOptions: schema: type: object properties: responses: type: object parameters: type: array allOf: - if: properties: responses: type: object anyOf: - required: ['201'] - required: ['202'] then: required: [parameters] properties: parameters: type: array contains: type: object properties: name: const: Idempotency-Key in: const: header required: [name, in] stella-operationId-style: description: "operationId must be lowerCamelCase" given: "$.paths[*][*].operationId" severity: warn then: function: casing functionOptions: type: camel stella-jobs-idempotency-key: description: "Orchestrator job submissions must accept Idempotency-Key header" given: "$.paths['/jobs'].post.parameters" severity: warn then: function: schema functionOptions: schema: type: array contains: type: object properties: name: const: Idempotency-Key in: const: header required: [name, in]