diff --git a/linting/config/.spectral-r4.yaml b/linting/config/.spectral-r4.yaml index d81b489b..56479618 100644 --- a/linting/config/.spectral-r4.yaml +++ b/linting/config/.spectral-r4.yaml @@ -15,6 +15,7 @@ # apiRoot, 403, error codes, subscription, format descriptions, required props, # array items description, notification content-type # - 14.06.2026: Added camara-integer-safe-range rule (S-038) +# - 08.07.2026: Reworded S-038 description and message to the OpenAPI Format Registry framing # Note: @stoplight/spectral-owasp-ruleset is installed via validation/package.json. @@ -543,7 +544,7 @@ rules: recommended: true camara-integer-safe-range: - description: "Integer schema values MUST stay within the JavaScript safe-integer range." + description: "Integer schema values MUST stay within the 53-bit integer range recommended by the OpenAPI Format Registry." message: "{{error}}" severity: error given: "$" diff --git a/linting/config/lint_function/camara-integer-safe-range.js b/linting/config/lint_function/camara-integer-safe-range.js index 877c169b..0d208d04 100644 --- a/linting/config/lint_function/camara-integer-safe-range.js +++ b/linting/config/lint_function/camara-integer-safe-range.js @@ -1,9 +1,11 @@ // CAMARA Project - support function for Spectral linter -// Checks integer schema values for JavaScript safe-integer compatibility. +// Checks integer schema values against the 53-bit integer range recommended +// by the OpenAPI Format Registry for int64. // -// Release snapshot bundling passes OpenAPI YAML through JavaScript tooling. -// Numeric integer literals outside Number.MAX_SAFE_INTEGER can be silently -// rounded before the snapshot is published, so r4 validation rejects them. +// Recipients that parse JSON numbers into double-precision (binary64) +// representation cannot preserve integer literals outside the 53-bit range; +// release snapshot bundling is one such consumer and can silently round the +// value before the snapshot is published, so r4 validation rejects them. const MAX_SAFE_INTEGER = Number.MAX_SAFE_INTEGER; const INTEGER_VALUE_KEYS = [ @@ -24,11 +26,13 @@ export default (document, _options, context) => { function addFinding(value, path, label) { errors.push({ message: - `Integer schema ${label} ${String(value)} exceeds the JavaScript ` + - `safe-integer range [-${MAX_SAFE_INTEGER}, ${MAX_SAFE_INTEGER}]. ` + - "Values outside this range can be silently rounded by release " + - "bundling; use a value within range or model it as a string " + - "(CAMARA Design Guide section 2.2).", + `Integer schema ${label} ${String(value)} exceeds the 53-bit ` + + `integer range [-${MAX_SAFE_INTEGER}, ${MAX_SAFE_INTEGER}] ` + + "recommended by the OpenAPI Format Registry. Values outside this " + + "range are silently altered by tooling that parses JSON numbers " + + "into double-precision (binary64) representation, including " + + "release bundling; use a value within range or model it as a " + + "string (CAMARA Design Guide section 2.2).", path, }); } diff --git a/validation/tests/test_spectral_gap_rules.py b/validation/tests/test_spectral_gap_rules.py index 0ca00a10..8526067b 100644 --- a/validation/tests/test_spectral_gap_rules.py +++ b/validation/tests/test_spectral_gap_rules.py @@ -777,7 +777,7 @@ def test_non_id_parameter_ignored(self): class TestS038IntegerSafeRange: - """S-038: integer schema values must stay within JS safe-integer range.""" + """S-038: integer schema values must stay within the 53-bit integer range.""" def test_unsafe_int64_maximum_fires(self): spec = _VALID_SPEC + (