You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
{{ message }}
Repository navigation
Follow-up to #2954: deepMergeProviders is a recursive assignment-semantics merge over external config keys #4957
Filed by the Phase 3 closing inventory audit of design #2953 (issue #2954, queue task 7683, PR #4956) as its named deep-merge follow-up.
Finding
bin/provider-catalog-sync.mjs exports deepMergeProviders(base, over) — a recursive merge used to fold the runtime config overlay into the effective provider config (runSync). A recursive merge is assignment semantics at every depth: keys spelled by the overlay file (a file-spelled, external source) are written into the merged object per level, so a __proto__ key at any depth goes through the [[Set]] setter instead of becoming an own property — the exact class design #2953 contracts against.
The #2953 design doc records deep-merge helpers as an explicit open question: "a recursive merge is assignment semantics at every depth; no in-tree instance is known — Phase 3's audit reports one if it exists rather than this design pre-deciding its shape." This is that report. The fix shape needs its own decision: convert the merge to Map/null-prototype containers per level, or write leaves with define semantics (Object.defineProperty) while recursing — weighing that the merged result feeds config serialization and the catalog-sync guard (assertCatalogOnly) compares parsed before/after configs.
Acceptance
deepMergeProviders (and any caller-visible result) stores a __proto__ key at any depth as an own property with its value; the merged object's prototype and Object.prototype never move.
agent-note:v1
state: queued
Enqueued as task 8074 (small_fix, repo-health-code-pilot) by lane code-j at the close of the #2954 audit (task 7683), so this follow-up has a live next action.
Change:deepMergeProviders now writes every overlay key with Object.defineProperty (own enumerable/writable/configurable data property) instead of out[k] = …, and resolves the base side through hasOwnProperty so a missing __proto__ cannot resolve to Object.prototype.
Tests:node --test bin/provider-catalog-sync.test.mjs — 37 pass / 0 fail on the branch, including two new probe tests (object __proto__ at depth 2 with constructor/toString/ordinary keys + JSON round-trip; string __proto__ at depth 3). The same two tests run against the origin/main helper give 35 pass / 2 fail, proving the bug. CI was not yet reported on the branch at completion.
Outcome: PR fix(catalog-sync): define __proto__ keys in deepMergeProviders (#4957) #5011 merged at 2026-11-03T16:14:52Z (merge commit 27f12c6e6054b5683ce89aa099c6a0311811a03a); no PR-tier checks were reported on the branch and mergeStateStatus was CLEAN, so the household-verified test run (37 pass / 0 fail, plus red-on-main proof) was the gate. The fix is now on main; the full main tier runs post-merge.
Activity
dezren39 commentedon Nov 3, 2026
agent-note:v1
state: queued
Enqueued as task 8074 (small_fix, repo-health-code-pilot) by lane code-j at the close of the #2954 audit (task 7683), so this follow-up has a live next action.
dezren39 commentedon Nov 3, 2026
🤖 Agent note · handed off
opencode; re-handing off to the laptop claimant (earlier handoff at 14:38Z expired unlaunched). Claim labels were missing on the issue and are now synced.fix(catalog-sync): define __proto__ keys in deepMergeProviders (#4957)
dezren39 commentedon Nov 3, 2026
🤖 Agent note · done
pr_opened. PR fix(catalog-sync): define __proto__ keys in deepMergeProviders (#4957) #5011fix(catalog-sync): define __proto__ keys in deepMergeProviderson branchqueue/8074-4957-deep-merge-define(commit96026522b).deepMergeProvidersnow writes every overlay key withObject.defineProperty(own enumerable/writable/configurable data property) instead ofout[k] = …, and resolves the base side throughhasOwnPropertyso a missing__proto__cannot resolve toObject.prototype.node --test bin/provider-catalog-sync.test.mjs— 37 pass / 0 fail on the branch, including two new probe tests (object__proto__at depth 2 withconstructor/toString/ordinary keys + JSON round-trip; string__proto__at depth 3). The same two tests run against theorigin/mainhelper give 35 pass / 2 fail, proving the bug. CI was not yet reported on the branch at completion.Merge pull request #5011 from developing-today/queue/8074-4957-deep-m…
dezren39 commentedon Nov 3, 2026
🤖 Agent note · done (merge follow-up)
27f12c6e6054b5683ce89aa099c6a0311811a03a); no PR-tier checks were reported on the branch andmergeStateStatuswas CLEAN, so the household-verified test run (37 pass / 0 fail, plus red-on-main proof) was the gate. The fix is now onmain; the full main tier runs post-merge.