Bundle Safety
Trigger
- minify / minification / bundle / esbuild / build size
- re-export / namespace re-export / exportLines / exportRanges
- dist/index.js conformance checks
- identifier preservation / stack trace readability
- consumer-constraint verification before transforms
Required Procedure
(a) Minification Variant Selection
The standard minification configuration for the plugin bundle is identifier-preserving:
--minify-whitespace --minify-syntax
This yields 22.3% size reduction on the main bundle (1.28 MB absolute). The reduction is below the optimistic 35–43% range because identifier mangling is deliberately skipped.
Full identifier mangling (--minify-identifiers) is REJECTED. It breaks two hard constraints:
- 13 grep guardrail assertions — split across
tests/unit/build/full-auto-toolbefore-fail-closed.test.ts(fail-closed hook substring/wrapping checks) andtests/unit/turbo/lean/runtime-conformance.test.ts(Lean Turbo identifier-preservation checks). Mangling would rename these identifiers and cause all 13 assertions to fail. - Stack-trace readability — preserved identifier names are required for runtime debugging. The release-gate test
tests/unit/build/throw-and-verify-located.test.tsasserts that thrown errors carry readable stack frames with recognizable function names (e.g.initializeOpenCodeSwarm).
Decision is final: identifier-preserving minify is the standard. Do not enable --minify-identifiers without a documented exception approved by the team.
(b) Consumer-Constraint Verification Before Transforms
Before merging any minification or transform change:
- Build the smallest possible test bundle with the proposed transform flags.
- Run the consumer's exact constraint check first — the 13 grep guardrails are split across
tests/unit/build/full-auto-toolbefore-fail-closed.test.ts(fail-closed hook constraints) andtests/unit/turbo/lean/runtime-conformance.test.ts(Lean Turbo identifier-preservation checks). Together they are the authoritative consumer constraint. - Run the full build conformance suite (
tests/unit/build/throw-and-verify-located.test.ts,tests/unit/turbo/lean/runtime-conformance.test.ts) to verify runtime integrity and stack-trace readability. - Only merge if all guardrail assertions pass. A single grep guardrail failure blocks the change.
This procedure applies to any transform that could rename, inline, or remove identifiers — not just minification flags.
(c) Identifier-Preservation Testing
Verify identifier names survive the transform via the layered test stack:
Static (grep) layer:
tests/unit/build/full-auto-toolbefore-fail-closed.test.ts— fail-closed hook substring/wrapping checks verifying that specific identifier substrings (e.g.fullAutoPermissionHook.toolBefore,guardrailsHooks.toolBefore,scopeGuardHook.toolBefore,delegationGateHooks.toolBefore) are present and that fail-closed hooks are not wrapped insafeHook(...).tests/unit/turbo/lean/runtime-conformance.test.ts—distContains()checks verifying that Lean Turbo integration-point identifiers (verifyLeanTurboPhaseReady,verifyLeanTurboTaskCompletion,LEAN_TURBO_BANNER,enableLeanTurbo,hasActiveTurboMode) survive the build.
Runtime layer:
tests/unit/build/throw-and-verify-located.test.ts— asserts that thrown errors carry readable stack frames with preserved function names (e.g.initializeOpenCodeSwarm). This is the runtime complement to the static grep assertions.
Before enabling --minify-identifiers, confirm ALL of the following:
- No
eval()orFunction('...')dispatch in the bundle (mangled identifiers break dynamic dispatch). - No
constructor.nameorFunction.nameintrospection in production paths. - No
@__PURE__annotations or side-effectful top-level patterns that depend on identifier stability. - All 13 grep guardrails still pass.
- Stack-trace readability is verified at runtime.
If any of these checks fail, --minify-identifiers must not be enabled.
(d) Namespace Re-Export Coverage
When modifying re-export or export-tracking logic (e.g. exportLines, exportRanges, parseFileImports):
Test both forms of namespace re-export — they are distinct AST forms that require separate tracking:
- Regular namespace re-export:
export * from './module' - Aliased namespace re-export:
export * as ns from './module'
The regex in src/tools/repo-graph/builder.ts (parseFileImports) handles both via the pattern export\s+\*(?:\s+as\s+\w+)?\s+from\s+['"]([^'"\0\t\r\n]+)['"]`. Both forms must be tested when modifying export tracking because:
- They produce different
importTypevalues in the parsed output (namespacefor both, but the aliased form carries a local binding name). - They require separate tracking in
exportLines/exportRanges— the aliased form creates a local binding (ns) that must be recorded alongside the re-exported symbols. - Missing either form causes silent graph gaps in
repo-graphcallers/dead-exports analysis.
Test file: tests/unit/tools/repo-graph-reexports.test.ts covers both forms (see test case "4. export * as ns from './bar' — TypeScript namespace re-export → importType: namespace"). Run this test alongside any export-tracking change.
Forbidden Shortcuts
- Enabling
--minify-identifierswithout confirming all 13 grep guardrails pass and runtime stack-trace readability is verified. - Merging a minification/transform change without first running the consumer-constraint check (the 13 grep guardrails) against the smallest possible bundle.
- Modifying re-export/export tracking without testing
export * as ns from '...'(aliased namespace) alongsideexport * from '...'(regular namespace). - Assuming identifier preservation is "good enough" without running the full grep guardrail stack plus runtime stack-trace inspection.
Delegation Template
When delegating a task affected by this skill, include:
SKILLS: file:.opencode/skills/generated/bundle-safety/SKILL.md
Reviewer Checks
- Verify the minification config in the build script matches
--minify-whitespace --minify-syntax(no--minify-identifiers). - Verify
tests/unit/build/full-auto-toolbefore-fail-closed.test.tspasses against the builtdist/index.js(fail-closed hook guardrails green). - Verify
tests/unit/turbo/lean/runtime-conformance.test.tspasses (Lean Turbo identifier-preservation guardrails green). - Verify
tests/unit/build/throw-and-verify-located.test.tspasses (runtime stack-trace readability). - If re-export tracking was modified, verify
tests/unit/tools/repo-graph-reexports.test.tscovers bothexport * from '...'andexport * as ns from '...'. - Verify
dist/index.jssize is under the packaging gate (MAIN_BUNDLE_MAX_BYTES = 8.0 MiBintests/smoke/packaging.test.ts).
Source Knowledge IDs
- 5746c5c9-1330-4fbe-b62e-f564deb1ff77 — Before enabling any minification or transform flag, verify it doesn't break a hard consumer constraint by testing the smallest possible bundle against the exact constraint check. Required actions: test build output against consumer constraints before merging minification changes; build a minimal test bundle and run the consumer's validation first.
- 5d99affe-bdd1-4945-8cd8-fcf37abb8c84 — Identifier-preserving minify (--minify-whitespace --minify-syntax) yields 22.3% on this bundle (1.28MB absolute) — substantial but below the optimistic 35-43% because identifier mangling is deliberately skipped to keep stack traces readable. The standard is identifier-preserving; full mangling is REJECTED because it breaks the 13 identifier-grepping guardrail assertions and stack-trace readability.
- 9323a8f0-c07e-41c2-9857-11a24c55dca2 — When re-export handling is modified, verify aliased namespace re-exports (
export * as ns from '...') are preserved alongside regular re-exports — they are distinct AST forms that require separate tracking in exportLines/exportRanges. Required: test namespace re-exports alongside regular re-exports when modifying export tracking.