Skip to content

fix!: preserve unsigned command types in optimistic previews - #247

Open
patrickleet wants to merge 1 commit into
fix/aggregate-replay-event-versionfrom
fix/unsigned-command-preview
Open

fix!: preserve unsigned command types in optimistic previews#247
patrickleet wants to merge 1 commit into
fix/aggregate-replay-event-versionfrom
fix/unsigned-command-preview

Conversation

@patrickleet

Copy link
Copy Markdown
Collaborator

Unsigned revision commands can now produce typed optimistic projections. Previously, an authored u64 input became the same unrefined BigInt codec as i64, so the client compiler could not prove that it was a valid source for a U64 projection slot.

#[derive(serde::Deserialize, distributed::CommandInput)]
pub struct UpdateDocumentInput {
    pub document_id: String,
    pub expected_revision: u64,
}

The generated field still uses GraphQL BigInt and TypeScript number, with uint64_safe_integer as its command codec. A preview binding such as input.expected_revision now compiles, and preparation uses the same exact integer for the optimistic projection and dispatched input.

  • Retains unsigned width through command derives, portable application metadata, surface metadata, and fingerprints, including optional fields and list elements.
  • Rejects negative values, negative zero, fractions, non-finite values, overflow, and unsafe JavaScript integers before optimism or dispatch. Generated command results and trusted presets use the same bounds.
  • Supports u8, u16, u32, u64, and target-width usize. Browser U64 values stop at Number.MAX_SAFE_INTEGER; native Rust commands, aggregate state, and U64 projection constants retain their full range.
  • Keeps signed codecs, signed command retry fingerprints, read-model scalar codecs, GraphQL scalar syntax, and query complexity limits unchanged.

Breaking: manually constructed CommandTypeField and SurfaceTypeField values require unsigned_integer metadata. The protocol fingerprint changes, so services and generated clients must be rebuilt together. Derive users need no new annotations.

Validation:

  • cargo test --workspace --all-features --all-targets: 2,257 passed across 95 targets, 20 ignored (broker-dependent tests require their external services).
  • cargo test -p distributed_cli --lib: 251 passed
  • npm test: 394 passed
  • npm run check, package smoke test, publint, and diff checks passed. Rust formatting passed before unrelated baseline formatting-only changes were removed to keep this PR scoped.
  • A checked-in fixture is compared against actual compiler output, then executed by the JavaScript command tests.

This PR adds no application UI copy. The documentation describes numeric bounds and regeneration requirements needed to use the API correctly.

cargo clippy --all-targets -- -D warnings is not green: 36 diagnostics (5 CLI, 31 library). Running the identical command with Rust 1.98.1 on a pristine detached checkout of 16b571f117d6a9b3c2cdaaee2cfbe00f8a79ff95 produced the exact same diagnostic/message-and-file multiset; no new diagnostics were introduced. Existing examples include too_many_arguments, needless_borrow, type_complexity, and manual_async_fn. These unrelated lint changes are not included.

Stacked on #246. Its recorded CI at 16b571f117d6a9b3c2cdaaee2cfbe00f8a79ff95 already has three failures, before these changes:

Those failures are not presented as passing validation; this PR's CI is tracked separately.

Preserve typed nonnegative integer ranges through command derives, portable metadata, generated codecs and U64 projection proofs. Reject inexact browser numbers before optimism or dispatch while preserving native unsigned range and signed codecs.

BREAKING CHANGE: manually constructed command/surface fields require unsigned_integer metadata; the protocol fingerprint changes and services and generated clients must be rebuilt together.
@coderabbitai

coderabbitai Bot commented Sep 10, 2026

Copy link
Copy Markdown

Important

Review skipped

Auto reviews are disabled on base/target branches other than the default branch.

Please check the settings in the CodeRabbit UI or the .coderabbit.yaml file in this repository. To trigger a single review, invoke the @coderabbitai review command.

⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Advanced

Run ID: 08da373d-1914-4f1e-86f3-405a9e3d2371

You can disable this status message by setting the reviews.review_status to false in the CodeRabbit configuration file.

Use the checkbox below for a quick retry:

  • 🔍 Trigger review

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands.

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

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant