diff --git a/reference/components/module-loading.md b/reference/components/module-loading.md
index 1d54fc4a..31e4faa9 100644
--- a/reference/components/module-loading.md
+++ b/reference/components/module-loading.md
@@ -148,6 +148,37 @@ Like `allowedDirectory`, this applies to imports the application module loader h
Allowlisting `child_process` still yields Harper's constrained substitute under the VM loaders, not Node's unmodified module.
+## Native Addons on Pointer-Compression Runtimes
+
+
+
+Harper can run on a Node.js build with V8 pointer compression enabled (built with `--experimental-enable-pointer-compression`, so that `process.config.variables.v8_enable_pointer_compression` is `1`), which uses less JavaScript heap per thread. Free and Hobby tier clusters on Harper Fabric use pointer-compression runtimes by default. Pointer compression changes V8's C++ ABI without changing Node.js's module version. A native addon (`.node` file) that calls V8's C++ API directly, rather than Node-API, and was built for a standard Node.js therefore loads and then crashes the whole process the first time it is used.
+
+On a pointer-compression runtime, Harper checks native addons before they load, in every thread. That covers addons loaded by applications, by their dependencies, and by [`threads.preload` and `threads.preloadRequire`](../configuration/options.md#threads) modules. Harper refuses an addon that links V8's C++ API unless it was built for pointer compression. A 64-bit ELF addon whose symbol table cannot be read is refused too, unless one of the last two rules below admits it.
+
+An addon loads when any of these holds:
+
+- It uses only [Node-API](https://nodejs.org/api/n-api.html), which is ABI-stable across the flag: it imports no V8 C++ symbols. Most current addons are Node-API.
+- node-gyp compiled it under this Node.js, for example with `npm rebuild --build-from-source`, and it is loaded from that package's `build/` directory. That build's `config.gypi` must record `"v8_enable_pointer_compression": 1`, and the binary must be newer than it. Two cases need the marker below instead:
+ - a binary copied elsewhere after building, as node-pre-gyp does;
+ - a build whose files all share one modification time, such as a reproducible build with clamped timestamps.
+- Its package directory contains a `.pointer-compression-build` file. The marker admits every native binary in the package without inspecting it. Add this marker only when all of them were built for pointer compression.
+
+A refused addon fails to load with an `IncompatibleNativeAddonError`. The error names the file and its package, and lists the fixes:
+
+- a Node-API version of the package;
+- a build compiled for pointer compression;
+- a rebuild from source under the running Node.js;
+- a standard Node.js runtime.
+
+The error carries `code: 'ERR_DLOPEN_FAILED'`, the code Node.js uses for an addon it cannot load. So packages that treat their native accelerator as optional, such as `cbor-x` and `msgpackr`, fall back to their JavaScript implementation.
+
+The check has three limits:
+
+- It inspects Linux (ELF) binaries only. Addons in other formats are left to Node.js and are not checked.
+- Modules preloaded through `NODE_OPTIONS` run before Harper starts. Their addons are not checked. Load such modules with `threads.preload` or `threads.preloadRequire` instead.
+- On a standard Node.js build, nothing changes.
+
## Choosing a Mode
For most applications the default is the right choice, and the settings on this page are worth changing only in response to a concrete problem.
diff --git a/release-notes/v5-lincoln/5.4.md b/release-notes/v5-lincoln/5.4.md
index 32120367..63febd7b 100644
--- a/release-notes/v5-lincoln/5.4.md
+++ b/release-notes/v5-lincoln/5.4.md
@@ -23,3 +23,17 @@ A durable MQTT session now resumes through the same checked replay. When a recon
### Certifying a Release in a Canary Worker
A `deploy_component` with `restart: true` or `restart: "rolling"` now checks its release before rolling it out. The first worker started on the release, the canary, is held out of traffic until it reports whether the deployed component loaded, and the rollout goes on only if it did. Each later replacement is checked the same way. When the node that received the deploy rejects the release, the deploy fails with `400`. The release it replaced is made live again, or, with nothing to go back to, the component fails closed on that node. A new `certification` field in the response reports the outcome, and says when a restarting deploy went out unchecked (`uncertified` or `unavailable`, as for a `package: file:` deploy). With `"rolling"`, each other node then certifies the release with a canary of its own, and a node that rejects it fails the deploy's job, not the deploy: poll its `restartJobId` with `get_job` for the outcome. A node running a version before 5.4.0 activates without a canary. A deploy that restarts nothing is not test-loaded. If its release throws when it loads, `get_status` reports the failure. See [Certifying a release in a canary worker](/reference/v5/operations-api/operations#certifying-a-release-in-a-canary-worker).
+
+## Native Addons
+
+### Pointer-Compression Runtimes Refuse Incompatible Native Addons
+
+Free and Hobby tier clusters on Harper Fabric use pointer-compression runtimes by default. On a Node.js build with V8 pointer compression, Harper now checks native addons before they load, in every thread. It refuses an addon that links V8's C++ API built for the standard ABI, which would otherwise load and then crash the process on first use. The refusal is an `IncompatibleNativeAddonError` that names the file, its package and the fixes.
+
+These still load as before:
+
+- Node-API addons;
+- addons that node-gyp built under the running Node.js and that load from the package's `build/` directory;
+- packages marked with `.pointer-compression-build`.
+
+Standard Node.js builds are unchanged. See [Native Addons on Pointer-Compression Runtimes](/reference/v5/components/module-loading#native-addons-on-pointer-compression-runtimes).