# Mika Live2D Production Brief

- avatarId: `mika_live2d`
- runtime: `live2d`
- readyForLearnMore: `false`
- deliveryReady: `true`
- intakeReadyForApply: `true`
- nextMilestone: `source`
- LearnMore default until ready: `mao_pro`
- sample fallback: `mao_pro`

## Production Queue

- `runtime` (done) - missing: `-`; blocked: `-`; next: export Cubism runtime model3.json, moc3, textures, DisplayInfo, Physics, and Pose
- `source` (blocked) - missing: `-`; blocked: `-`; next: prepare layered Mika art source and editable Cubism project
- `expressions` (done) - missing: `-`; blocked: `-`; next: produce a/i/u/e/o mouth shapes plus blink, smile, surprised, and thinking expressions
- `motions` (done) - missing: `-`; blocked: `-`; next: produce idle, lyric reading, pointing, rhythm sway, chorus gesture, and soft dance motions
- `parameters` (done) - missing: `-`; blocked: `-`; next: confirm ParamA/I/U/E/O, ParamMouthDown, head, body, shoulder, and arm parameters in PARAMETER_MAP.json
- `license` (done) - missing: `-`; blocked: `-`; next: finalize source ownership, usage scope, and LearnMore attribution copy
- `acceptance` (done) - missing: `-`; blocked: `-`; next: record desktop and mobile preview media and approve LearnMore behavior

## Required Expressions

`a`, `i`, `u`, `e`, `o`, `blink`, `smile`, `surprised`, `thinking`

## Required Motions

`idle`, `greeting`, `lyric-reading`, `point-lyrics`, `rhythm-sway`, `chorus-gesture`, `soft-dance-loop`

## Required Runtime Maps

- expression map: `EXPRESSION_MAP.json` -> `runtime/expressions`
- motion map: `MOTION_MAP.json` -> `runtime/motions`
- model3 reference required: `true`
- expression rule: each value must resolve to a non-empty runtime expression file and be declared in model3 Expressions name/file
- motion rule: each value must resolve to a non-empty runtime motion file and be declared in model3 Motions group/file
- model3 declaration rule: all EXPRESSION_MAP.json and MOTION_MAP.json values must be declared in runtime/mika_live2d.model3.json

## Required Source Layer Split

- checklist file: `LAYER_SPLIT_CHECKLIST.md`
- PSD layer spec file: `PSD_LAYER_SPEC.md`
- source manifest file: `SOURCE_MANIFEST.json`
- source manifest URL: `/mika-avatar/handoff/mika-live2d/source-manifest.json`
- source manifest schema: `/mika-avatar/handoff/mika-live2d/source-manifest.schema.json`
- PSD layer manifest file: `PSD_LAYER_MANIFEST.json`
- PSD layer manifest URL: `/mika-avatar/handoff/mika-live2d/psd-layer-manifest.json`
- PSD layer manifest schema: `/mika-avatar/handoff/mika-live2d/psd-layer-manifest.schema.json`
- parts map file: `PARTS_MAP.json`
- parts map URL: `/mika-avatar/handoff/mika-live2d/parts-map.json`
- parts map schema: `/mika-avatar/handoff/mika-live2d/parts-map.schema.json`
- rigging spec file: `RIGGING_SPEC.json`
- rigging spec URL: `/mika-avatar/handoff/mika-live2d/rigging-spec.json`
- rigging spec schema: `/mika-avatar/handoff/mika-live2d/rigging-spec.schema.json`
- source dir: `source/`
- editable source extensions: `.cmo3, .psd, .clip, .kra`
- reference URLs: `https://moonku44.com/live2d-psd/, https://www.live2d.com/en/learn/sample/, https://www.facebook.com/reel/908184438905522/`
- canvas rule: front-facing sRGB source, long edge around 4000px or higher when full-body detail needs it
- layer hygiene rule: layers must be grouped by part, clearly named, non-duplicated, and cleaned for Cubism import
- modeling reference avatar: `mao_pro`
- modeling reference rule: Layered source must support mao_pro-like model-native Cubism parameters, not CSS or image overlays.
- source manifest rule: SOURCE_MANIFEST.json must inventory every source file with path, sizeBytes, sha256, editable/layered flags, producer, and source proof before sourceProjectReady can be true.
- PSD layer manifest rule: PSD_LAYER_MANIFEST.json must inventory every required Mika source layer id, group, PSD path, occluded-fill flag, mouth/physics/pose role, and Cubism-driven parameter set before sourceProjectReady can be true.
- parts map rule: PARTS_MAP.json must confirm source-layer parts for face, eyes, mouth, hair, body, arms, legs, clothes/accessories, physics targets, and pose targets before sourceProjectReady can be true.
- rigging spec rule: RIGGING_SPEC.json must connect split source parts to model-native Cubism parameters, deformers, artMeshTargets, physics, and pose targets before Mika can replace mao_pro in LearnMore.
- rejected source types: `single merged illustration, static PNG standee, CSS mouth overlay, DOM motion overlay, uneditable placeholder source`

