Bundle Safety

SkillDev tools

Bundle transform safety — minification variant selection, consumer-constraint verification, identifier preservation, and namespace re-export coverage for build output.

Available today. Use it from your connected AI after setup.

Connect ahel once, and every AI you use reads what you have installed.

Then ask your AI: use the Bundle Safety skill

What this skill tells your AI

The instructions your AI receives, as published by zaxbyhub/opencode-swarm in .opencode/skills/generated/bundle-safety/SKILL.md and read by ahel’s review.

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:

  1. 13 grep guardrail assertions — split across tests/unit/build/full-auto-toolbefore-fail-closed.test.ts (fail-closed hook substring/wrapping checks) and tests/unit/turbo/lean/runtime-conformance.test.ts (Lean Turbo identifier-preservation checks). Mangling would rename these identifiers and cause all 13 assertions to fail.
  2. Stack-trace readability — preserved identifier names are required for runtime debugging. The release-gate test tests/unit/build/throw-and-verify-located.test.ts asserts 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:

  1. Build the smallest possible test bundle with the proposed transform flags.
  2. 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) and tests/unit/turbo/lean/runtime-conformance.test.ts (Lean Turbo identifier-preservation checks). Together they are the authoritative consumer constraint.
  3. 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.
  4. 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 in safeHook(...).
  • tests/unit/turbo/lean/runtime-conformance.test.tsdistContains() 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() or Function('...') dispatch in the bundle (mangled identifiers break dynamic dispatch).
  • No constructor.name or Function.name introspection 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:

  1. Regular namespace re-export: export * from './module'
  2. 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 importType values in the parsed output (namespace for 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-graph callers/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-identifiers without 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) alongside export * 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.ts passes against the built dist/index.js (fail-closed hook guardrails green).
  • Verify tests/unit/turbo/lean/runtime-conformance.test.ts passes (Lean Turbo identifier-preservation guardrails green).
  • Verify tests/unit/build/throw-and-verify-located.test.ts passes (runtime stack-trace readability).
  • If re-export tracking was modified, verify tests/unit/tools/repo-graph-reexports.test.ts covers both export * from '...' and export * as ns from '...'.
  • Verify dist/index.js size is under the packaging gate (MAIN_BUNDLE_MAX_BYTES = 8.0 MiB in tests/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.

Signals

GitHub stars
467
Forks
51
Last commit
Sep 2026
Advanced
Catalog kind
skill
Gateway key
bundle-safety
Source
github.com/zaxbyhub/opencode-swarm