Skip to content

chore: rivetkit core/napi/typescript follow up review#4702

Draft
NathanFlurry wants to merge 1 commit into04-22-chore_fix_remaining_issues_with_rivetkit-corefrom
04-22-chore_rivetkit_core_napi_typescript_follow_up_review
Draft

chore: rivetkit core/napi/typescript follow up review#4702
NathanFlurry wants to merge 1 commit into04-22-chore_fix_remaining_issues_with_rivetkit-corefrom
04-22-chore_rivetkit_core_napi_typescript_follow_up_review

Conversation

@NathanFlurry
Copy link
Copy Markdown
Member

Description

Please include a summary of the changes and the related issue. Please also include relevant motivation and context.

Type of change

  • Bug fix (non-breaking change which fixes an issue)
  • New feature (non-breaking change which adds functionality)
  • Breaking change (fix or feature that would cause existing functionality to not work as expected)
  • This change requires a documentation update

How Has This Been Tested?

Please describe the tests that you ran to verify your changes.

Checklist:

  • My code follows the style guidelines of this project
  • I have performed a self-review of my code
  • I have commented my code, particularly in hard-to-understand areas
  • I have made corresponding changes to the documentation
  • My changes generate no new warnings
  • I have added tests that prove my fix is effective or that my feature works
  • New and existing unit tests pass locally with my changes

@railway-app
Copy link
Copy Markdown

railway-app Bot commented Apr 23, 2026

🚅 Deployed to the rivet-pr-4702 environment in rivet-frontend

Service Status Web Updated (UTC)
website 😴 Sleeping (View Logs) Web Apr 23, 2026 at 8:11 am
frontend-cloud ❌ Build Failed (View Logs) Web Apr 23, 2026 at 8:05 am
frontend-inspector ❌ Build Failed (View Logs) Web Apr 23, 2026 at 8:05 am
ladle ✅ Success (View Logs) Web Apr 23, 2026 at 8:05 am
kitchen-sink ❌ Build Failed (View Logs) Web Apr 23, 2026 at 8:03 am
mcp-hub ✅ Success (View Logs) Web Apr 23, 2026 at 3:55 am

Copy link
Copy Markdown
Member Author

NathanFlurry commented Apr 23, 2026

Warning

This pull request is not mergeable via GitHub because a downstack PR is open. Once all requirements are satisfied, merge this PR as a stack on Graphite.
Learn more

This stack of pull requests is managed by Graphite. Learn more about stacking.

@claude
Copy link
Copy Markdown

claude Bot commented Apr 23, 2026

PR 4702 Code Review — Adversarial Review Synthesis

The full adversarial review findings (F1-F42) with challenger verdicts are in this comment. The per-diff code review is in the comment below.

Key findings verified as REAL in this PR:

  • F3: clean run exit fix (task.rs) - FIXED in this PR
  • F12: Registry.handler()/serve() throw - spec written (handler-serve-restoration.md), fix pending
  • F14: package exports subpaths removed - ./db and ./db/drizzle restored in this PR
  • F18: actor-lifecycle state in napi not core - tracked, not yet fixed
  • F19: inspector logic duplicated in TypeScript - tracked, not yet fixed
  • F21: 50ms polling loop in native.ts - tracked, not yet fixed
  • F32: module-level actor-keyed maps in native.ts - tracked, not yet fixed
  • F34: ActorContext.key type widened - tracked, not yet fixed
  • F35: sql on ctx but ./db dropped - ./db/drizzle restored in this PR
  • F36: ContextOf type helpers removed - tracked for restoration
  • F38: inline use in test - tracked
  • F41: dead BARE code audit - pending audit
  • F42: inline mod tests in src/ - policy added to CLAUDE.md

@NathanFlurry NathanFlurry changed the base branch from 04-22-chore_fix_remaining_issues_with_rivetkit-core to graphite-base/4702 April 23, 2026 04:02
@NathanFlurry NathanFlurry force-pushed the 04-22-chore_rivetkit_core_napi_typescript_follow_up_review branch from 689feea to 527f1d2 Compare April 23, 2026 04:02
@NathanFlurry NathanFlurry changed the base branch from graphite-base/4702 to 04-22-chore_fix_remaining_issues_with_rivetkit-core April 23, 2026 04:02
@NathanFlurry NathanFlurry force-pushed the 04-22-chore_rivetkit_core_napi_typescript_follow_up_review branch from 527f1d2 to ef109dd Compare April 23, 2026 08:02
@NathanFlurry NathanFlurry force-pushed the 04-22-chore_fix_remaining_issues_with_rivetkit-core branch from a639b2e to d7cd40d Compare April 23, 2026 08:02
@claude
Copy link
Copy Markdown

claude Bot commented Apr 23, 2026

PR Review: chore: rivetkit core/napi/typescript follow up review

This PR addresses follow-up items from the adversarial review of rivetkit-core/napi/typescript. Below are findings from a fresh pass over the diff.


Issues to address before merge