- `arms-hands-separated`: 左右上臂、下臂、手掌需分離，能支援指歌詞、打拍子與抬手。
- `clothes-accessories-separated`: 衣服片、帽子、飾品、緞帶、垂墜物需和身體分層，能接物理或姿勢控制。
- `eyes-separated`: 左右眼需拆出眼白、眼球、高光、上下眼皮、睫毛與眉毛。
- `face-base-occluded-fill`: 臉部底圖需補齊被頭髮遮住的區域，方便頭髮、表情與角度變形。
- `front-facing-layered-source`: 正面角色來源必須是分層 PSD/CSP/KRA 或可編輯 .cmo3，不可只交單張合併圖。
- `hair-separated`: 頭髮需拆前髮、側髮、後髮、髮束與可物理晃動小件。
- `layer-hygiene`: 圖層需清楚命名、無重名、無無用隱藏圖層，特殊效果需整理成 Cubism 可匯入狀態。
- `legs-shoes-separated`: 左右大腿、小腿、鞋子需分離，保留日後腿部與全身動作擴充空間。
- `mao-pro-runtime-wiring`: 拆圖與建模需能像 mao_pro 一樣接 model3、DisplayInfo、Physics、Pose、Expressions、Motions。
- `mouth-internals-separated`: 嘴巴需拆出上下唇、牙齒、口腔、舌頭或等效內部色塊，支援 a/i/u/e/o。

## Source Export Preflight

- tool: `tools/live2d/inspect_mika_live2d_source_export.py`
- command: `python3 tools/live2d/inspect_mika_live2d_source_export.py deliveries/mika-live2d/source`
- default source dir: `deliveries/mika-live2d/source`
- ready field: `ready`
- source file ready field: `sourceFileReady`
- source manifest consistency field: `sourceManifestConsistency.ready`
- source package gate field: `sourcePackageAcceptanceGate`
- blocking field: `blockingReasons`
- required ready fields: `sourceFileReady`, `sourceManifestConsistency.ready`, `manifestStatus.sourceProject.ready`, `manifestStatus.sourceManifest.ready`, `manifestStatus.psdLayerManifest.ready`, `manifestStatus.partsMap.ready`, `manifestStatus.riggingSpec.ready`
- required file ids: `sourceProject`, `sourceManifest`, `psdLayerManifest`, `partsMap`, `riggingSpec`
- editable source extensions: `.cmo3`, `.psd`, `.clip`, `.kra`
- required manifest files: `SOURCE_MANIFEST.json`, `PSD_LAYER_MANIFEST.json`, `PARTS_MAP.json`, `RIGGING_SPEC.json`
- required layer split check ids: `arms-hands-separated`, `clothes-accessories-separated`, `eyes-separated`, `face-base-occluded-fill`, `front-facing-layered-source`, `hair-separated`, `layer-hygiene`, `legs-shoes-separated`, `mao-pro-runtime-wiring`, `mouth-internals-separated`

- single merged illustration
- static PNG standee
- uneditable placeholder source
- source files smaller than the minimum source project byte threshold
- SOURCE_MANIFEST paths, sizeBytes, or sha256 that do not match source/ files
- SOURCE_MANIFEST TODO placeholders
- unconfirmed SOURCE_MANIFEST, PSD_LAYER_MANIFEST, PARTS_MAP or RIGGING_SPEC

### Source Export Current Preflight

- url: `/mika-avatar/api/live2d/mika/source-export-preflight`
- ready: `true`
- sourceFileReady: `true`
- tool: `tools/live2d/inspect_mika_live2d_source_export.py`
- missing ids: -
- blocked ids: -

- No current source export blockers.

## Required Runtime Model

- contract file: `RUNTIME_MODEL_CONTRACT.json`
- contract URL: `/mika-avatar/handoff/mika-live2d/runtime-model-contract.json`
- contract schema: `/mika-avatar/handoff/mika-live2d/runtime-model-contract.schema.json`
- model JSON: `runtime/mika_live2d.model3.json`
- Version required: `3`
- root: `FileReferences`
- FileReferences.Moc required: `true`
- FileReferences.Textures required: `true`
- FileReferences.DisplayInfo required: `true`
- DisplayInfo required parameters: `ParamA, ParamI, ParamU, ParamE, ParamO, ParamMouthDown, ParamAngleX, ParamAngleY, ParamAngleZ, ParamBodyAngleX, ParamBodyAngleY, ParamBodyAngleZ, ParamAllX, ParamAllY, ParamAllRotate, ParamBreath, ParamLeftShoulderUp, ParamRightShoulderUp, ParamArmLA01, ParamArmLA02, ParamArmLA03, ParamArmRA01, ParamArmRA02, ParamArmRA03, ParamHandLA, ParamHandRA, ParamFingerL, ParamFingerR, ParamLegLA01, ParamLegLA02, ParamLegRA01, ParamLegRA02, ParamFootL, ParamFootR, ParamEyeLOpen, ParamEyeROpen, ParamEyeBallX, ParamEyeBallY, ParamEyeLSmile, ParamEyeRSmile, ParamCheek, ParamBrowLY, ParamBrowRY, ParamHairFront, ParamHairSideL, ParamHairSideR, ParamHairBack, ParamHairBackL, ParamHairBackR, ParamoHairMesh, ParamHairFrontFuwa, ParamHairSideFuwa, ParamHairBackFuwa, ParamSkirtFront, ParamSkirtSideL, ParamSkirtSideR, ParamSkirtFuwa, ParamSleeveL, ParamSleeveR`
- FileReferences.Physics required: `true`
- FileReferences.Pose required: `true`
- FileReferences.Expressions required: `true`
- FileReferences.Motions required: `true`
- Expressions Name required: `true`
- Motions group names required: `true`
- Motions groups non-empty: `true`
- Expressions files must exist: `true`
- Motions files must exist: `true`
- Physics/Pose files must exist: `true`
- Physics/Pose files must pass schema: `true`
- reference rule: all FileReferences paths must resolve to non-empty files under runtime/ and pass type-specific validation
- texture reference format rule: texture references must be valid PNG, JPEG, or WebP images with the required minimum texture dimensions
- displayInfo file schema rule: DisplayInfo must be a .cdi3.json file with Version=3 and Parameters entries for every required Mika mouth and motion parameter
- expression name rule: each FileReferences.Expressions item must include a non-empty Name that is not a placeholder
- motion group rule: each FileReferences.Motions group name must be non-empty and not a placeholder, and each group must contain at least one motion
- expression file schema rule: expression files must be JSON objects with a non-empty Parameters array
- motion file schema rule: motion files must be JSON objects with Meta and a non-empty Curves array
- physics file schema rule: declared physics files must be JSON objects with Version=3, Meta, and a non-empty PhysicsSettings array
- pose file schema rule: declared pose files must be JSON objects with Groups and valid part Id values

## Runtime Export Preflight

- tool: `tools/live2d/inspect_mika_live2d_runtime_export.py`
- command: `python3 tools/live2d/inspect_mika_live2d_runtime_export.py deliveries/mika-live2d/runtime`
- default runtime dir: `deliveries/mika-live2d/runtime`
- ready field: `ready`
- blocking field: `blockingReasons`
- required file ids: `runtimeModelJson`, `moc3`, `textures`, `displayInfo`, `physics`, `pose`, `expressions`, `motions`
- required DisplayInfo parameters: `ParamA`, `ParamI`, `ParamU`, `ParamE`, `ParamO`, `ParamMouthDown`, `ParamAngleX`, `ParamAngleY`, `ParamAngleZ`, `ParamBodyAngleX`, `ParamBodyAngleY`, `ParamBodyAngleZ`, `ParamAllX`, `ParamAllY`, `ParamAllRotate`, `ParamBreath`, `ParamLeftShoulderUp`, `ParamRightShoulderUp`, `ParamArmLA01`, `ParamArmLA02`, `ParamArmLA03`, `ParamArmRA01`, `ParamArmRA02`, `ParamArmRA03`, `ParamHandLA`, `ParamHandRA`, `ParamFingerL`, `ParamFingerR`, `ParamLegLA01`, `ParamLegLA02`, `ParamLegRA01`, `ParamLegRA02`, `ParamFootL`, `ParamFootR`, `ParamEyeLOpen`, `ParamEyeROpen`, `ParamEyeBallX`, `ParamEyeBallY`, `ParamEyeLSmile`, `ParamEyeRSmile`, `ParamCheek`, `ParamBrowLY`, `ParamBrowRY`, `ParamHairFront`, `ParamHairSideL`, `ParamHairSideR`, `ParamHairBack`, `ParamHairBackL`, `ParamHairBackR`, `ParamoHairMesh`, `ParamHairFrontFuwa`, `ParamHairSideFuwa`, `ParamHairBackFuwa`, `ParamSkirtFront`, `ParamSkirtSideL`, `ParamSkirtSideR`, `ParamSkirtFuwa`, `ParamSleeveL`, `ParamSleeveR`

- missing model3.json FileReferences
- missing DisplayInfo a/i/u/e/o mouth parameters
- missing Physics or Pose file references
- unreferenced runtime files
- empty or placeholder expression and motion files

### Runtime Export Current Preflight

- url: `/mika-avatar/api/live2d/mika/runtime-export-preflight`
- ready: `true`
- tool: `tools/live2d/inspect_mika_live2d_runtime_export.py`
- missing ids: -
- missing DisplayInfo parameters: -

- No current runtime export blockers.

## Open-LLM-VTuber Custom Model Contract

- source: Open-LLM-VTuber custom Live2D model workflow
- references: `https://github.com/Open-LLM-VTuber/OLV-Docker-Config/tree/main, https://blog.csdn.net/gitblog_00434/article/details/154483201`
- config mount dir: `/app/conf`
- Live2D models dir: `live2d-models`
- runtime dir: `live2d-models/mika_live2d/runtime`
- model dict file: `model_dict.json`
- model_dict name: `mika_live2d`
- model_dict url: `/live2d-models/mika_live2d/runtime/mika_live2d.model3.json`
- idle motion group: `Idle`
- emotionMap required: `true`
- character config values: `character_config.live2d_model_name=mika_live2d`, `character_config.conf_name=mika_live2d`
- required runtime files: `runtime/mika_live2d.model3.json`, `runtime/*.moc3`, `runtime/*.physics3.json`, `runtime/*.pose3.json`, `runtime/textures/`, `runtime/expressions/`, `runtime/motions/`
- minimum model3 FileReferences: `Moc`, `Textures`, `Physics`, `Pose`, `Expressions`, `Motions`
- placement rule: A finished Mika delivery must be intakeable into live2d-models/mika_live2d/runtime and registered in model_dict.json with the same avatar id before LearnMore can switch from mao_pro.

## Required Acceptance Evidence

- visual QA: `VISUAL_QA.json`
- checklist: `ACCEPTANCE_CHECKLIST.md`
- media dir: `acceptance/`
- required visual QA fields: `schemaVersion, reviewer, reviewedMedia, checks, blockingReasons, notes`
- reviewer rule: reviewer must be non-empty and not a placeholder
- blocking reasons rule: blockingReasons must be an empty array after approval
- notes rule: notes must be non-empty and not a placeholder
- reviewedMedia required: `true`
- media rule: VISUAL_QA.json reviewedMedia must list existing non-empty acceptance media files
- required media targets: `desktop, mobile`
- media target rule: reviewedMedia must include both desktop and mobile LearnMore acceptance evidence
- media format rule: reviewedMedia files must have a valid image/video container signature matching the file extension
- minimum image dimensions: `320x240`
- image dimension rule: image reviewedMedia must be parseable and at least 320x240 pixels
- checklist rule: all required acceptance checks must be checked with [x]
- checklist evidence rule: each checked acceptance checklist item must include an existing acceptance/ media reference

## Required Model Parameters

- file: `PARAMETER_MAP.json`
- URL: `/mika-avatar/handoff/mika-live2d/parameter-map.json`
- schema: `/mika-avatar/handoff/mika-live2d/parameter-map.schema.json`
- driver: `live2d-core-parameters`
- confirmedInRuntimeModel: `true`
- CSS overlay allowed: `false`
- CSS motion allowed: `false`
- mouth: `a=ParamA`, `i=ParamI`, `u=ParamU`, `e=ParamE`, `o=ParamO`, `amplitude=ParamMouthDown`
- motion: `ParamAngleX`, `ParamAngleY`, `ParamAngleZ`, `ParamBodyAngleX`, `ParamBodyAngleY`, `ParamBodyAngleZ`, `ParamAllX`, `ParamAllY`, `ParamAllRotate`, `ParamBreath`, `ParamLeftShoulderUp`, `ParamRightShoulderUp`, `ParamArmLA01`, `ParamArmLA02`, `ParamArmLA03`, `ParamArmRA01`, `ParamArmRA02`, `ParamArmRA03`, `ParamHandLA`, `ParamHandRA`, `ParamFingerL`, `ParamFingerR`, `ParamLegLA01`, `ParamLegLA02`, `ParamLegRA01`, `ParamLegRA02`, `ParamFootL`, `ParamFootR`, `ParamEyeLOpen`, `ParamEyeROpen`, `ParamEyeBallX`, `ParamEyeBallY`, `ParamEyeLSmile`, `ParamEyeRSmile`, `ParamCheek`, `ParamBrowLY`, `ParamBrowRY`, `ParamHairFront`, `ParamHairSideL`, `ParamHairSideR`, `ParamHairBack`, `ParamHairBackL`, `ParamHairBackR`, `ParamoHairMesh`, `ParamHairFrontFuwa`, `ParamHairSideFuwa`, `ParamHairBackFuwa`, `ParamSkirtFront`, `ParamSkirtSideL`, `ParamSkirtSideR`, `ParamSkirtFuwa`, `ParamSleeveL`, `ParamSleeveR`
- runtime parameter evidence rule: when confirmedInRuntimeModel=true, every mouth and motion parameter in PARAMETER_MAP.json must appear in runtime expression Parameters or motion Curves

