fix(post-release): split CJS smoke into resolve (bridge-off) + require (default) to end engines-contract false failure#142
Conversation
…e (default) to end engines-contract false failure
|
The two-phase split is logically sound. Phase 1 correctly scopes One minor gap: the No high-confidence correctness, security, or reliability issues found in the changed lines. Review iteration 1 · Commit 6ac1082 · 2026-07-21T09:23:10Z |
Summary
Closes #135. The post-release "Smoke: CJS imports" gate failed for
@piplabs/cdr-cryptoand@piplabs/cdr-sdkwithERR_REQUIRE_ESM: require() of ES Module @noble/hashes/hkdf.js— a false failure. Two of our own gates disagreed:cdr-cryptopins@noble/hashes@2.0.1(ESM-only), so the CJS build loads it via Node'srequire(esm)bridge —NODE_OPTIONS=--no-experimental-require-module, disabling that bridge to protect "consumers on Node <20.19" — a runtime theenginesfield already excludes, and whose rationale expired when Node 20 hit EOL (April 2026).The dual-publish itself is fine: on every runtime
enginesadmits, plainrequire("@piplabs/cdr-sdk")works. Only the gate was wrong.Fix (issue Option 1)
Split the single step into two correctly-configured phases, so the gate tests what real consumers hit while keeping the regression it was built for:
require.resolve(), bridge OFF. Keeps--no-experimental-require-module. Resolves the CJS entry without executing it, so it never touches the ESM-only transitive dep. Still fails loudly if a package loses its CJS entry (ships ESM-only with noexports.require).require(), default Node options (bridge ON). Actually requires the package the way a consumer on a supported runtime does. The ESM-only transitive dep loads via the bridge.Row output now prefixes failures with
resolve:/require:so a red gate says which phase broke.Test plan
NODE_OPTIONSenv removed;cjs_smokeid +rowsoutput preserved (summary section unchanged)@piplabs/cdr-{contracts,crypto,sdk}):post-release-integration.ymlfrom this branch againstversion=0.2.2— expect the CJS smoke greenNotes
--no-experimental-require-moduleflag on Phase 1 is spec-per-issue but functionally vestigial:require.resolve()is unaffected by the bridge flag. Kept to document intent and match the issue's recommendation.verifyjob's Node 20 pin (still>=20.19) remains correct — Phase 2 depends on the bridge being on by default, which that line provides.