Skip to content

fix(#755): collapse duplicate engines keys, teach gate-toolchain to detect them - #822

Merged
claude[bot] merged 2 commits into
masterfrom
claude/issue-755-duplicate-engines
Aug 27, 2026
Merged

fix(#755): collapse duplicate engines keys, teach gate-toolchain to detect them#822
claude[bot] merged 2 commits into
masterfrom
claude/issue-755-duplicate-engines

Conversation

@github-actions

Copy link
Copy Markdown
Contributor

Root cause: the #646/#647 engines sweep appended a second "engines" block to
32 package.json manifests that already had one (likely a re-run of the sweep
over an already-touched worklist). JSON.parse silently keeps the LAST
occurrence of a duplicate key, so every one of these manifests parsed to a
single well-formed engines value and nothing complained -- gate-toolchain's
entire job is policing engines, and it was structurally blind to engines
being declared twice, because it reads manifests via JSON.parse.

PR #814 already fixed 4 of the original 36 (sdk, services/billing-service,
services/email-service, services/sms-service) as a side effect of an axios
bump. Re-measured from latest origin/master: 32 manifests were still
affected. All 32 duplicate pairs were verified byte-identical
(node ">=24.0.0", npm ">=10.0.0") before collapsing -- no divergent copies
were found, so this is a mechanical de-dup, not a behavior change.

Part B: gate-toolchain.mjs now tokenizes each package.json's raw text and
walks brace/bracket nesting to find top-level keys declared more than once,
BEFORE any JSON.parse-based check runs -- so a duplicate is caught even
though JSON.parse can't see it. Generalized beyond "engines" per the issue's
suggestion: any duplicated top-level key in a manifest is a latent version of
this same bug (JSON.parse takes last, other parsers take first or reject,
npm normalises and silently discards one). Verified the new check both
detects the regression (re-ran the gate against the pre-fix duplicates via
git stash -- 12/12 correctly flagged and failed) and produces zero false
positives on legitimately repeated key names nested under different parents.

Co-Authored-By: Claude Opus 5 noreply@anthropic.com
Claude-Session: https://claude.ai/code/session_013tMciHkPE8To7V67CsgKKc

…etect them

Root cause: the #646/#647 engines sweep appended a second "engines" block to
32 package.json manifests that already had one (likely a re-run of the sweep
over an already-touched worklist). JSON.parse silently keeps the LAST
occurrence of a duplicate key, so every one of these manifests parsed to a
single well-formed engines value and nothing complained -- gate-toolchain's
entire job is policing engines, and it was structurally blind to engines
being declared twice, because it reads manifests via JSON.parse.

PR #814 already fixed 4 of the original 36 (sdk, services/billing-service,
services/email-service, services/sms-service) as a side effect of an axios
bump. Re-measured from latest origin/master: 32 manifests were still
affected. All 32 duplicate pairs were verified byte-identical
(node ">=24.0.0", npm ">=10.0.0") before collapsing -- no divergent copies
were found, so this is a mechanical de-dup, not a behavior change.

Part B: gate-toolchain.mjs now tokenizes each package.json's raw text and
walks brace/bracket nesting to find top-level keys declared more than once,
BEFORE any JSON.parse-based check runs -- so a duplicate is caught even
though JSON.parse can't see it. Generalized beyond "engines" per the issue's
suggestion: any duplicated top-level key in a manifest is a latent version of
this same bug (JSON.parse takes last, other parsers take first or reject,
npm normalises and silently discards one). Verified the new check both
detects the regression (re-ran the gate against the pre-fix duplicates via
git stash -- 12/12 correctly flagged and failed) and produces zero false
positives on legitimately repeated key names nested under different parents.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_013tMciHkPE8To7V67CsgKKc
@github-actions
github-actions Bot requested a review from izzywdev as a code owner August 27, 2026 08:00
@github-actions github-actions Bot added the auto-merge Enable squash auto-merge once CI passes label Aug 27, 2026
@claude claude Bot closed this Aug 27, 2026
@claude claude Bot reopened this Aug 27, 2026
@github-actions
github-actions Bot enabled auto-merge (squash) August 27, 2026 08:06
@claude
claude Bot merged commit 28c4704 into master Aug 27, 2026
73 checks passed
@claude
claude Bot deleted the claude/issue-755-duplicate-engines branch August 27, 2026 11:28
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

auto-merge Enable squash auto-merge once CI passes

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant