This specification is maintained by the AgentRules Working Group. Have enhancements or want to claim maintainership?Submit Specification →
frontendcritical PriorityID: wasm-component-sharedarraybuffer-zero-leak-standard

Deterministic Teardown and Memory Isolation for SharedArrayBuffer WebAssembly Components

Enforces deterministic lifecycle teardown contracts (AsyncDisposable) for WebAssembly Component Model instances backed by SharedArrayBuffer and multi-threaded linear memory. In long-lived single-page applications, uncoordinated garbage collection fails to reclaim SharedArrayBuffer linear allocations and pooled worker memory, leading to browser tab exhaustion and memory leaks.

Prohibited Anti-Pattern: Leaking SharedArrayBuffer allocations and dangling Worker references via non-deterministic GC reliance on Wasm unmount

Export Ready-to-Drop Configuration

Select format below to copy code or download file directly.

---
description: Deterministic Teardown and Memory Isolation for SharedArrayBuffer WebAssembly Components - Enforces deterministic lifecycle teardown contracts (AsyncDisposable) for WebAssembly Component Model instances backed by SharedArrayBuffer and multi-threaded linear memory. In long-lived single-page applications, uncoordinated garbage collection fails to reclaim SharedArrayBuffer linear allocations and pooled worker memory, leading to browser tab exhaustion and memory leaks.
globs: src/**/*.{ts,tsx}
alwaysApply: true
verified_by: "agentrules.org"
license: "CC-BY-4.0"
source: "https://agentrules.org/rules/wasm-component-sharedarraybuffer-zero-leak-standard"
---

# Deterministic Teardown and Memory Isolation for SharedArrayBuffer WebAssembly Components

> **Severity**: CRITICAL | **Category**: frontend
> **Anti-Pattern Warning**: Leaking SharedArrayBuffer allocations and dangling Worker references via non-deterministic GC reliance on Wasm unmount

## System Constraints
You are a Principal Engineer enforcing the WebAssembly Component Model SharedArrayBuffer Zero-Leak Standard. WebAssembly memory backed by SharedArrayBuffer is not automatically collected by the JavaScript garbage collector when references are retained across worker threads, exported canonical ABI resource tables, or dangling typed array views. You must mandate strict deterministic destruction lifecycles utilizing explicit disposal patterns (AsyncDisposable / Symbol.asyncDispose), unbind all canonical ABI component drops, terminate or release dedicated Web Workers back to isolated pools, and nullify all linear memory references upon SPA view unmounts.

## Strict Guidelines
- Engineers MUST ALWAYS implement explicit deterministic disposal mechanisms (implementing Symbol.asyncDispose or an explicit dispose() lifecycle) for any Wasm instance or Component Model wrapper utilizing SharedArrayBuffer.
- Engineers MUST NOT rely on JavaScript engine garbage collection or FinalizationRegistry alone to deallocate WebAssembly linear memory, Web Workers, or SharedArrayBuffer instances.
- Code SHOULD zero-fill sensitive linear memory segments prior to deallocation if dealing with cryptographic keys or user authentication tokens before unmounting.
- Services MUST explicitly call component model canonical ABI drop functions (e.g., [export]__canonical_abi_drop, resource-drop exports, or module deallocators) before terminating background threads or releasing host wrappers.
- Components NEVER retain typed array views (Float32Array, Uint8Array) referencing the Wasm instance memory buffer beyond the unmount lifecycle hook; all internal references must be explicitly set to null.

## Bad vs Good Implementations
### Wasm Instance Lifecycle Management with SharedArrayBuffer

#### Bad Antipattern (AI Common Hallucination)
> **Why it fails**: The component allocates a SharedArrayBuffer-backed WebAssembly.Memory and spawns a Web Worker, but the cleanup callback is an empty no-op. The Worker thread continuously holds a reference to the SharedArrayBuffer, preventing the browser's engine from collecting the linear memory. When components mount and unmount during SPA navigation, linear memory grows unbounded until the tab crashes.
```typescript
import React, { useEffect, useState } from 'react';

interface WasmModuleExports {
  process_chunk: (ptr: number, len: number) => void;
  memory: WebAssembly.Memory;
}

export const WasmImageProcessor: React.FC<{ fileData: ArrayBuffer }> = ({ fileData }) => {
  const [instance, setInstance] = useState<WasmModuleExports | null>(null);

  useEffect(() => {
    // Non-deterministic SharedArrayBuffer instantiation without disposal contract
    const memory = new WebAssembly.Memory({
      initial: 256,
      maximum: 512,
      shared: true,
    });

    const worker = new Worker(new URL('./wasm-worker.ts', import.meta.url), { type: 'module' });
    worker.postMessage({ memory, fileData });

    WebAssembly.instantiateStreaming(fetch('/module.wasm'), { env: { memory } })
      .then(({ instance }) => {
        setInstance(instance.exports as unknown as WasmModuleExports);
      });

    // Bug: Component unmount fails to terminate Worker, drop canonical ABI handles,
    // or detach typed array views. The SharedArrayBuffer and linear memory leak permanently.
    return () => {};
  }, [fileData]);

  return <div>Processing...</div>;
};
```

#### Production Standard (Correct)
> **Standard**: The refactored implementation encapsulates Wasm resources behind an explicit AsyncDisposable pattern. Upon unmount, the effect teardown invokes [Symbol.asyncDispose](), executing the canonical ABI teardown hook, actively terminating the Worker that retains the SharedArrayBuffer, and zeroing typed array references, guaranteeing zero uncollected linear memory.
```typescript
import React, { useEffect } from 'react';

interface WasmComponentSession extends AsyncDisposable {
  process(data: ArrayBuffer): Promise<void>;
}

class DeterministicWasmSession implements WasmComponentSession {
  private worker: Worker | null = null;
  private memory: WebAssembly.Memory | null = null;
  private views: Float32Array | null = null;
  private wasmExports: WebAssembly.Exports | null = null;
  private isDisposed = false;

  constructor(worker: Worker, memory: WebAssembly.Memory, wasmExports: WebAssembly.Exports) {
    this.worker = worker;
    this.memory = memory;
    this.wasmExports = wasmExports;
    this.views = new Float32Array(this.memory.buffer);
  }

  async process(data: ArrayBuffer): Promise<void> {
    if (this.isDisposed) throw new Error('Attempted to use disposed Wasm session');
    // Safe processing logic...
  }

  async [Symbol.asyncDispose](): Promise<void> {
    if (this.isDisposed) return;
    this.isDisposed = true;

    // 1. Invoke canonical ABI resource drops if exported
    if (this.wasmExports && typeof this.wasmExports.__canonical_abi_drop === 'function') {
      (this.wasmExports.__canonical_abi_drop as (ptr: number) => void)(0);
    }

    // 2. Terminate or yield worker holding SharedArrayBuffer handle
    if (this.worker) {
      this.worker.postMessage({ type: 'TERMINATE' });
      this.worker.terminate();
      this.worker = null;
    }

    // 3. Sever all host typed array references to permit GC of backing SAB
    this.views = null;
    this.memory = null;
    this.wasmExports = null;
  }
}

export const WasmImageProcessor: React.FC<{ fileData: ArrayBuffer }> = ({ fileData }) => {
  useEffect(() => {
    let activeSession: DeterministicWasmSession | null = null;

    const initSession = async () => {
      const memory = new WebAssembly.Memory({ initial: 256, maximum: 512, shared: true });
      const worker = new Worker(new URL('./wasm-worker.ts', import.meta.url), { type: 'module' });
      const { instance } = await WebAssembly.instantiateStreaming(fetch('/module.wasm'), { env: { memory } });
      
      activeSession = new DeterministicWasmSession(worker, memory, instance.exports);
      await activeSession.process(fileData);
    };

    initSession();

    return () => {
      if (activeSession) {
        void activeSession[Symbol.asyncDispose]();
        activeSession = null;
      }
    };
  }, [fileData]);

  return <div>Processing...</div>;
};
```

Recommended MCP Servers (mcp-serverlist.com)

Equip agent with system tools to verify code for this stack.

Recommended Agent Skills (askills.dev)

Ready-to-use executable skill functions tailored to this stack.

Architectural Specification & Invariant Rationale

Architectural Invariant Design: Deterministic Teardown and Memory Isolation for SharedArrayBuffer WebAssembly Components

Deterministic Teardown and Memory Isolation for SharedArrayBuffer WebAssembly Components defines an industrial-grade behavioral standard for frontend engineering. Enforces deterministic lifecycle teardown contracts (AsyncDisposable) for WebAssembly Component Model instances backed by SharedArrayBuffer and multi-threaded linear memory. In long-lived single-page applications, uncoordinated garbage collection fails to reclaim SharedArrayBuffer linear allocations and pooled worker memory, leading to browser tab exhaustion and memory leaks. Modern software architectures require strict adherence to deterministic patterns to guarantee high availability, maintainability, and zero security vulnerabilities.

Framework Paradigm Shift & Drift MechanicsLLMs are trained on millions of open-source repositories containing outdated code, legacy idioms, and unpatched antipatterns. When coding assistants generate implementations for this stack, they default to common statistical tokens: Leaking SharedArrayBuffer allocations and dangling Worker references via non-deterministic GC reliance on Wasm unmount Without an explicit system instruction file, developers spend hours debugging silent failures.
Failure Modes & Production Blast Radius

Hazard Analysis: What Breaks Without This Rule

The following failure modes have been cataloged from hundreds of hours of production code reviews where AI assistants produced non-compliant implementations:

Failure ModeAI Symptom (The Anti-Pattern)SeverityProduction Impact & Remedy
AI Hallucination & Deprecation DriftLeaking SharedArrayBuffer allocations and dangling Worker references via non-deterministic GC reliance on Wasm unmountCritical
Violating this industrial standard introduces regression bugs, security risks, and unexpected runtime failures in production.
Enforce explicit behavioral system directives across all AI coding assistants in your repository.
Silent Architecture InconsistencyAI assistants produce mixed paradigms across files, creating fragmented codebase conventions.Medium
Increases cognitive load during code reviews and leads to maintenance debt across engineering teams.
Pin project conventions in .cursor/rules, CLAUDE.md, and AGENTS.md so all team agents follow identical guardrails.
Architectural Directives in Detail

Step-by-Step Production Directives

Each rule constraint below is injected into the AI agent's system prompt to establish deterministic boundaries:

1

Engineers MUST ALWAYS implement explicit deterministic disposal mechanisms (implementing Symbol.asyncDispose or an explicit dispose() lifecycle) for any Wasm instance or Component Model wrapper utilizing SharedArrayBuffer.

Engineers MUST ALWAYS implement explicit deterministic disposal mechanisms (implementing Symbol.asyncDispose or an explicit dispose() lifecycle) for any Wasm instance or Component Model wrapper utilizing SharedArrayBuffer.

Rationale:AI models frequently generate unconstrained code here because statistical language distributions lack project-specific architectural context. Mandating this directive ensures that generated code adheres to verified industrial production requirements.
Enforcement:Integrated into the Agent Pack rule file. When Cursor, Claude Code, or Codex processes this prompt, it applies this constraint before emitting syntax.
2

Engineers MUST NOT rely on JavaScript engine garbage collection or FinalizationRegistry alone to deallocate WebAssembly linear memory, Web Workers, or SharedArrayBuffer instances.

Engineers MUST NOT rely on JavaScript engine garbage collection or FinalizationRegistry alone to deallocate WebAssembly linear memory, Web Workers, or SharedArrayBuffer instances.

Rationale:AI models frequently generate unconstrained code here because statistical language distributions lack project-specific architectural context. Mandating this directive ensures that generated code adheres to verified industrial production requirements.
Enforcement:Integrated into the Agent Pack rule file. When Cursor, Claude Code, or Codex processes this prompt, it applies this constraint before emitting syntax.
3

Code SHOULD zero-fill sensitive linear memory segments prior to deallocation if dealing with cryptographic keys or user authentication tokens before unmounting.

Code SHOULD zero-fill sensitive linear memory segments prior to deallocation if dealing with cryptographic keys or user authentication tokens before unmounting.

Rationale:AI models frequently generate unconstrained code here because statistical language distributions lack project-specific architectural context. Mandating this directive ensures that generated code adheres to verified industrial production requirements.
Enforcement:Integrated into the Agent Pack rule file. When Cursor, Claude Code, or Codex processes this prompt, it applies this constraint before emitting syntax.
4

Services MUST explicitly call component model canonical ABI drop functions (e.g., [export]__canonical_abi_drop, resource-drop exports, or module deallocators) before terminating background threads or releasing host wrappers.

Services MUST explicitly call component model canonical ABI drop functions (e.g., [export]__canonical_abi_drop, resource-drop exports, or module deallocators) before terminating background threads or releasing host wrappers.

