Hot-Swap a 3D Avatar Without Publishing the Broken Frame A developer has published a tutorial for building a two-phase, transactional avatar loader that keeps the currently committed 3D avatar visible until a newly generated candidate passes policy validation and runtime qualification. The controller wraps Tencent RTC's Beauty AR SDK through a narrow adapter, using per-device-tier thresholds for declared asset size, qualification frames, bad-frame tolerance, and frame time, and deliberately avoids revealing the camera when no avatar has been committed. The implementation has no rendering-library dependency, making its state and failure behavior testable without a camera, GPU, or live room. An AI tool can help generate a 3D avatar concept, asset manifest, or integration scaffold in minutes. The uncomfortable part begins afterward: who decides that the candidate is safe to show in a live session? A model can produce something visually persuasive without proving that it loads on the target device, tracks correctly, stays within your rendering budget, or survives a failed wardrobe change. That does not make AI-assisted creation useless. It changes the engineering task. Instead of treating “the asset exists” as completion, we need a controlled transition from a candidate avatar to the avatar participants actually see . In this tutorial, we will build that transition as a two-phase loader: Tencent RTC Beauty AR supports scenarios including avatars, beauty effects, stickers, virtual backgrounds, and image or video enhancement. The official overview is here: https://trtc.io/document/beauty-ar-overview https://trtc.io/document/beauty-ar-overview The controller below deliberately sits around the selected Beauty AR SDK integration. It does not invent SDK methods. You map its narrow adapter to the APIs and platform described by the official documentation. Suppose a user is already represented by avatar-blue-v4 and selects a newly generated 3D avatar. The tempting implementation is: await loadAvatar nextAsset ; showAvatar nextAsset ; That leaves several questions unanswered: Our invariant is stronger: The committed avatar remains visible until a newer candidate has passed policy validation and runtime qualification. If no avatar has been committed, the application should show an explicit placeholder or paused-avatar state. It should not silently reveal the camera; camera presentation requires its own product policy and consent decision. mkdir transactional-avatar-loader cd transactional-avatar-loader npm init -y npm install --save-dev typescript vitest @types/node npx tsc --init mkdir src Add the test script to package.json : { "scripts": { "test": "vitest run" } } The implementation has no rendering-library dependency. That makes its state and failure behavior testable without a camera, GPU, or live room. Create src/avatar-loader.ts : export type DeviceTier = "low" | "mid" | "high"; export interface AvatarManifest { id: string; revision: string; format: "3d-avatar"; declaredBytes: number; } export interface PreparedAvatar { assetId: string; revision: string; opaqueHandle: unknown; } export interface FrameProbe { rendered: boolean; tracking: "good" | "lost"; frameTimeMs: number; } export interface TierPolicy { allow3dAvatar: boolean; maxDeclaredBytes: number; qualificationFrames: number; maxBadFrames: number; maxFrameTimeMs: number; } export type PolicyByTier = Record