Skip to content

Document how native addons load on pointer-compression Node runtimes - #725

Draft
kriszyp wants to merge 5 commits into
mainfrom
docs/pointer-compression-native-addons
Draft

kriszyp wants to merge 5 commits into
mainfrom
docs/pointer-compression-native-addons

Conversation

@kriszyp

@kriszyp kriszyp commented Oct 10, 2026 •

Copy link
Copy Markdown
Member

⊙ Problem

HarperFast/harper#3140 (v5.4) makes Harper refuse native addons on V8 pointer-compression Node runtimes when they link V8's C++ API for the standard ABI. Such an addon would otherwise load and then crash the process on first use. A component author whose dependency is refused needs to know why, which addons are allowed, and how to fix it. Nothing in the docs covers pointer-compression runtimes today.

❓ Your call: Does this belong in the docs? Yes: the refusal is user-visible, and it names fixes the reader has to act on. The alternative is to leave it to the error message alone, which already lists the fixes but cannot explain the rules ahead of a deploy.

💡 Solution

A new "Native Addons on Pointer-Compression Runtimes" section in reference/components/module-loading.md, marked v5.4.0, between "Allowed Built-in Modules" and "Choosing a Mode". It covers:

  • What is checked: addons loaded by applications, by their dependencies, and by threads.preload/threads.preloadRequire modules, in every thread.
  • Cloud default: Free and Hobby tier clusters on Harper Fabric use pointer-compression runtimes by default.
  • What loads:
    • Node-API addons, which import no V8 C++ symbols;
    • addons that node-gyp built under the running Node.js and that load from the package's build/ directory, where config.gypi records the flag and is older than the binary;
    • packages carrying .pointer-compression-build. The marker admits every binary in the package, so the page says to add it only when all of them are pointer-compression builds.
  • What a refusal looks like: IncompatibleNativeAddonError with code: 'ERR_DLOPEN_FAILED', and the JavaScript fallback of optional accelerators such as cbor-x and msgpackr.
  • Limits: only Linux ELF binaries are inspected; NODE_OPTIONS preloads run before Harper and are not checked; standard Node.js is unchanged.

A "Native Addons" entry in release-notes/v5-lincoln/5.4.md summarizes the change and links to the section. It also states the Free and Hobby tier default.

❓ Your call: Tier-default context. Free and Hobby are maintainer-confirmed tier names. The Fabric creation guide lists examples of cluster sizes, so it is not an exhaustive tier catalog; refreshing its tier-selection guidance is separate work. The reference's remedies serve both managed and self-managed deployments. A Fabric runtime-selection setting or a paid-tier upgrade path would need a confirmed product contract before documenting it. In the release note, "use ... by default" supplies runtime context and "now checks" identifies the v5.4 change.

❓ Your call: Marker as a user contract. The page documents .pointer-compression-build for anyone, with the whole-package caveat, so that pc builds made by other toolchains (cmake-js, node-pre-gyp copies, reproducible builds with clamped mtimes) have a way in. The alternative is to keep it a producer-only mechanism of the harper-pro pc image. Once documented it is effectively public API, and narrowing it later would break users who rely on it.

❓ Your call: NODE_OPTIONS workaround. The page tells operators to move such preloads to threads.preload/threads.preloadRequire, which are checked. Those run in worker threads only, so main-thread instrumentation is lost. The root-cause fix would be a core export that users can put first in NODE_OPTIONS, which harper#3140 does not provide.

❓ Your call: Release-summary depth. The 5.4 entry gives three cases and links to the full rules, rather than repeating every admission condition (the config.gypi flag, the strictly newer binary). A full copy would drift from the reference page.

❓ Your call: Page placement. The section lives on the components "Module Loading" reference rather than on a runtime or installation page. Moving it is cheap now; later it would need a historic-redirects.ts entry.

Known gap, outside this diff: on harper-pro's clone-node boot path (HDB_LEADER_URL set), bin/harper.js loads Harper's logger (and through it segfault-handler) and cbor-x before core installs the guard. Application addons still load after the guard. The fix is a one-line harper-pro change, recorded as a follow-up.