## Parameter Driver Contract

- file: `PARAMETER_DRIVER_CONTRACT.json`
- URL: `/mika-avatar/handoff/mika-live2d/parameter-driver-contract.json`
- schema: `/mika-avatar/handoff/mika-live2d/parameter-driver-contract.schema.json`
- compatibility reference: `mao_pro`
- driver: `live2d-core-parameters`
- forbidden driver modes: `dom-mouth-overlay, css-mouth-overlay, css-motion-animation`
- evidence rule: Every listed parameter must be present in runtime expression Parameters[].Id or runtime motion Curves[].Id before PARAMETER_MAP.json confirmedInRuntimeModel can be true.

### Mouth Driver Targets

- `a` -> `runtime/expressions/a.exp3.json`; parameters: `ParamA`; amplitude: `ParamMouthDown`
- `i` -> `runtime/expressions/i.exp3.json`; parameters: `ParamI`; amplitude: `ParamMouthDown`
- `u` -> `runtime/expressions/u.exp3.json`; parameters: `ParamU`; amplitude: `ParamMouthDown`
- `e` -> `runtime/expressions/e.exp3.json`; parameters: `ParamE`; amplitude: `ParamMouthDown`
- `o` -> `runtime/expressions/o.exp3.json`; parameters: `ParamO`; amplitude: `ParamMouthDown`

## Expression State Contract

- file: `RIGGING_SPEC.json`
- field: `expressionStateTargets`
- driver mode: `cubism-expression`
- forbidden fallbacks: `css-overlay, dom-overlay, detached-png-layer`
- mouth amplitude parameter: `ParamMouthDown`
- release rule: Every required expression state must be declared in RIGGING_SPEC.json expressionStateTargets, mapped by EXPRESSION_MAP.json, declared by model3 Expressions, and backed by expression Parameters that drive Cubism model parts instead of detached overlays.
- mouth rule: Japanese vowel expressions a/i/u/e/o must drive ParamA/ParamI/ParamU/ParamE/ParamO plus ParamMouthDown so singing and lyric reading can vary mouth shape and amplitude like mao_pro.

- `a` (mouth-vowel) -> `runtime/expressions/a.exp3.json`; groups: `mouth`; parameters: `ParamA, ParamMouthDown`
- `i` (mouth-vowel) -> `runtime/expressions/i.exp3.json`; groups: `mouth`; parameters: `ParamI, ParamMouthDown`
- `u` (mouth-vowel) -> `runtime/expressions/u.exp3.json`; groups: `mouth`; parameters: `ParamU, ParamMouthDown`
- `e` (mouth-vowel) -> `runtime/expressions/e.exp3.json`; groups: `mouth`; parameters: `ParamE, ParamMouthDown`
- `o` (mouth-vowel) -> `runtime/expressions/o.exp3.json`; groups: `mouth`; parameters: `ParamO, ParamMouthDown`
- `blink` (face-expression) -> `runtime/expressions/blink.exp3.json`; groups: `eyes`; parameters: `ParamEyeLOpen, ParamEyeROpen`
- `smile` (face-expression) -> `runtime/expressions/smile.exp3.json`; groups: `face, eyes, mouth`; parameters: `ParamEyeLSmile, ParamEyeRSmile, ParamCheek, ParamA`
- `surprised` (face-expression) -> `runtime/expressions/surprised.exp3.json`; groups: `face, eyes, mouth`; parameters: `ParamBrowLY, ParamBrowRY, ParamEyeLOpen, ParamEyeROpen, ParamO`
- `thinking` (face-expression) -> `runtime/expressions/thinking.exp3.json`; groups: `face, eyes, body`; parameters: `ParamAngleX, ParamBodyAngleZ, ParamBrowLY, ParamBrowRY, ParamEyeBallX`

### Motion Driver Targets

