bundle-safety · v1 · 2026-08-28 · sha256 6a17e2aba80f3c86
bundle-safety v1A
Immutable. This exact content is served forever at /api/v1/blob/6a17e2aba80f3c86.
---
name: bundle-safety
description: Bundle transform safety — minification variant selection, consumer-constraint verification, identifier preservation, and namespace re-export coverage for build output.
triggers:
- minify
- minification
- bundle
- esbuild
- build size
- re-export
- identifier
- namespace re-export
- exportLines
- exportRanges
- dist/index.js
generated_from_knowledge:
- 5746c5c9-1330-4fbe-b62e-f564deb1ff77
- 5d99affe-bdd1-4945-8cd8-fcf37abb8c84
- 9323a8f0-c07e-41c2-9857-11a24c55dca2
source_knowledge_ids:
- 5746c5c9-1330-4fbe-b62e-f564deb1ff77
- 5d99affe-bdd1-4945-8cd8-fcf37abb8c84
- 9323a8f0-c07e-41c2-9857-11a24c55dca2
generated_at: 2026-07-02T20:47:50.522Z
confidence: 0.60
status: active
version: 1
skill_origin: generated
---
<!-- generated by opencode-swarm skill-generator. Do not edit by hand; edits will be preserved on regeneration only with controlled update mode. -->
# 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:
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.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()` 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.