✅ Verification

  • Each claim was checked against harper#3140 (utility/nativeAddonAbi.ts, server/threads/nativeAddonGuard.ts) and that PR's end-to-end run on a pointer-compression Node 24.18. On that run, a component's standard-ABI V8 prebuild was refused with the documented error, while addons built by node-gyp under the pc Node and marked pc builds loaded.
  • Both links resolve: ../configuration/options.md#threads is the threads section, and the release note's /reference/v5/components/module-loading#native-addons-on-pointer-compression-runtimes matches the new heading.
  • npm run format:write, npm run format:check, npm run build, npm run typecheck, and npm run test:workflows passed. Both generated pages contain the Free and Hobby tier default.
  • Full pre-push review ran on 5c7fd4f62fa2 with Claude, Gemini, and Cursor Composer. Domain adjudication timed out; author triage retained the documented preload and release-summary decisions and scoped Fabric tier-selection guidance to separate work. The marker, error code, and build-evidence rules were rechecked against harper#3140's current source.

🤖 Generated by Claude Opus 5.5 (Claude Code) and OpenAI Codex; posted via @kriszyp.

https://claude.ai/code/session_011m4iSgKNWY8toCDWmuoh9a

Depends-on: HarperFast/harper#3140

Related PRs: none found
Complexity: easy

Review-Coverage: authored=codex; ran=gemini,claude,cursor-composer; blocked=domain(timeout); declined=cursor-grok,cursor-kimi,cursor-muse; rounds=5; full=1 @ 5c7fd4f

Review-Attention: skim ~2m (raised: degraded review) @ 5c7fd4f

kriszyp and others added 3 commits October 10, 2026 12:36
On a V8 pointer-compression runtime, Harper refuses a native addon that links V8's C++ API unless it
was built for pointer compression (HarperFast/harper#3140). Describe the three ways an addon loads,
the IncompatibleNativeAddonError a refused one raises, and the JavaScript fallback of optional
accelerators.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_011m4iSgKNWY8toCDWmuoh9a
Dispatch-Task: harper-pc-native-addon-guard
… 5.4 notes

Name the NODE_OPTIONS preload exception, the strictly-newer config.gypi condition, the marker's
whole-package scope and the refusal of an unreadable ELF symbol table, and list the change in the
5.4 release notes.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_011m4iSgKNWY8toCDWmuoh9a
Dispatch-Task: harper-pc-native-addon-guard
…rules

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_011m4iSgKNWY8toCDWmuoh9a
Dispatch-Task: harper-pc-native-addon-guard

@gemini-code-assist gemini-code-assist Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Code Review

This pull request adds documentation and release notes for native addon compatibility checks on V8 pointer-compression runtimes in Harper v5.4.0. The new section explains how incompatible native addons are detected and refused with an IncompatibleNativeAddonError to prevent process crashes. The review feedback suggests improving readability by splitting sentences in the documentation so that critical warnings, bypass behaviors, and limitations (such as platform constraints and preloaded modules) are clearly highlighted in separate, distinct sentences.

Comment thread reference/components/module-loading.md Outdated
Comment thread reference/components/module-loading.md Outdated
Comment thread reference/components/module-loading.md Outdated
@github-actions
github-actions Bot temporarily deployed to pr-725 October 10, 2026 18:58 Inactive
@github-actions

Copy link
Copy Markdown

🚀 Preview Deployment

Your preview deployment is ready!

🔗 Preview URL: https://preview.harper-documentation.harperfabric.com/pr-725

This preview will update automatically when you push new commits.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_011m4iSgKNWY8toCDWmuoh9a
Dispatch-Task: harper-pc-native-addon-guard
@github-actions
github-actions Bot temporarily deployed to pr-725 October 10, 2026 19:06 Inactive
@github-actions

Copy link
Copy Markdown

🚀 Preview Deployment

Your preview deployment is ready!

🔗 Preview URL: https://preview.harper-documentation.harperfabric.com/pr-725

This preview will update automatically when you push new commits.

Co-Authored-By: OpenAI Codex <noreply@openai.com>
@github-actions

Copy link
Copy Markdown

🚀 Preview Deployment

Your preview deployment is ready!

🔗 Preview URL: https://preview.harper-documentation.harperfabric.com/pr-725

This preview will update automatically when you push new commits.

This branch was successfully deployed

1 active deployment
pr-725 — 5c7fd4f6 Deployed Oct 13, 2026 by github-actions[bot]
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