- `idle` -> group `idle` / `runtime/motions/idle.motion3.json`; parameters: `ParamAngleX, ParamAngleY, ParamAngleZ, ParamBreath`; purpose: base breathing and gentle head motion when music is not driving a special cue
- `greeting` -> group `greeting` / `runtime/motions/greeting.motion3.json`; parameters: `ParamAngleX, ParamBodyAngleX, ParamBodyAngleY, ParamBodyAngleZ`; purpose: short greeting or tap response without replacing Mika identity
- `lyric-reading` -> group `lyric-reading` / `runtime/motions/lyric-reading.motion3.json`; parameters: `ParamAllX, ParamAllY, ParamAllRotate, ParamAngleX, ParamAngleY`; purpose: reading a selected lyric line while mouth parameters handle phonemes
- `point-lyrics` -> group `point-lyrics` / `runtime/motions/point-lyrics.motion3.json`; parameters: `ParamLeftShoulderUp, ParamRightShoulderUp, ParamArmLA01, ParamArmRA01`; purpose: gesture toward the current lyric area
- `rhythm-sway` -> group `rhythm-sway` / `runtime/motions/rhythm-sway.motion3.json`; parameters: `ParamBodyAngleX, ParamBodyAngleZ, ParamArmLA01, ParamArmLA02, ParamArmLA03, ParamHandLA, ParamHandRA, ParamLegLA01, ParamLegRA01, ParamFootL, ParamFootR, ParamSkirtFront, ParamSkirtFuwa, ParamSleeveL, ParamSleeveR`; purpose: song beat sway for tracks without bespoke choreography
- `chorus-gesture` -> group `chorus-gesture` / `runtime/motions/chorus-gesture.motion3.json`; parameters: `ParamBodyAngleY, ParamRightShoulderUp, ParamArmRA01, ParamArmRA02, ParamArmRA03, ParamHandRA, ParamFingerR`; purpose: larger chorus hand and upper-body accent
- `soft-dance-loop` -> group `soft-dance-loop` / `runtime/motions/soft-dance-loop.motion3.json`; parameters: `ParamAngleX, ParamAngleY, ParamAngleZ, ParamBodyAngleX, ParamBodyAngleY, ParamBodyAngleZ, ParamAllY, ParamAllRotate, ParamBreath, ParamLeftShoulderUp, ParamRightShoulderUp, ParamArmLA01, ParamArmLA02, ParamArmLA03, ParamArmRA01, ParamArmRA02, ParamArmRA03, ParamHandLA, ParamHandRA, ParamFingerL, ParamFingerR, ParamLegLA01, ParamLegLA02, ParamLegRA01, ParamLegRA02, ParamFootL, ParamFootR, ParamHairFront, ParamHairSideL, ParamHairSideR, ParamHairBack, ParamHairBackL, ParamHairBackR, ParamoHairMesh, ParamHairFrontFuwa, ParamHairSideFuwa, ParamHairBackFuwa, ParamEyeLSmile, ParamEyeRSmile, ParamEyeLOpen, ParamEyeROpen, ParamEyeBallX, ParamEyeBallY, ParamCheek, ParamBrowLY, ParamBrowRY, ParamSkirtFront, ParamSkirtSideL, ParamSkirtSideR, ParamSkirtFuwa, ParamSleeveL, ParamSleeveR`; purpose: smooth loop for Mika-only choreographed songs

## Motion State Contract

- file: `RIGGING_SPEC.json`
- field: `motionStateTargets`
- driver mode: `cubism-motion-parameter-curves`
- native motion policy: `non-interrupting-section-aware`
- forbidden fallbacks: `css-motion-animation, dom-transform-motion, detached-png-limb`
- maxParamAllYAbs: `0.08`
- maxRootScaleDelta: `0.0`
- forbidCssTransform: `true`
- noVerticalJitter: `true`
- release rule: Every required motion state must be declared in RIGGING_SPEC.json motionStateTargets, mapped by MOTION_MAP.json, declared by model3 Motions, and backed by motion3 Curves that drive Cubism model parameters without CSS or DOM fallback animation.
- interruption rule: Song-section motions must not be interrupted before minimumDurationSeconds except when switching to a higher-priority user action; gesture cooldownSeconds must be respected.

- `idle` -> `runtime/motions/idle.motion3.json`; group: `idle`; minimumDurationSeconds: `3.0`; cooldownSeconds: `0.0`; parameters: `ParamAngleX, ParamAngleY, ParamAngleZ, ParamBreath`
- `greeting` -> `runtime/motions/greeting.motion3.json`; group: `greeting`; minimumDurationSeconds: `1.2`; cooldownSeconds: `0.8`; parameters: `ParamAngleX, ParamBodyAngleX, ParamBodyAngleY, ParamBodyAngleZ`
- `lyric-reading` -> `runtime/motions/lyric-reading.motion3.json`; group: `lyric-reading`; minimumDurationSeconds: `1.0`; cooldownSeconds: `0.4`; parameters: `ParamAllX, ParamAllY, ParamAllRotate, ParamAngleX, ParamAngleY`
- `point-lyrics` -> `runtime/motions/point-lyrics.motion3.json`; group: `point-lyrics`; minimumDurationSeconds: `1.0`; cooldownSeconds: `0.8`; parameters: `ParamLeftShoulderUp, ParamRightShoulderUp, ParamArmLA01, ParamArmRA01`
- `rhythm-sway` -> `runtime/motions/rhythm-sway.motion3.json`; group: `rhythm-sway`; minimumDurationSeconds: `4.0`; cooldownSeconds: `0.0`; parameters: `ParamBodyAngleX, ParamBodyAngleZ, ParamArmLA01, ParamArmLA02, ParamArmLA03, ParamHandLA, ParamHandRA, ParamLegLA01, ParamLegRA01, ParamFootL, ParamFootR, ParamSkirtFront, ParamSkirtFuwa, ParamSleeveL, ParamSleeveR`
- `chorus-gesture` -> `runtime/motions/chorus-gesture.motion3.json`; group: `chorus-gesture`; minimumDurationSeconds: `2.0`; cooldownSeconds: `1.2`; parameters: `ParamBodyAngleY, ParamRightShoulderUp, ParamArmRA01, ParamArmRA02, ParamArmRA03, ParamHandRA, ParamFingerR`
- `soft-dance-loop` -> `runtime/motions/soft-dance-loop.motion3.json`; group: `soft-dance-loop`; minimumDurationSeconds: `8.0`; cooldownSeconds: `0.0`; parameters: `ParamAngleX, ParamAngleY, ParamAngleZ, ParamBodyAngleX, ParamBodyAngleY, ParamBodyAngleZ, ParamAllY, ParamAllRotate, ParamBreath, ParamLeftShoulderUp, ParamRightShoulderUp, ParamArmLA01, ParamArmLA02, ParamArmLA03, ParamArmRA01, ParamArmRA02, ParamArmRA03, ParamHandLA, ParamHandRA, ParamFingerL, ParamFingerR, ParamLegLA01, ParamLegLA02, ParamLegRA01, ParamLegRA02, ParamFootL, ParamFootR, ParamHairFront, ParamHairSideL, ParamHairSideR, ParamHairBack, ParamHairBackL, ParamHairBackR, ParamoHairMesh, ParamHairFrontFuwa, ParamHairSideFuwa, ParamHairBackFuwa, ParamEyeLSmile, ParamEyeRSmile, ParamEyeLOpen, ParamEyeROpen, ParamEyeBallX, ParamEyeBallY, ParamCheek, ParamBrowLY, ParamBrowRY, ParamSkirtFront, ParamSkirtSideL, ParamSkirtSideR, ParamSkirtFuwa, ParamSleeveL, ParamSleeveR`

### Pose Retarget Contract

- source video file: `source.mp4`
- skeleton input file: `pose_record.json`
- input schema file: `docs/schemas/mika-live2d-pose-record.schema.json`
- input schema URL: `/mika-avatar/handoff/mika-live2d/pose-record.schema.json`
- sample file: `pose_record.sample.json`
- retarget tool: `tools/live2d/pose_record_to_live2d_motion.py`
- output runtime file: `runtime/motions/soft-dance-loop.motion3.json`
- output format: `Cubism motion3.json parameter curves`
- dry-run report: `/mika-avatar/handoff/mika-live2d/pose-retarget-dry-run.json`
- dry-run report Markdown: `/mika-avatar/handoff/mika-live2d/pose-retarget-dry-run.md`
- sample motion3: `/mika-avatar/handoff/mika-live2d/soft-dance-loop.sample.motion3.json`
- sample motion note: Dry-run retarget artifact for production review; not a release-ready runtime motion until the rigged Mika model exists.
- point format: `[x, y, confidence] normalized to source video frame`
- source workflow: source.mp4 -> human skeleton timeline -> pose_record.json -> model-native Live2D parameters
- reference UI: Live2D Dancer style side-by-side source video, skeleton timeline, and full-body Live2D preview
- minimum FPS: `30`
- requires synchronized timeline: `true`
- requires full-body model: `true`
- required skeleton joints: `head`, `neck`, `shoulder_L`, `shoulder_R`, `elbow_L`, `elbow_R`, `wrist_L`, `wrist_R`, `hip_L`, `hip_R`, `knee_L`, `knee_R`, `ankle_L`, `ankle_R`
- required driven parameters: `ParamAngleX`, `ParamAngleY`, `ParamAngleZ`, `ParamBodyAngleX`, `ParamBodyAngleY`, `ParamBodyAngleZ`, `ParamAllX`, `ParamAllY`, `ParamAllRotate`, `ParamLeftShoulderUp`, `ParamRightShoulderUp`, `ParamArmLA01`, `ParamArmLA02`, `ParamArmLA03`, `ParamArmRA01`, `ParamArmRA02`, `ParamArmRA03`, `ParamHandLA`, `ParamHandRA`, `ParamFingerL`, `ParamFingerR`, `ParamLegLA01`, `ParamLegLA02`, `ParamLegRA01`, `ParamLegRA02`, `ParamFootL`, `ParamFootR`
- forbidden fallback: static PNG standee, CSS-only animation, or detached mouth/limb overlay
- acceptance rule: A recorded dance clip must visibly move head, body, shoulders, arms, and full-body pose in sync with the skeleton timeline without vertical jitter.

