Skip to content

IPC v1: use portable bounds for all JSON integers #419

Description

@mamoreau-devolutions

Context

Request IDs are correctly limited to JavaScript's exactly representable integer maximum (9007199254740991), but several other protocol integers permit the full unsigned 64-bit range.

Problem

schema/ipc/v1/common.schema.json and protocol-specific schemas allow values up to 18446744073709551615 for fields including deadlines, retry delays, expiries, and authorization durations. Rust models these as u64.

Common JSON/OpenRPC clients—especially JavaScript/TypeScript clients using number and ordinary JSON.parse—cannot round-trip integers above 2^53 - 1 exactly. A deadline or expiry may silently change value before validation, signature/correlation logic, or comparison. The protocol already acknowledges this portability constraint for request IDs, so applying a different numeric model to timestamps/durations is surprising.

Suggested resolution

Before freezing v1, choose one wire-wide rule:

  1. Recommended: constrain every JSON integer to the exactly representable range 0..=9007199254740991 (or 1..= where positive), including deadline_unix_ms, retry_after_ms, expires_at_unix_ms, requested_authorization_duration_ms, and protocol-specific TTL/expiry fields; or
  2. encode potentially larger integer fields as canonical decimal strings.

The first option is simpler and still represents epoch milliseconds for hundreds of thousands of years.

Update schemas, Rust validation, C parsing, docs, and fixtures together. Do not rely on a language binding to discover after parsing that precision was already lost.

Deterministic coverage

Add cross-language cases for:

  • fractional values;
  • negative values where unsigned/positive is required;
  • 2^53 - 1 accepted;
  • 2^53 rejected;
  • u64::MAX rejected;
  • boundary values passing identically through the C and Rust clients.

Activity

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions