Skip to content

feat: port Rust core runtime#104

Closed
pgherveou wants to merge 138 commits into
mainfrom
worktree-issue-96-rust-core-port
Closed

feat: port Rust core runtime#104
pgherveou wants to merge 138 commits into
mainfrom
worktree-issue-96-rust-core-port

Conversation

@pgherveou

@pgherveou pgherveou commented May 17, 2026

Copy link
Copy Markdown
Collaborator

Summary

Umbrella 👉 #104 ports dotli onto the shared Rust TrUAPI core and makes the Rust crates the source of truth for protocol dispatch, generated product/client types, host capability bindings, auth/session state, permissions, SSO/signing orchestration, chainHead, preimage, theme, notification, and host-wasm plumbing.

Recent updates tighten the runtime permission model and lifecycle cleanup, generate the wasm host bridge from platform trait metadata, switch the JS host callback surface to namespaces, and update dotli to consume that surface.

Reviewable Stack

This PR is the cumulative view. Please review and merge the active child PRs bottom-up; the top child PR has the same tree as this umbrella branch.

  1. feat(truapi): add testing API and versioned wiring #248 - layer 1/9, merged historical: truapi testing API and versioned wiring.
  2. feat(truapi-platform): add host capability traits #249 - layer 2/9, merged historical: truapi-platform host capability traits.
  3. feat(truapi-codegen): emit Rust dispatcher, wire table, and host callbacks #254 - layer 3/9, merged historical: codegen Rust dispatcher, wire table, and host callbacks.
  4. feat(truapi-server): add host logic primitives #255 - layer 4/9, merged historical: server host logic primitives.
  5. feat(truapi-server): add wire and chain infrastructure #256 - layer 5/9, merged historical: server wire and chain infrastructure.
  6. feat(truapi-server): add platform runtime and host bridge #250 - active layer 1/4: server runtime, permissions, lifecycle, and permission-flow docs.
  7. feat(codegen): generate wasm bridge callbacks #265 - active layer 2/4: generic wasm bridge/codegen layer.
  8. feat(host-wasm): add @parity/truapi-host-wasm runtime #252 - active layer 3/4: @parity/truapi-host-wasm namespaced callback consumer.
  9. chore: docs, CI, tooling, and dotli integration for the Rust core #253 - active layer 4/4, top: docs, CI/tooling, playground, and dotli integration.

This umbrella is the cumulative review target for the whole port; active child #253 is kept tree-equivalent with it.

Architecture

Validation

  • cargo fmt --all --check
  • cargo check -p truapi-server
  • cargo test -p truapi-codegen golden_
  • cargo test -p truapi-server
  • cd js/packages/truapi-host-wasm && npm run build && npm test
  • make dev
  • cd hosts/dotli && bun run typecheck && bun run test

The remote top stack tree was verified equal to this umbrella tree locally before push.

@socket-security

socket-security Bot commented May 17, 2026

Copy link
Copy Markdown

Review the following changes in direct dependencies. Learn more about Socket for GitHub.

Diff Package Supply Chain
Security
Vulnerability Quality Maintenance License
Addednpm/​jsqr@​1.4.010010010075100
Addednpm/​@​parity/​truapi-host@​0.1.0N/AN/AN/AN/AN/A

View full report

@pgherveou pgherveou marked this pull request as draft May 17, 2026 16:22
pgherveou added a commit that referenced this pull request May 18, 2026
Bug fixes:
- Makefile uniffi target now writes Swift bindings through a tempdir
  and copies into the actual SwiftPM layout (Sources/TrUAPIHost/ for
  the .swift file, Sources/truapi_serverFFI/include/ for the C header
  and module.modulemap). Cdylib path picks .dylib on macOS.
- electron provider: onClose sets disposed=true and clears listener
  sets so subsequent postMessage no-ops cleanly and close listeners
  don't fire twice if the caller also calls dispose().
- web worker provider: init-failure paths call worker.terminate()
  before rejecting so a failed core init doesn't leak the worker.
- createWebSocketProvider: subscribe / subscribeClose use Set instead
  of Array+indexOf so double-registration of the same callback is
  idempotent (matches the other providers in the package).

Test coverage:
- New js/packages/truapi/test/ws-provider.test.mjs exercises the WS
  provider against a stubbed WebSocket constructor (queue+flush,
  fan-out, set semantics, close fan-out, post-after-close throws).

Doc + style fixes:
- docs/design/dotli-architecture-change.md describes featureSupported
  as a current callback with a planned removal, matching the platform
  trait and the host shells. The implementation-vs-doc contradiction
  is gone.
- Migration narrative stripped from runtime.rs, wasm.rs, native.rs,
  host_logic/features.rs, the Kotlin shell, and the Swift shell.
- Em-dashes swept from 18 PR-scope files (CLAUDE.md, both design
  docs, both native READMEs, the TS host packages, a few platform
  doc comments).