1. Test-only probe compiled into production (websocket.rs)

RawHibernatableAckTestState and maybe_respond_to_raw_hibernatable_ack_state_probe are unconditionally compiled into the production binary. The only guard is a runtime env::var_os("VITEST").is_none() check. In production, every non-binary message on a hibernatable raw WebSocket connection allocates an Arc<Mutex<RawHibernatableAckTestState>> per handler and calls into the probe, which attempts a serde_json::from_slice parse.

Both the struct and the function should be gated with #[cfg(test)]. The ack_test_state allocation inside the closure and the two if is_hibernatable && ... blocks that call record should be gated the same way.

2. Null hazard in the incoming-size limit path (actor-conn.ts)

In the new size-limit block:

const inFlight = this.#takeActionInFlight(actionId);
// ...
logger().warn({ ..., actionName: inFlight.name, ... });
inFlight.reject(error);

If #takeActionInFlight returns undefined — the action resolved, timed out, or was cancelled between serialization and the size check — inFlight.name and inFlight.reject(error) both throw, producing an unhandled rejection out of the send path. Should guard before use:

const inFlight = this.#takeActionInFlight(actionId);
if (!inFlight) return; // action already settled

3. DEFAULT_MAX_INCOMING_MESSAGE_SIZE is opaque to callers (actor-conn.ts)

The 65,536-byte client-side limit is hardcoded and not derived from the server config. A user who sets a larger maxIncomingMessageSize server-side will get an incoming_too_long error with no hint the server would accept larger payloads. Consider plumbing the configured limit through ActorConnOptions so both sides agree, or at minimum document the mismatch risk.

4. ensure_local_normal_runner_config in hot startup path — no retry (runner_config.rs)

CoreRegistry::serve calls ensure_local_normal_runner_config with no retry logic. If the local engine is still booting, GET /datacenters or PUT /runner-configs/... will fail and abort startup permanently. A short exponential-backoff retry (e.g. 3 attempts, ~1s initial delay) would make local-dev startup resilient to the engine warm-up race. Also, use std::net::IpAddr; at the top of the file is unused.


Correct changes worth noting

  • task.rs F3 fix — the new clean_exit && lifecycle == Started -> return None path is correct. The actor stays in Started awaiting the engine Stop; reset_sleep_timer and related teardown are deferred until after transition_to(Terminated). The two new tests (clean_run_exit_still_dispatches_on_sleep_when_stop_arrives / _on_destroy) give solid coverage.

  • OutgoingTooLong structured error — delivers ActorConnectError with action_id instead of a raw close code 1011, which is the correct client-facing contract.

  • Workflow-engine @deprecated aliasescommitInterval, historyEvery, historyKeep are properly aliased with fallback reads and @deprecated jsdoc, preserving backward compatibility without runtime breakage.

  • isClosedTaskRegistrationError null guard — the extra metadataError indirection before the typeof === "string" check is correct; the previous form accessed error.metadata?.error as unknown without the type narrowing.

  • restartRunHandler / setAlarm async wrappers — wrapping void NAPI calls in async () => { this.#ctx.method(); } is correct; the previous form unnecessarily propagated the sync NAPI return through callNative's Promise chain.


Summary: the core lifecycle fix (F3) and structured-error improvements are solid. Issues 1-4 above — production test code in websocket.rs, the null hazard in the size-check path, the hardcoded client limit, and the no-retry startup call — should be addressed before merge.

@github-actions
Copy link
Copy Markdown
Contributor

Preview packages published to npm

Install with:

npm install rivetkit@pr-4702

All packages published as 0.0.0-pr.4702.d108c6a with tag pr-4702.

Engine binary is shipped via @rivetkit/engine-cli on linux-x64-musl, linux-arm64-musl, darwin-x64, and darwin-arm64. Windows users should use the release installer or set RIVET_ENGINE_BINARY.

Docker images:

docker pull rivetdev/engine:slim-d108c6a
docker pull rivetdev/engine:full-d108c6a
Individual packages
npm install rivetkit@pr-4702
npm install @rivetkit/react@pr-4702
npm install @rivetkit/rivetkit-napi@pr-4702
npm install @rivetkit/workflow-engine@pr-4702

1 similar comment
@github-actions
Copy link
Copy Markdown
Contributor

Preview packages published to npm

Install with:

npm install rivetkit@pr-4702

All packages published as 0.0.0-pr.4702.d108c6a with tag pr-4702.

Engine binary is shipped via @rivetkit/engine-cli on linux-x64-musl, linux-arm64-musl, darwin-x64, and darwin-arm64. Windows users should use the release installer or set RIVET_ENGINE_BINARY.

Docker images:

docker pull rivetdev/engine:slim-d108c6a
docker pull rivetdev/engine:full-d108c6a
Individual packages
npm install rivetkit@pr-4702
npm install @rivetkit/react@pr-4702
npm install @rivetkit/rivetkit-napi@pr-4702
npm install @rivetkit/workflow-engine@pr-4702

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