Skip to content

feat: tick-rate mount contract — ui.__tickHz handshake, rebuilt xcframework (0.2.1) - #1

Merged
NathanWalker merged 2 commits into
mainfrom
feat/tick-rate-contract
Aug 14, 2026
Merged

feat: tick-rate mount contract — ui.__tickHz handshake, rebuilt xcframework (0.2.1)#1
NathanWalker merged 2 commits into
mainfrom
feat/tick-rate-contract

Conversation

@NathanWalker

Copy link
Copy Markdown
Contributor

Prep for 0.2.1 — the tick-rate release owed since 0.2.0 shipped ahead of the engine-side review (see RELEASE-PLAN-0.2.1.md, updated on this branch). The contract is now settled on pocket-stack/pocketjs#257 (head d6ae5f0): the rate is declared before eval_bundle, published to the guest at mount as ui.__tickHz, and every bundle refuses a host driving a rate other than its baked one.

What changed

  • PocketHostView._mountUi publishes __tickHz next to __host/__hostAbi — external-guest mode's half of the pairing handshake. The value is read from the surface's accepted rate, so it is always what the core actually runs.
  • tickRate gained a setNative: same-value re-application (property application after createNativeView already declared the rate) is skipped; a genuinely late change is pushed so the new surface refuses it through the error event instead of the display link silently diverging from the realm's step.
  • Rebuilt PocketApple.xcframework from the #257 head: call order create → load_pak* → [set_identity] → [set_tick_rate] → eval_bundle, PocketSurfaceView applies tickRate in its setter (start only pins the display link), and the embedded surface publishes __tickHz for PocketView's guest mode.
  • README (usage, identity handshake, provenance now citing #257) and index.d.ts contract text; version 0.2.1.

Compatibility

60 Hz bundles mount on every plugin version — an absent __tickHz means the 60 default, which is all any pre-rate host ever drove. Non-60 bundles refuse 0.2.0 loudly (nothing in it declares a rate) and require this release.

Validation (iPhone 17 Pro Max simulator, iOS 26.5)

  • Guest mode: pocket ios play nsengine --hz=120 --density=4 --plugin-path=<this checkout>[pocket-shell] guest loaded, nsengine renders fully, spinner animating, guest↔host ping round-trip live (screenshot-verified).
  • External-guest mode: pocket ios play nsengine --external-guest --no-build --plugin-path=<this checkout> — the new build stamp staged tickHz: 120 with no --hz flag (previously this silently staged 60), and the bundle mounted against the plugin-published __tickHz.
  • npm pack ships 18 files / 2.7 MB; both xcframework slices carry the new pocket_apple.h contract and PocketSurfaceView.h setter docs.

Before publishing (do not merge until then)

  1. feat(core): per-realm tick rate — fixed-step at a declared hz pocket-stack/pocketjs#257 merges (then #258).
  2. Rebuild the xcframework from post-merge main and re-vendor — the binary here is a build of the branch head, kept so this PR is testable end-to-end; the shipped one must be a build of upstream.
  3. npm publish, then the one-line ns-shell pin bump (0.2.00.2.1) upstream.

🤖 Generated with Claude Code

… xcframework

The 0.2.1 prep owed since 0.2.0 shipped ahead of the engine-side review
(pocket-stack/pocketjs#257). The contract is now settled upstream: the
rate is declared before eval_bundle, published to the guest at mount as
ui.__tickHz, and every bundle refuses a host driving a rate other than
the one it was baked with.

- PocketHostView._mountUi publishes __tickHz next to __host/__hostAbi,
  read from the surface's accepted rate so it always reflects what the
  core actually runs.
- tickRate gains a setNative: same-value re-application after
  createNativeView is skipped; a genuinely late change is pushed so the
  surface refuses it through the error event instead of the display
  link silently diverging from the realm's step.
- PocketApple.xcframework rebuilt from the #257 head (both slices):
  create -> load_pak* -> [set_identity] -> [set_tick_rate] ->
  eval_bundle, PocketSurfaceView applies tickRate in its setter, the
  embedded surface publishes __tickHz for guest mode.
- README/index.d.ts contract text; version 0.2.1;
  RELEASE-PLAN-0.2.1.md updated with the remaining publish sequence
  (rebuild from post-merge main before npm publish).

Validated on the iOS 26.5 simulator in both modes with a 120 Hz
nsengine build: guest mode renders with the effect channel live;
external-guest mode mounts against the plugin-declared rate and reads
iOS 26.5 through the NativeScript bindings.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
@coderabbitai

coderabbitai Bot commented Aug 14, 2026

Copy link
Copy Markdown

Important

Review skipped

Auto reviews are disabled on this repository. 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: Organization UI

Review profile: CHILL

Plan: Pro Plus

Run ID: 475315f8-77bc-4c42-8b4e-8c03d238da7e

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.

Same headers, binaries rebuilt from pocket-stack/pocketjs main after #257
and #258 merged (picks up #270's guest-allocator change). Verified: both
slices export the tick-rate ABI; render_hero at declared 120 Hz gives 180
deterministic non-blank frames with damage_px matching the upstream
merge-time verification.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
@NathanWalker
NathanWalker marked this pull request as ready for review August 14, 2026 17:24
@NathanWalker
NathanWalker merged commit e0eb9fe into main Aug 14, 2026
1 check passed
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