From a077a15bb1e973487b3c633c9c09f065b980ada3 Mon Sep 17 00:00:00 2001 From: Kris Zyp Date: Tue, 6 Oct 2026 15:56:27 -0600 Subject: [PATCH 1/7] Document that source maps are off by default and how to enable them Co-Authored-By: Claude Opus 5.5 --- reference/configuration/debugging.md | 14 ++++++++++++++ 1 file changed, 14 insertions(+) diff --git a/reference/configuration/debugging.md b/reference/configuration/debugging.md index 0424fe46c..c44377a78 100644 --- a/reference/configuration/debugging.md +++ b/reference/configuration/debugging.md @@ -106,6 +106,20 @@ threads: Snapshots can be large (often a sizable fraction of the heap limit) and writing them blocks the thread briefly — leave disabled for normal operation and enable only when investigating an out-of-memory pattern. +## Source Maps in Stack Traces + + + +Harper ships its compiled JavaScript with source maps, but does not enable them by default: Node.js keeps every loaded module's source map in memory on every thread, which costs several megabytes per thread. Without them, stack traces from Harper's core point at the compiled files under `dist/`. + +To get stack traces that point at the TypeScript sources, enable source maps with the Node.js flag, either on the command line or through `NODE_OPTIONS`. Harper passes the setting on to every worker thread: + +```bash +NODE_OPTIONS=--enable-source-maps harper +``` + +Before v5.4.0, source maps were always enabled. + ## Related - [Configuration Options — `threads`](./options.md#threads) — full thread configuration reference From c9d3e405d5d13cfab445eb732ff2db1a8d2701f1 Mon Sep 17 00:00:00 2001 From: Kris Zyp Date: Tue, 6 Oct 2026 16:31:57 -0600 Subject: [PATCH 2/7] Mark the source-map default as changed in 5.4, cover component source maps, and add a 5.4 release note Co-Authored-By: Claude Opus 5.5 --- reference/configuration/debugging.md | 9 ++++++--- reference/configuration/overview.md | 2 +- release-notes/v5-lincoln/5.4.md | 8 ++++++++ 3 files changed, 15 insertions(+), 4 deletions(-) diff --git a/reference/configuration/debugging.md b/reference/configuration/debugging.md index c44377a78..8ccf74104 100644 --- a/reference/configuration/debugging.md +++ b/reference/configuration/debugging.md @@ -108,16 +108,18 @@ Snapshots can be large (often a sizable fraction of the heap limit) and writing ## Source Maps in Stack Traces - + -Harper ships its compiled JavaScript with source maps, but does not enable them by default: Node.js keeps every loaded module's source map in memory on every thread, which costs several megabytes per thread. Without them, stack traces from Harper's core point at the compiled files under `dist/`. +Harper no longer enables source maps by default: Node.js keeps every loaded module's source map in memory on every thread, which costs several megabytes per thread. Without them, stack traces point at the JavaScript that actually ran, which for Harper's core is the compiled code under `dist/`, and for a component built with a bundler or `tsc` is its build output rather than its original sources. -To get stack traces that point at the TypeScript sources, enable source maps with the Node.js flag, either on the command line or through `NODE_OPTIONS`. Harper passes the setting on to every worker thread: +To get stack traces that point at the original sources, for Harper's core and for components that ship source maps alike, set the Node.js `--enable-source-maps` flag through `NODE_OPTIONS`. Harper passes the setting on to every worker thread: ```bash NODE_OPTIONS=--enable-source-maps harper ``` +Passing the flag to `node` directly works too when you launch Harper's entry script with `node`. + Before v5.4.0, source maps were always enabled. ## Related @@ -125,3 +127,4 @@ Before v5.4.0, source maps were always enabled. - [Configuration Options — `threads`](./options.md#threads) — full thread configuration reference - [Architecture Overview](../database/overview.md#architecture-overview) — how worker threads fit into Harper - [Node.js Inspector documentation](https://nodejs.org/en/learn/getting-started/debugging) — debugger protocol details +- [Node.js `--enable-source-maps`](https://nodejs.org/api/cli.html#--enable-source-maps) — how Node.js applies source maps to stack traces diff --git a/reference/configuration/overview.md b/reference/configuration/overview.md index 033c8006c..c82ba9a49 100644 --- a/reference/configuration/overview.md +++ b/reference/configuration/overview.md @@ -315,6 +315,6 @@ Built-in plugins (REST, HTTP, operations API, etc.) and the core database are un ## See Also - [Configuration Options](./options.md) — complete reference for every `harper-config.yaml` key -- [Worker Thread Debugging](./debugging.md) — attaching Node.js inspector to Harper's worker threads +- [Worker Thread Debugging](./debugging.md) — attaching Node.js inspector to Harper's worker threads, and enabling source maps in stack traces - [Storage Tuning](../database/storage-tuning.md) — production tuning of `storage.*` options - [Logging Configuration](../logging/configuration.md) — main and per-subsystem log settings diff --git a/release-notes/v5-lincoln/5.4.md b/release-notes/v5-lincoln/5.4.md index bf779e192..363737c98 100644 --- a/release-notes/v5-lincoln/5.4.md +++ b/release-notes/v5-lincoln/5.4.md @@ -76,6 +76,14 @@ The agent records the usage of each model call on its session, and `get_agent_se A `models.generative` entry can now declare `pricing: { inputPerMtok, outputPerMtok }`, what you pay in USD per million prompt and completion tokens. Harper ships no prices of its own. Each `generate()` call is priced at the rates of the entry that served it, a fallback included, and the result carries `costUsd` when that entry is priced and the provider reported both token counts. With `toolMode: 'auto'` it covers the final round, and streaming calls are not priced. This makes `maxCostUsd` work on `toolMode: 'auto'` calls; before, it had no prices behind it and never tripped. A `toolMode: 'auto'` round that leaves `maxCostUsd` or `maxToolTokens` unmeasurable, because the entry is unpriced or the provider reported no token counts, now stops the call with the budget error (429) instead of warning once and continuing, so set `pricing` on entries you cap by cost. See [Pricing](/reference/v5/models/overview#pricing). +## Memory + +### Smaller Per-Thread Baseline + +An idle Harper thread now uses roughly 40% less JavaScript heap (about 58 MB down to 35 MB in a default install, before any application code loads). Harper's compiled code is smaller in memory, and several dependencies used only by specific features (LMDB storage, certificate revocation checks, certificate generation, `system_information`) now load when that feature is first used. + +Source maps are no longer enabled by default, so stack traces point at the compiled JavaScript, for Harper's core and for components that ship source maps. Set `NODE_OPTIONS=--enable-source-maps` to map them back to the original sources in every thread. See [Source Maps in Stack Traces](/reference/v5/configuration/debugging#source-maps-in-stack-traces). + ## Component Deploys ### Certifying a Release in a Canary Worker From 5abce91067fd6b046a14315db9abecf9ab588dc3 Mon Sep 17 00:00:00 2001 From: Kris Zyp Date: Tue, 6 Oct 2026 16:47:03 -0600 Subject: [PATCH 3/7] Scope the source-map note to modules Node.js loads itself Co-Authored-By: Claude Opus 5.5 --- reference/configuration/debugging.md | 4 ++-- release-notes/v5-lincoln/5.4.md | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/reference/configuration/debugging.md b/reference/configuration/debugging.md index 8ccf74104..e6331eefb 100644 --- a/reference/configuration/debugging.md +++ b/reference/configuration/debugging.md @@ -110,9 +110,9 @@ Snapshots can be large (often a sizable fraction of the heap limit) and writing -Harper no longer enables source maps by default: Node.js keeps every loaded module's source map in memory on every thread, which costs several megabytes per thread. Without them, stack traces point at the JavaScript that actually ran, which for Harper's core is the compiled code under `dist/`, and for a component built with a bundler or `tsc` is its build output rather than its original sources. +Harper no longer enables source maps by default: Node.js keeps every loaded module's source map in memory on every thread, which costs several megabytes per thread. Without them, stack traces from Harper's core point at the compiled code under `dist/` rather than its TypeScript sources. -To get stack traces that point at the original sources, for Harper's core and for components that ship source maps alike, set the Node.js `--enable-source-maps` flag through `NODE_OPTIONS`. Harper passes the setting on to every worker thread: +To get stack traces that point at the original sources, set the Node.js `--enable-source-maps` flag through `NODE_OPTIONS`. Harper passes the setting on to every worker thread. It applies to modules Node.js loads itself: Harper's core, and application code loaded natively (for example with `applications.moduleLoader: native`). Modules run by the default VM-based loader are not mapped either way. ```bash NODE_OPTIONS=--enable-source-maps harper diff --git a/release-notes/v5-lincoln/5.4.md b/release-notes/v5-lincoln/5.4.md index 363737c98..8a4979990 100644 --- a/release-notes/v5-lincoln/5.4.md +++ b/release-notes/v5-lincoln/5.4.md @@ -82,7 +82,7 @@ A `models.generative` entry can now declare `pricing: { inputPerMtok, outputPerM An idle Harper thread now uses roughly 40% less JavaScript heap (about 58 MB down to 35 MB in a default install, before any application code loads). Harper's compiled code is smaller in memory, and several dependencies used only by specific features (LMDB storage, certificate revocation checks, certificate generation, `system_information`) now load when that feature is first used. -Source maps are no longer enabled by default, so stack traces point at the compiled JavaScript, for Harper's core and for components that ship source maps. Set `NODE_OPTIONS=--enable-source-maps` to map them back to the original sources in every thread. See [Source Maps in Stack Traces](/reference/v5/configuration/debugging#source-maps-in-stack-traces). +Source maps are no longer enabled by default, so stack traces from Harper's core point at its compiled JavaScript. Set `NODE_OPTIONS=--enable-source-maps` to map them back to the TypeScript sources in every thread. See [Source Maps in Stack Traces](/reference/v5/configuration/debugging#source-maps-in-stack-traces). ## Component Deploys From 7ffb116462c84d3aba745b42fc773d43bd6b42b9 Mon Sep 17 00:00:00 2001 From: Kris Zyp Date: Tue, 6 Oct 2026 16:56:13 -0600 Subject: [PATCH 4/7] Name the unmapped VM loaders and drop the bare node-flag hint Co-Authored-By: Claude Opus 5.5 --- reference/configuration/debugging.md | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/reference/configuration/debugging.md b/reference/configuration/debugging.md index e6331eefb..e7a96476c 100644 --- a/reference/configuration/debugging.md +++ b/reference/configuration/debugging.md @@ -112,14 +112,12 @@ Snapshots can be large (often a sizable fraction of the heap limit) and writing Harper no longer enables source maps by default: Node.js keeps every loaded module's source map in memory on every thread, which costs several megabytes per thread. Without them, stack traces from Harper's core point at the compiled code under `dist/` rather than its TypeScript sources. -To get stack traces that point at the original sources, set the Node.js `--enable-source-maps` flag through `NODE_OPTIONS`. Harper passes the setting on to every worker thread. It applies to modules Node.js loads itself: Harper's core, and application code loaded natively (for example with `applications.moduleLoader: native`). Modules run by the default VM-based loader are not mapped either way. +To get stack traces that point at the original sources, set the Node.js `--enable-source-maps` flag through `NODE_OPTIONS`. Harper passes the setting on to every worker thread. It applies to modules Node.js loads itself: Harper's core, and application code loaded natively (for example with `applications.moduleLoader: native`). Modules run by Harper's VM-based loaders (`vm-current-context`, the default, as well as `vm` and `compartment`) are not mapped either way. ```bash NODE_OPTIONS=--enable-source-maps harper ``` -Passing the flag to `node` directly works too when you launch Harper's entry script with `node`. - Before v5.4.0, source maps were always enabled. ## Related From a91e7eef096eb9bb878c8f215ec46eb07de9edf7 Mon Sep 17 00:00:00 2001 From: Kris Zyp Date: Mon, 19 Oct 2026 10:22:45 -0600 Subject: [PATCH 5/7] Lead the source-map section with how to enable them, and say what Fabric users see Co-Authored-By: Claude Opus 5.5 Dispatch-Task: fix-kriszyp_documentation_714-dcf91ad3 --- reference/configuration/debugging.md | 10 +++++++--- 1 file changed, 7 insertions(+), 3 deletions(-) diff --git a/reference/configuration/debugging.md b/reference/configuration/debugging.md index e7a96476c..0c8fd4b65 100644 --- a/reference/configuration/debugging.md +++ b/reference/configuration/debugging.md @@ -110,14 +110,18 @@ Snapshots can be large (often a sizable fraction of the heap limit) and writing -Harper no longer enables source maps by default: Node.js keeps every loaded module's source map in memory on every thread, which costs several megabytes per thread. Without them, stack traces from Harper's core point at the compiled code under `dist/` rather than its TypeScript sources. - -To get stack traces that point at the original sources, set the Node.js `--enable-source-maps` flag through `NODE_OPTIONS`. Harper passes the setting on to every worker thread. It applies to modules Node.js loads itself: Harper's core, and application code loaded natively (for example with `applications.moduleLoader: native`). Modules run by Harper's VM-based loaders (`vm-current-context`, the default, as well as `vm` and `compartment`) are not mapped either way. +Stack traces from Harper's core point at its compiled JavaScript under `dist/`. To map them back to the TypeScript sources, enable source maps with the Node.js `--enable-source-maps` flag, set through `NODE_OPTIONS`: ```bash NODE_OPTIONS=--enable-source-maps harper ``` +Harper passes the setting on to every worker thread (not under Bun). Source maps cost memory: Node.js keeps every loaded module's source map on every thread, several megabytes per thread, so leave them off unless you are reading stack traces. + +The setting applies to modules Node.js loads itself: Harper's core, and application code loaded natively (for example with `applications.moduleLoader: native`). Harper's VM-based loaders (`vm-current-context`, the default, as well as `vm` and `compartment`) do not apply source maps either way. They strip TypeScript types without moving code, so a stack trace from an application they load still points at the right line of the file it loaded. + +On Harper Fabric you do not set the process environment, so `NODE_OPTIONS` is not available there. Applications on the default loader get the same stack traces either way; only stack traces from Harper's core stay unmapped. + Before v5.4.0, source maps were always enabled. ## Related From 0d22abf01cff2e8eb90cbfb8934718ad3c3e8850 Mon Sep 17 00:00:00 2001 From: Kris Zyp Date: Mon, 19 Oct 2026 10:27:24 -0600 Subject: [PATCH 6/7] Count natively loaded packages in the source-map scope, drop the line-position promise, and carry the Fabric limit into the release note Co-Authored-By: Claude Opus 5.5 Dispatch-Task: fix-kriszyp_documentation_714-dcf91ad3 --- reference/configuration/debugging.md | 6 +++--- release-notes/v5-lincoln/5.4.md | 2 +- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/reference/configuration/debugging.md b/reference/configuration/debugging.md index 0c8fd4b65..ce10ea824 100644 --- a/reference/configuration/debugging.md +++ b/reference/configuration/debugging.md @@ -116,11 +116,11 @@ Stack traces from Harper's core point at its compiled JavaScript under `dist/`. NODE_OPTIONS=--enable-source-maps harper ``` -Harper passes the setting on to every worker thread (not under Bun). Source maps cost memory: Node.js keeps every loaded module's source map on every thread, several megabytes per thread, so leave them off unless you are reading stack traces. +Harper passes the setting on to every worker thread (not under Bun). Source maps cost memory: Node.js keeps every loaded module's source map on every thread, several megabytes per thread. -The setting applies to modules Node.js loads itself: Harper's core, and application code loaded natively (for example with `applications.moduleLoader: native`). Harper's VM-based loaders (`vm-current-context`, the default, as well as `vm` and `compartment`) do not apply source maps either way. They strip TypeScript types without moving code, so a stack trace from an application they load still points at the right line of the file it loaded. +The setting applies to modules Node.js loads itself: Harper's core, application code loaded natively (for example with `applications.moduleLoader: native`), and the npm packages that Harper loads natively (under the default `applications.dependencyLoader: auto`, every package that does not depend on Harper; see [Dependency Loading](../components/module-loading.md#dependency-loading)). Harper's VM-based loaders (`vm-current-context`, the default, as well as `vm` and `compartment`) do not apply source maps either way. -On Harper Fabric you do not set the process environment, so `NODE_OPTIONS` is not available there. Applications on the default loader get the same stack traces either way; only stack traces from Harper's core stay unmapped. +On Harper Fabric you do not set the process environment, so `NODE_OPTIONS` is not available there. Stack traces from application code on the default loader are the same either way; those from Harper's core and from natively loaded packages stay unmapped. Before v5.4.0, source maps were always enabled. diff --git a/release-notes/v5-lincoln/5.4.md b/release-notes/v5-lincoln/5.4.md index 8a4979990..822d7b1aa 100644 --- a/release-notes/v5-lincoln/5.4.md +++ b/release-notes/v5-lincoln/5.4.md @@ -82,7 +82,7 @@ A `models.generative` entry can now declare `pricing: { inputPerMtok, outputPerM An idle Harper thread now uses roughly 40% less JavaScript heap (about 58 MB down to 35 MB in a default install, before any application code loads). Harper's compiled code is smaller in memory, and several dependencies used only by specific features (LMDB storage, certificate revocation checks, certificate generation, `system_information`) now load when that feature is first used. -Source maps are no longer enabled by default, so stack traces from Harper's core point at its compiled JavaScript. Set `NODE_OPTIONS=--enable-source-maps` to map them back to the TypeScript sources in every thread. See [Source Maps in Stack Traces](/reference/v5/configuration/debugging#source-maps-in-stack-traces). +Source maps are no longer enabled by default, so stack traces from Harper's core point at its compiled JavaScript. If you control the process environment (not on Harper Fabric), set `NODE_OPTIONS=--enable-source-maps` to map them back to the TypeScript sources in every thread. See [Source Maps in Stack Traces](/reference/v5/configuration/debugging#source-maps-in-stack-traces). ## Component Deploys From 67168fa3054ea51b3627cfff216392e08912b424 Mon Sep 17 00:00:00 2001 From: Kris Zyp Date: Mon, 19 Oct 2026 10:29:54 -0600 Subject: [PATCH 7/7] Scope the Fabric limit to clusters Harper hosts, and drop the every-thread promise from the release note Co-Authored-By: Claude Opus 5.5 Dispatch-Task: fix-kriszyp_documentation_714-dcf91ad3 --- reference/configuration/debugging.md | 2 +- release-notes/v5-lincoln/5.4.md | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/reference/configuration/debugging.md b/reference/configuration/debugging.md index ce10ea824..072bd8c2c 100644 --- a/reference/configuration/debugging.md +++ b/reference/configuration/debugging.md @@ -120,7 +120,7 @@ Harper passes the setting on to every worker thread (not under Bun). Source maps The setting applies to modules Node.js loads itself: Harper's core, application code loaded natively (for example with `applications.moduleLoader: native`), and the npm packages that Harper loads natively (under the default `applications.dependencyLoader: auto`, every package that does not depend on Harper; see [Dependency Loading](../components/module-loading.md#dependency-loading)). Harper's VM-based loaders (`vm-current-context`, the default, as well as `vm` and `compartment`) do not apply source maps either way. -On Harper Fabric you do not set the process environment, so `NODE_OPTIONS` is not available there. Stack traces from application code on the default loader are the same either way; those from Harper's core and from natively loaded packages stay unmapped. +On Fabric clusters that Harper hosts, you do not set the process environment, so `NODE_OPTIONS` is not available there. Stack traces from application code on the default loader are the same either way; those from Harper's core and from natively loaded packages stay unmapped. Before v5.4.0, source maps were always enabled. diff --git a/release-notes/v5-lincoln/5.4.md b/release-notes/v5-lincoln/5.4.md index 822d7b1aa..de5cf747b 100644 --- a/release-notes/v5-lincoln/5.4.md +++ b/release-notes/v5-lincoln/5.4.md @@ -82,7 +82,7 @@ A `models.generative` entry can now declare `pricing: { inputPerMtok, outputPerM An idle Harper thread now uses roughly 40% less JavaScript heap (about 58 MB down to 35 MB in a default install, before any application code loads). Harper's compiled code is smaller in memory, and several dependencies used only by specific features (LMDB storage, certificate revocation checks, certificate generation, `system_information`) now load when that feature is first used. -Source maps are no longer enabled by default, so stack traces from Harper's core point at its compiled JavaScript. If you control the process environment (not on Harper Fabric), set `NODE_OPTIONS=--enable-source-maps` to map them back to the TypeScript sources in every thread. See [Source Maps in Stack Traces](/reference/v5/configuration/debugging#source-maps-in-stack-traces). +Source maps are no longer enabled by default, so stack traces from Harper's core point at its compiled JavaScript. If you control the process environment (not on Fabric clusters that Harper hosts), set `NODE_OPTIONS=--enable-source-maps` to map them back to the TypeScript sources. See [Source Maps in Stack Traces](/reference/v5/configuration/debugging#source-maps-in-stack-traces). ## Component Deploys