## Required License And Sources

- license file: `LICENSE.md`
- art sources file: `ART_SOURCES.md`
- attribution manifest file: `ATTRIBUTION_MANIFEST.json`
- grants: `commercialUse=可商用：yes`, `publicWebUse=可公開網站使用：yes`, `learnMoreUse=可用於 LearnMore：yes`, `sourceProof=來源或授權 URL，或明確標示內部原創/自製`
- art source fields: `角色立繪`, `分層源檔`, `貼圖`, `製作者`, `素材來源 URL 或內部原創聲明`
- required attribution locations: `mika-handoff, learnmore-site-notes`
- attribution visibility rule: attribution locations must be publicly visible on Mika handoff and LearnMore/site notes
- accepted source proof: `http://, https://, 內部原創, 自製, original`

## Validation Commands

```bash
python3 tools/live2d/inspect_mika_live2d_source_export.py deliveries/mika-live2d/source --no-fail
python3 tools/live2d/inspect_mika_live2d_runtime_export.py deliveries/mika-live2d/runtime --no-fail
python3 tools/live2d/validate_mika_live2d_pose_record.py deliveries/mika-live2d/pose_record.sample.json
python3 tools/live2d/pose_record_to_live2d_motion.py deliveries/mika-live2d/pose_record.sample.json --output reports/mika-live2d-soft-dance-loop.sample.motion3.json --report-output reports/mika-live2d-pose-retarget-dry-run.json --markdown-output reports/mika-live2d-pose-retarget-dry-run.md
python3 tools/live2d/validate_mika_live2d_delivery.py deliveries/mika-live2d
python3 tools/live2d/check_mika_live2d_delivery_readiness.py deliveries/mika-live2d --no-fail
```

## LearnMore Promotion Gate

- targetAvatarId: `mika_live2d`
- currentDefaultAvatarId: `mao_pro`
- fallbackAvatarId: `mao_pro`
- required true fields: `readyForLearnMore`, `deliveryReady`, `intakeReadyForApply`, `olvCustomLive2dReady`
- blocking fields: `blockingReasons`, `deliveryBlockingReasons`, `intakeBlockingReasons`, `olvCustomLive2dBlockingReasons`, `remainingProductionQueueIds`
- switch only when: `readyForLearnMore=true and deliveryReady=true and intakeReadyForApply=true and olvCustomLive2dReady=true`

## Post-Delivery Intake

1. Extract the returned Mika Live2D delivery into deliveries/mika-live2d.
2. Run the source export preflight against deliveries/mika-live2d/source before full intake.
3. Run the runtime export preflight against deliveries/mika-live2d/runtime before full intake.
4. Run delivery validation and readiness checks.
5. Copy approved runtime files into live2d-models/mika_live2d/runtime.
6. Register mika_live2d in model_dict.json only after runtime files pass validation.
7. Run full core verification and LearnMore acceptance before changing LearnMore default.

```bash
python3 tools/live2d/inspect_mika_live2d_source_export.py deliveries/mika-live2d/source
python3 tools/live2d/inspect_mika_live2d_runtime_export.py deliveries/mika-live2d/runtime
python3 tools/live2d/validate_mika_live2d_delivery.py deliveries/mika-live2d
python3 tools/live2d/check_mika_live2d_delivery_readiness.py deliveries/mika-live2d --no-fail
python3 tools/live2d/intake_mika_live2d_delivery.py deliveries/mika-live2d --no-fail
python3 tools/live2d/intake_mika_live2d_delivery.py deliveries/mika-live2d --apply
python3 tools/vrm/test_mika_live2d_status.py
bash scripts/verify_mika_avatar_core.sh
```

## Notice

Do not promote mika_live2d or switch LearnMore away from mao_pro until readyForLearnMore, deliveryReady, intakeReadyForApply, and olvCustomLive2dReady are all true.

mika_formal_2d is a static preview and cannot be promoted to mika_live2d without layered art, Cubism rigging, runtime export, license notes, and LearnMore acceptance.
