Skip to content

fix(core): state integer proofs in sdk/text.ts range constructors - #394

Open
sapjax wants to merge 1 commit into
vercel-labs:mainfrom
sapjax:fix/text-ts-integer-proofs
Open

fix(core): state integer proofs in sdk/text.ts range constructors#394
sapjax wants to merge 1 commit into
vercel-labs:mainfrom
sapjax:fix/text-ts-integer-proofs

Conversation

@sapjax

@sapjax sapjax commented Aug 21, 2026

Copy link
Copy Markdown

Problem

The shipped packages/core/sdk/text.ts (v0.9.5, unchanged on main) fails the pinned scriptc 0.0.33 integer-boundary checks — 19 × SC4022/SC4023 errors on every TextRange/TextSelection construction that isn't routed through caretSelectionAt:

sdk/text.ts:79:34 - error SC4023: integer slot 'TextRange.start' (i64) cannot be proven — range failed: the proven range [-Infinity, 9007199254740991] does not fit [-9007199254740991, 9007199254740991] — integrality is provable only within ±(2^53 − 1)
sdk/text.ts:79:63 - error SC4022: integer slot 'TextRange.start' (i64) cannot be proven — wholeness failed: the value may be NaN, which is not a whole number
…

Any TS-core app that imports @native-sdk/core/text — i.e. every app with a text field — fails native build. Note native check stays green: this refusal comes from the external core compiler's integer-boundary proofs, not the NS subset checker, and the repo's external-compiler tests stub scriptc with a fixture, so CI never compiles this module with the real pinned compiler.

Fix

State each offset whole in place, using the module's own established idiom — caretSelectionAt already documents exactly this pattern:

offsets are whole byte offsets by contract, proven in place — range-guarded (an ordered comparison excludes NaN) and stated whole with Math.trunc. A value outside the provable ±(2^53 − 1) window clamps to 0, the same floor every caller's snap already applies.

This extends that form to rangeNormalized, snapTextRange, setTextComposition, and the six delete-* edit paths. No behavior change on reachable values: every internal producer already returns whole, non-negative byte offsets ≤ text length.

Verification

  • Reproduced all 19 SC4022/SC4023 errors on an app importing @native-sdk/core/text with the unpatched module; with this patch the same app builds clean (native build, ReleaseFast).
  • node --test packages/core/test/text.test.ts — 6/6 pass.
  • Differential fuzz vs the unpatched module: 4000 rounds / ~23k applied applyTextInputEvent + clampedInsertEvent calls over random UTF-8 text (multibyte, CRLF, selections, compositions, capacity refusals) — byte-identical states.
  • tsc --noEmit --strict clean on the patched module.

Possible follow-up (out of scope here): a CI lane that compiles sdk/text.ts / sdk/events.ts with the real pinned scriptc would catch this class of regression — the current external-compiler tests stub scriptc.

sdk/text.ts fails the pinned scriptc 0.0.33 integer-boundary checks
(SC4022/SC4023, 19 errors) on every TextRange/TextSelection construction
that is not routed through caretSelectionAt — any TS-core app importing
@native-sdk/core/text (every app with a text field) cannot build.

State each offset whole in place with the module's own established idiom
(the range-guard + Math.trunc form caretSelectionAt already documents):
an ordered comparison excludes NaN and Math.trunc states wholeness, with
out-of-window values clamping to 0, the same floor every snap applies.

Semantics-preserving on all reachable values: node --test
packages/core/test/text.test.ts passes, and a differential fuzz of
applyTextInputEvent/clampedInsertEvent against the unpatched module
(4000 rounds, ~23k applied events over UTF-8, CRLF, composition and
capacity-refusal paths) produces byte-identical states.
@vercel

vercel Bot commented Aug 21, 2026

Copy link
Copy Markdown

@sapjax is attempting to deploy a commit to the Vercel Labs Team on Vercel.

A member of the Team first needs to authorize it.

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