- create-iframe-host.ts comment now describes current behaviour
  without referencing the "legacy fallback".
- tests/object_safety.rs renamed to tests/bounds.rs with a docstring
  that matches what the test actually asserts (the trait isn't
  object-safe; the bound check is on Send + Sync + 'static).
- iOS: drop dead `_ = self.callbackRetainer` line; explain the
  retainer in plain prose instead of via a no-op suppression.
- Android: drop redundant @Suppress("unused") on a property that is
  read in init.

Deferred to follow-up issues (#105-#111).
@pgherveou pgherveou changed the title feat: port Rust core runtime from truapi_next prototype feat: port Rust core runtime May 18, 2026
pgherveou added a commit that referenced this pull request May 30, 2026
Harden the Rust core runtime and host SDKs against the review of the core
port. No change to the wire protocol or the generated artifacts (codegen
regenerates byte-identically; the committed WASM bundle is rebuilt).

truapi-server:
- Subscriptions use generation-stamped reservation slots: a reused or raced
  request_id stops-and-replaces instead of leaking an unstoppable stream, and
  a _stop arriving before activation cancels the pending subscription.
  Unregistered methods answer Unsupported instead of leaving the caller to
  hang. Dead negotiated_version slot and interrupt API removed.
- chainHead-v1 runtime: single-flight follow setup (no duplicate or leaked
  remote subscriptions), the close-vs-insert race in request_value is closed
  so a caller can no longer hang forever, the pending follow-event buffer is
  bounded, and an orphaned remote follow is unfollowed when its local follow
  is torn down mid-setup.
- WS bridge: constant-time token comparison, bounded inbound message size,
  bounded outbound queue and connection count, documented loopback trust
  model.
- wasm surface registers a panic hook and surfaces non-boolean / non-string
  host returns as errors; permissions persist only genuine user decisions, so
  a transient prompt-callback error no longer locks a capability out; dotns
  classifies trailing-dot FQDNs and lowercases/de-dupes remote domains;
  navigate_to returns an error instead of panicking on a contract violation.
- smoldot provider is wired into the runtime behind its feature (with a
  platform fallback), with finite json-rpc ceilings, a distinguishable
  reconnect error, and Apache-2.0 attribution (SPDX headers +
  THIRD_PARTY_NOTICES.md).
- Tests: subscription-race regressions, malformed-frame drop, subscription
  lifecycle through the wire boundary, and a hardened Rust<->TS wire-table
  parity check (panics on unparseable ids, compares all four subscription
  ids, asserts a row-count floor).

codegen: Rust dispatcher/wire-table emitters use writedoc!/formatdoc!
(byte-identical output); TS host-callbacks handles bare trait-object returns.

JS hosts: worker-runtime faults now reach close subscribers; the WebSocket
provider is built on the shared close-once base provider; the electron
provider detaches port listeners on remote close; new tests for the node
WASM round-trip, WS error/non-binary/CLOSING paths, and the iframe
handshake/origin/dispose paths.

native: Android and iOS HostBridge document that callbacks fire on the
truapi-ws-bridge worker thread; the iOS bootstrap uses a JSONEncoder-based JS
string-literal escaper; Maven coordinates reconciled across build.gradle.kts,
jitpack.yml, and the README.

CI/docs: host-packages CI runs the host-shared smoke test against the
freshly built WASM bundle and triggers on truapi-platform changes; the
Makefile wasm target no longer hides the committed bundle; design docs and
the truapi-platform README are reconciled to the shipped trait set.
@pgherveou

Copy link
Copy Markdown
Collaborator Author

Superseded by a 3-PR stack carved from this branch, each independently reviewable and green on CI:

Review bottom-up. Authored with assistance from Claude Code.

@pgherveou pgherveou closed this Jun 12, 2026
@pgherveou pgherveou reopened this Jun 12, 2026
Comment thread js/packages/truapi-host-wasm/src/web/create-worker-host-runtime.ts Outdated
Comment thread js/packages/truapi-host-wasm/src/web/create-worker-host-runtime.ts Outdated
Comment thread js/packages/truapi-host-wasm/src/web/create-worker-host-runtime.ts Outdated
Comment thread js/packages/truapi-host-wasm/src/node-runtime.ts Outdated
Comment thread js/packages/truapi/src/transport.ts Outdated
Comment thread js/packages/truapi/src/wire-tags.ts Outdated
Comment thread docs/design/host-contract-and-core-impl/A - host-primitives.md Outdated
Comment thread playground/src/components/DiagnosisView.tsx
Comment thread rust/crates/truapi/src/api/account.rs Outdated
Comment thread rust/crates/truapi/src/v01/permissions.rs Outdated
@pgherveou

Copy link
Copy Markdown
Collaborator Author

Follow-up update: PR #214 was merged back into this PR branch so the parent can run e2e, and #214 is now closed as superseded. Mobile host scaffolding/config/CI moved to child PR #215.

@pgherveou pgherveou force-pushed the worktree-issue-96-rust-core-port branch from 341366d to c5fb5c9 Compare June 14, 2026 09:29
pgherveou added a commit that referenced this pull request Jun 26, 2026
The truapi-ready/truapi-init handshake pairs with the WASM host's
createIframeHost (#104). Keep sandbox.ts at base so merging to main does not
break the deployed playground against the current host.
@pgherveou pgherveou changed the base branch from main to slim/js-playground-extract June 26, 2026 10:22
Base automatically changed from slim/js-playground-extract to main June 26, 2026 10:48
@pgherveou pgherveou force-pushed the worktree-issue-96-rust-core-port branch from a0793b9 to 5f03570 Compare June 28, 2026 10:00
decrypto21 added a commit that referenced this pull request Jul 8, 2026
decrypto21 added a commit that referenced this pull request Jul 8, 2026
decrypto21 added a commit that referenced this pull request Jul 8, 2026
…ductRuntimeConfig, WasmPairingHostRuntime, mock.dot id)
decrypto21 added a commit that referenced this pull request Jul 8, 2026
pgherveou added 13 commits July 8, 2026 15:33
Publish the host runtime as @parity/truapi-host and move the dotli diagnosis harness into the playground repo.
…t-core-port

# Conflicts:
#	rust/crates/truapi-codegen/tests/golden/host-callbacks-adapter.ts
#	rust/crates/truapi-codegen/tests/golden/host-callbacks.ts
#	rust/crates/truapi-codegen/tests/golden/worker-callbacks.ts
#	rust/crates/truapi-codegen/tests/golden_rust_emit.rs
#	rust/crates/truapi-server/src/lib.rs
Add wasm32 CI and make check coverage, avoid leaking signer callbacks, and reject compound codec callback boundaries during codegen.
Subscription and chain response callbacks re-enter the WASM core from the shared worker. If one of those callbacks panicked, the exception escaped the worker message handler and could terminate the shared worker for every tab.\n\nRoute those dispatches through guarded helpers that stop only the affected subscription or chain connection and report a non-fatal worker warning. Add unit coverage for both guarded paths.
Host callback streams previously logged iterator and Result errors and then stopped pumping, leaving the Rust subscription stream waiting forever.

Add an explicit sendError sink beside sendItem for raw WASM subscriptions. Direct and worker-backed host callbacks now forward stream failures as GenericError values into the Rust platform stream, so products observe subscription errors instead of hanging.
The iframe host always transferred the capability MessagePort with targetOrigin "*", and the ready gate accepted "null" even for the default same-origin sandbox. That left the handoff relying only on the source-window check.

Derive opaque-origin handling from the sandbox attribute. The default allow-same-origin sandbox now pins the port transfer to the product origin and rejects "null" ready messages; only explicitly opaque sandboxes keep the required "*" transfer path.
The sandbox iframe handshake had no product-side tests, accepted opaque init origins even when the parent origin was known, and tied the cached port handshake cleanup to the first caller's AbortSignal. That made the security boundary underspecified and overlapping startup calls fragile.

Add focused sandbox handshake tests, reject mismatched init origins when the host origin is resolved, keep the data-free wildcard ready ping documented for hidden-origin browsers, and wrap the shared port promise with per-caller abort handling.
The release job pushed tags before publishing and used tag existence to decide idempotency. With checkout credentials disabled the plain git push could fail, and a pushed tag could make a failed downstream publish skip on retry.

Resolve publish targets from npm registry state, attest packed tarballs, dispatch publish before release metadata, and create tags/releases idempotently with explicit GitHub token auth.
The signer-bot helper only scrubbed a literal mnemonic field, and the non-OK pair error included the raw response body. If the bot returns a seed, secret phrase, private key, or similar field, CI logs could expose it.

Redact a normalized set of signer secret fields from JSON responses, keep a quoted-field fallback for malformed bodies, and reuse the redacted text when surfacing pair failures.
@pgherveou pgherveou force-pushed the worktree-issue-96-rust-core-port branch from d37c86b to f341d5b Compare July 10, 2026 11:34
…t-core-port

# Conflicts:
#	rust/crates/truapi-codegen/src/ts/host_callbacks.rs
#	rust/crates/truapi-codegen/tests/golden/host-callbacks-adapter.ts
#	rust/crates/truapi-server/src/lib.rs
#	rust/crates/truapi-server/src/wasm.rs
@pgherveou pgherveou force-pushed the worktree-issue-96-rust-core-port branch from 30f6d60 to 72094ac Compare July 10, 2026 13:49
@pgherveou pgherveou closed this Jul 10, 2026
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