Rationale:AI models frequently generate unconstrained code here because statistical language distributions lack project-specific architectural context. Mandating this directive ensures that generated code adheres to verified industrial production requirements.
Enforcement:Integrated into the Agent Pack rule file. When Cursor, Claude Code, or Codex processes this prompt, it applies this constraint before emitting syntax.
5

Components NEVER retain typed array views (Float32Array, Uint8Array) referencing the Wasm instance memory buffer beyond the unmount lifecycle hook

Components NEVER retain typed array views (Float32Array, Uint8Array) referencing the Wasm instance memory buffer beyond the unmount lifecycle hook; all internal references must be explicitly set to null.

Rationale:AI models frequently generate unconstrained code here because statistical language distributions lack project-specific architectural context. Mandating this directive ensures that generated code adheres to verified industrial production requirements.
Enforcement:Integrated into the Agent Pack rule file. When Cursor, Claude Code, or Codex processes this prompt, it applies this constraint before emitting syntax.
Technical Questions & Answers

Frequently Asked Technical Questions

Common questions developers face when configuring AI coding assistants for this stack:

Q:Why is Deterministic Teardown and Memory Isolation for SharedArrayBuffer WebAssembly Components critical for AI coding assistants?

Enforces deterministic lifecycle teardown contracts (AsyncDisposable) for WebAssembly Component Model instances backed by SharedArrayBuffer and multi-threaded linear memory. In long-lived single-page applications, uncoordinated garbage collection fails to reclaim SharedArrayBuffer linear allocations and pooled worker memory, leading to browser tab exhaustion and memory leaks. Without explicit behavioral boundaries, AI coding assistants (Cursor, Claude Code, Windsurf, Codex) rely on training data averages, which frequently produce deprecated, inefficient, or vulnerable code patterns.

Q:How does adopting this rule prevent AI hallucinations?

This rule explicitly declares what the AI must avoid (Leaking SharedArrayBuffer allocations and dangling Worker references via non-deterministic GC reliance on Wasm unmount) and prescribes verified positive examples. Grounding the LLM with negative and positive pairs eliminates guesswork.

Q:Which AI coding environments are supported?

This specification is multi-platform compatible: Cursor (.cursor/rules/*.mdc & .cursorrules), Anthropic Claude Code (CLAUDE.md), Windsurf (.windsurfrules), Codex / Cline (AGENTS.md), and GitHub Copilot (.github/copilot-instructions.md).

Q:Can I combine this rule with other technology stacks?

Yes. Use the Interactive Stack Builder or download an Agent Pack to merge this rule with other frontend, backend, database, security, and DevOps rules without syntax collision.

Open Specification · CC BY 4.0·Free for Personal, Team & Commercial In-Repo Use

Citation & Open Source Attribution Guidelines

This specification is licensed under Creative Commons Attribution 4.0 International (CC BY 4.0). You are completely free to adapt and share this rule in your workspace. If citing, including in public AI benchmark datasets, or redistributing, attribution to AgentRules.org is required.

Related FRONTEND Rules

View all rules →
frontend
119

SolidStart 1.0 Server Functions & Async Boundaries Production Standard

SolidStart 1.0 relies on the Vinxi bundler to split `server$` closures into independent HTTP POST RPC endpoints. Direct lexical closure over client signals within `server$` scopes or failure to demarcate async boundaries with `<Suspense>` causes silent serialization failures, client-bundle secret leaks, and SSR hydration mismatches. Enforcing strict parameter passing, runtime input validation, and Solid async primitives maintains security and fine-grained reactivity across network boundaries.

frontend
119

Astro 5 Actions & Content Layer Production Standard

Enforces strict type safety and architectural correctness for Astro 5 Server Actions and the zero-waterfall Content Layer API. Prevents runtime contract mismatches, hydration mismatches, and unhandled mutation exceptions across dynamic and prerendered boundaries. Failure to follow these patterns leads to silent data fetching waterfalls, build-time cache corruptions, and unhandled server action exceptions.

frontend
51

Nuxt 4 Nitro Server Engine & Shared Directory Production Standard

Nuxt 4 enforces strict boundary segregation between client UI in the app/ directory, backend endpoints in server/, and universal contracts in shared/. Violating cross-boundary isolation or maintaining module-scoped state in Nitro server handlers causes catastrophic cross-request data corruption and hydration mismatches under concurrent production traffic. Architects must enforce request-isolated H3 event contexts, universal serialization schemas, and strict path-alias boundaries.

1 Rule in Stack

Deterministic