Repository navigation
Conversation
There was a problem hiding this comment.
Code Review
This pull request updates the documentation and release notes to reflect the change in the default lockdown mode to seal-after-load in version 5.4.0, which addresses performance issues associated with frozen prototypes on Node.js. The feedback highlights an inaccuracy in the downgrade instructions across several files; the documentation incorrectly suggests setting lockdown: freeze-after-load when downgrading to versions v5.0.1 through v5.3, but since freeze-after-load was only introduced in v5.0.2, the range should be corrected to v5.0.2 through v5.3.
🚀 Preview DeploymentYour preview deployment is ready! 🔗 Preview URL: https://preview.harper-documentation.harperfabric.com/pr-756 This preview will update automatically when you push new commits. |
🚀 Preview DeploymentYour preview deployment is ready! 🔗 Preview URL: https://preview.harper-documentation.harperfabric.com/pr-756 This preview will update automatically when you push new commits. |
a8b6b4d to
c1fc622
Compare
🚀 Preview DeploymentYour preview deployment is ready! 🔗 Preview URL: https://preview.harper-documentation.harperfabric.com/pr-756 This preview will update automatically when you push new commits. |
c1fc622 to
5e21763
Compare
5e21763 to
1e44217
Compare
🚀 Preview DeploymentYour preview deployment is ready! 🔗 Preview URL: https://preview.harper-documentation.harperfabric.com/pr-756 This preview will update automatically when you push new commits. |
applications.lockdown gains seal and seal-after-load; seal-after-load is the new default for new installs. Rewrite the Intrinsic Lockdown section around what each mode blocks, scope what is locked, and cover the upgrade (installs keep their written value) and downgrade (older releases freeze eagerly on a seal mode) consequences in the reference, options, 5.4 release notes and v5 migration guide. Closes #755 Dispatch-Task: docs-harper-3552 Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…ranges Sealing also blocks reconfiguring a property with Object.defineProperty, and still lets a payload overwrite an existing method. Downgrade advice applies to 5.0.2 through 5.3 (5.0.0 and 5.0.1 have no after-load mode). A config with no lockdown value, such as one carried over from v4, gets no lockdown. The migration guide now says when lockdown applies and that upgrades keep the configured value. Dispatch-Task: docs-harper-3552 Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
v5.0.1 already supports freeze-after-load; only v5.0.0 lacks an after-load mode. The migration guide no longer says the pre-5.4 default sealed. Dispatch-Task: docs-harper-3552 Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
The defaults table gives v5.0.2 as when freeze-after-load became the default, which reads as when it appeared; v5.0.1 already supports it. Dispatch-Task: docs-harper-3552 Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Dispatch-Task: pr-maint-75e960e45b99e352ac56d740b08786db Co-Authored-By: Gemini <noreply@google.com>
- Note that switching to a seal mode in a cluster requires all nodes on v5.4.0+ so replicated set_configuration does not fall back to freeze on 5.3 peers - Use arr.push = fn as the shadowing contrast with freeze in 5.4 release notes and link to What is locked for the intrinsic list - Note that seal and freeze modes neutralize Function.prototype.constructor before the first module loads - Clarify v5-migration YAML comment and sealing behavior Dispatch-Task: pr-maint-75e960e45b99e352ac56d740b08786db Co-Authored-By: Gemini <noreply@google.com> Co-Authored-By: GPT-5 Codex <noreply@openai.com>
Dispatch-Task: pr-maint-75e960e45b99e352ac56d740b08786db Co-Authored-By: GPT-5 Codex <noreply@openai.com>
1e44217 to
6f65d88
Compare
🚀 Preview DeploymentYour preview deployment is ready! 🔗 Preview URL: https://preview.harper-documentation.harperfabric.com/pr-756 This preview will update automatically when you push new commits. |
⊙ Problem
Seal JavaScript intrinsics by default instead of freezing them adds
applications.lockdown: sealandseal-after-load, and makesseal-after-loadthe default for new installs. The docs list only the freeze modes and say any runtime change to an intrinsic throws. That is no longer true under the new default.🤔 Is the requirement warranted?
As specified, yes: #755 names the pages. I also updated the v5 migration guide, which stated the old default. The source PR is merged and its seal implementation is present in v5.4.0-alpha.1; the badges use v5.4.0.
💡 Solution
Describe the six lockdown modes, their limits, and upgrade compatibility. Align the configuration reference, release notes, and migration guide. Look hardest at the overwrite trade-off and downgrade advice, which operators act on.
⚖️ Alternatives
lockdown: nonefor changes the new default allows.🔧 Changes
reference/components/module-loading.md— the config example, the defaults note (new installs get these values; an upgrade keeps the file's values), the Intrinsic Lockdown section, the VM compatibility wording, and the troubleshooting bullet.reference/configuration/options.md— theapplications.lockdownexample and description.release-notes/v5-lincoln/5.4.md— Upgrade Notes (upgraded instances keep their mode; setfreeze-after-loadbefore downgrading to 5.0.1 through 5.3) and a Security entry, including the Function.prototype compatibility warning. Document the operations API source allowlist is merged; both entries now share one## Securityheading.release-notes/v5-lincoln/v5-migration.md— the lockdown YAML example and its section.🤔 Retain the documented overwrite trade-off?
The source change deliberately leaves existing intrinsic properties writable. Such overwrites can affect application-specific validation or policy checks; the docs' qualified “mostly” wording does not guarantee authorization safety. Keep that decision visible and recommend
freeze-after-loadwhen existing properties must be unchangeable.🤔 Keep the numerical benchmark comparison?
The source PR's benchmark table reports approximately 3.9-4.0x, supporting “about four times.” Core's DESIGN.md says approximately 3x. Keep the source PR's measured comparison. No new benchmark was run for this update.
🤔 Expand the migration guide and reformat Upgrade Notes?
Keep detailed mutation rules in the linked reference. The migration workaround covers adding, deleting, or reconfiguring properties; sealing already allows writable-value assignments.
Object.definePropertythrows in strict and sloppy code. Preserve the existing full-text upgrade paragraph rather than reformat unrelated base content.🤔 Document that a config without
lockdowngets no lockdown?Harper skips locking when the value is absent, as in a config carried over from v4. The docs now say so. The alternative is a core fix that falls back to the default, after which these lines change. This was traced through code, not run.
✅ Verification
security/intrinsicsLockdown.ts(heada9247aed) in fresh Node 26.2 workers for each mode and a misspelled one. Under seal, adding and deleting threw; overwrites andarr.push = fnworked. Under freeze both threw. Only the seal modes sealedFunction.prototype, and the misspelled mode froze before load.applications.*. Thev5.0.0,v5.0.1,v5.0.2andv5.1.0tags give the default history; only v5.0.0 lacksfreeze-after-load. No live upgrade was run.v5.4.0-alpha.1tag object matches; that tag contains the seal implementation and default.npm run format:write,format:check,lint,typecheck,test:examples,test:workflows, andbuildon the rebased tree. All pass; example tests pass 13 with one offline companion comparison skipped. The production build checks links and MDX.Probe results (after the lock, strict mode unless noted)
seal-after-load/sealfreeze-after-load/freeze/ misspelledObject.prototype.x = 1TypeErrorTypeErrorObject.defineProperty(Array.prototype, 'x', …)TypeErrorTypeErrorFunction.prototype.x = 1TypeErrorArray.prototype.map = Array.prototype.mapTypeErrorarr.push = fnon an instanceTypeErrorobj.toString = fnon an instancenew Array(1e6)fillThe misspelled mode locked before load, like
freeze.Closes #755
🤖 Generated by OpenAI Codex (maintenance; original documentation by Anthropic Claude); posted via @kriszyp.
Related PRs: #743 overlaps (merged; both entries now share one Security heading)
Complexity: medium
Origin — the dispatch brief this PR was written from
Document the seal lockdown modes and the seal-after-load default
Document the new
applications.lockdownseal modes and default, tracked by #755 (its body lists the pages and the exact content; close it from the docs PR).Source change: HarperFast/harper#3552 (draft). Summary of the behavior to document:
sealandseal-after-load;seal-after-loadis the new default instatic/defaultConfig.yaml.none,freeze,freeze-after-loadandsesare unchanged.__proto__.isAdminneed. Existing properties stay writable: instances can shadow inherited methods, and code can still overwrite an existing prototype method (an accepted denial-of-service-only tradeoff).freeze-after-loadremains the opt-in for frozen prototypes.freeze-after-loaduntil an operator changes it. Before downgrading to a release without the seal modes, setfreeze-after-load: older releases freeze eagerly on an unknown value, and a dependency that extends an intrinsic at load then fails.Pages:
reference/components/module-loading.md(config example, defaults table, Intrinsic Lockdown section, troubleshooting bullet),reference/configuration/options.md(applications.lockdown), and the release notes for the release that ships the harper PR (currently milestoned v5.4). Do not merge before the harper PR merges.Dispatch: task
docs-harper-3552· queued by task:harper-lockdown-seal-default · ran by claude/opus/xhigh · worker kzyp-xps-1Review-Coverage: authored=codex; ran=gemini,cursor-composer,claude; adjudicated=domain; declined=cursor-grok,muse; rounds=10; full=1 @ 6f65d88
Review-Attention: skim ~2m (decisions: writable-default) @ 6f65d88