extends: - recommended rules: # Proprietary internal license -- no SPDX identifier or public URL exists. info-license-strict: off rule/info-title-api: subject: type: Info property: title assertions: pattern: /.*API.*/ rule/info-description: subject: type: Info property: description assertions: defined: true operation-4xx-response: error # Off: the live contract is {"error": string} as plain application/json # (serialization.py error_response). Adopting RFC 7807 would be a runtime # + SHOC-contract change, decided against 2026-07-24. operation-4xx-problem-details-rfc7807: off operation-operationId: error rule/operationId-casing: subject: type: Operation property: operationId assertions: casing: kebab-case rule/operationId-prefix: subject: type: Operation property: operationId assertions: pattern: /^GET|PUT|POST|DELETE|OPTIONS|HEAD|PATCH|TRACE/i rule/operation-summary-period: subject: type: Operation property: summary assertions: pattern: /[^.]$/ path-not-include-query: error # No parameter-casing rule: path parameter names (workOrderId, poNumber, # siteCode) are camelCase by contract -- they are baked into the API Gateway # resource paths and read by the handler's pathParameters lookup. rule/params-must-include-examples: severity: error subject: type: Parameter assertions: requireAny: - example - examples no-http-verbs-in-paths: error no-ambiguous-paths: error path-segment-plural: severity: error exceptions: - docs - openapi.json paths-kebab-case: error no-invalid-schema-examples: error # No schema-properties casing rule: property names mirror the DynamoDB # items and the shipped SHOC webhook contract -- snake_case for WO/PO # tables, camelCase for verified-sites (legacy, issue #24). Not lintable # to one casing without a contract break. # Error bodies must carry the top-level "error" field (the Error schema). # 403 is exempt: it is emitted by API Gateway's SigV4 layer with AWS's # {"message"} shape, not by the Lambda. response-contains-property: severity: error names: '400': - error '401': - error '404': - error '501': - error request-mime-type: severity: error allowedValues: - application/json response-mime-type: severity: error allowedValues: - application/json - text/html no-server-example.com: error rule/no-server-localhost: subject: type: Server property: url assertions: notPattern: /(localhost|127.0.0.1) operation-singular-tag: error operation-tag-defined: error rule/tag-description: subject: type: Tag property: description assertions: defined: true rule/description-capitalization: subject: type: any property: description assertions: pattern: /^([A-Z]|true|seahaven-prod)/ rule/description-punctuation: subject: type: any property: description assertions: pattern: /(\.|server)$/ rule/avoid-words-in-descriptions: subject: type: any property: description assertions: notPattern: /(simply|easy|easily|just|obviously|notethat)/i