motionloom 2.0.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (112) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +179 -0
  3. package/SKILL.md +122 -0
  4. package/agent-card.json +161 -0
  5. package/assets/library/ATTRIBUTION.md +6 -0
  6. package/assets/library/README.md +20 -0
  7. package/assets/library/avatar-base.svg +19 -0
  8. package/assets/library/error-alert.json +1 -0
  9. package/assets/library/rive/ATTRIBUTION.md +12 -0
  10. package/assets/library/rive/state-machine-test.riv +0 -0
  11. package/assets/library/success-check.json +1 -0
  12. package/bin/motionloom.mjs +81 -0
  13. package/docs/BROWSER-REVIEW-E2E.md +78 -0
  14. package/docs/CATEGORIES.md +16 -0
  15. package/docs/CHECKLIST.md +31 -0
  16. package/docs/DEEP-AUDIT-WORKING-NOTES.md +22 -0
  17. package/docs/FRAMEWORK-SELECTION.md +26 -0
  18. package/docs/PROJECT-MANIFEST.md +37 -0
  19. package/docs/ROADMAP-INTELLIGENCE.md +224 -0
  20. package/docs/audits/1.10.0-attestation-research-notes.md +19 -0
  21. package/docs/audits/1.8.0-trust-boundary-hardening.md +56 -0
  22. package/docs/audits/1.9.0-evidence-interoperability-threat-model.md +37 -0
  23. package/docs/audits/2.0.0-attestation-acceptance.md +30 -0
  24. package/docs/releases/1.5.0.md +25 -0
  25. package/docs/releases/1.6.0.md +27 -0
  26. package/docs/releases/1.7.0.md +23 -0
  27. package/docs/releases/1.8.0.md +23 -0
  28. package/docs/releases/1.9.0.md +21 -0
  29. package/docs/releases/2.0.0.md +21 -0
  30. package/docs/releases/npm-publish-from-workstation.md +88 -0
  31. package/docs/research/AGENT-PROTOCOL-FINDINGS.md +43 -0
  32. package/examples/report-demo/REPORT.md +50 -0
  33. package/examples/report-demo/artifact-manifest.json +25 -0
  34. package/examples/report-demo/decision-log.jsonl +0 -0
  35. package/examples/report-demo/execution-report.json +70 -0
  36. package/examples/report-demo/handoff.json +22 -0
  37. package/examples/report-demo/issue-register.json +5 -0
  38. package/examples/report-demo/task.json +13 -0
  39. package/package.json +95 -0
  40. package/project-context.example.json +26 -0
  41. package/references/browser-review-contract.md +32 -0
  42. package/references/dotlottie-source-notes.md +21 -0
  43. package/references/intelligence-core.md +98 -0
  44. package/references/reporting-contract.md +38 -0
  45. package/references/runtime-capability.md +12 -0
  46. package/references/signed-attestation.md +31 -0
  47. package/schemas/artifact-manifest.schema.json +22 -0
  48. package/schemas/browser-review-candidate.schema.json +24 -0
  49. package/schemas/capability-registry.schema.json +61 -0
  50. package/schemas/continuity-report.schema.json +52 -0
  51. package/schemas/evidence-verifier-report.schema.json +35 -0
  52. package/schemas/execution-report.schema.json +35 -0
  53. package/schemas/fix-plan.schema.json +44 -0
  54. package/schemas/handoff.schema.json +19 -0
  55. package/schemas/motion-ir.schema.json +74 -0
  56. package/schemas/project-graph.schema.json +70 -0
  57. package/schemas/provenance.schema.json +76 -0
  58. package/schemas/runtime-evidence.schema.json +48 -0
  59. package/schemas/runtime-telemetry.schema.json +50 -0
  60. package/schemas/scene-manifest.schema.json +45 -0
  61. package/schemas/semantic-benchmark.schema.json +26 -0
  62. package/schemas/semantic-lint-report.schema.json +48 -0
  63. package/schemas/signed-attestation.schema.json +95 -0
  64. package/schemas/task.schema.json +39 -0
  65. package/schemas/trust-policy.schema.json +53 -0
  66. package/scripts/analyze.sh +13 -0
  67. package/scripts/attestation-keygen.py +63 -0
  68. package/scripts/attestation-verifier.py +178 -0
  69. package/scripts/attestation.py +288 -0
  70. package/scripts/capture-runtime-telemetry.sh +37 -0
  71. package/scripts/devlab.sh +77 -0
  72. package/scripts/eval-intelligence.py +377 -0
  73. package/scripts/evidence-verifier.py +222 -0
  74. package/scripts/fetch-library.sh +57 -0
  75. package/scripts/intelligence.py +1543 -0
  76. package/scripts/manifest.py +61 -0
  77. package/scripts/pr.sh +103 -0
  78. package/scripts/quality-gate.py +378 -0
  79. package/scripts/render-node.mjs +53 -0
  80. package/scripts/render.sh +37 -0
  81. package/scripts/report-contract.py +181 -0
  82. package/scripts/report.py +588 -0
  83. package/scripts/review-hook.py +199 -0
  84. package/scripts/runtime-adapters.mjs +187 -0
  85. package/scripts/skill-doctor.py +150 -0
  86. package/scripts/to-dotlottie.mjs +99 -0
  87. package/scripts/to-dotlottie.sh +25 -0
  88. package/scripts/validate-lottie.py +102 -0
  89. package/src/core/analyzer.py +226 -0
  90. package/src/core/snapshot.py +124 -0
  91. package/src/core/spec.py +240 -0
  92. package/src/output/browser-review-smoke/animation.json +57 -0
  93. package/src/output/browser-review-smoke/browser-review.json +21 -0
  94. package/src/output/browser-review-smoke/manifest.json +22 -0
  95. package/src/output/browser-review-smoke/motion-spec.json +28 -0
  96. package/src/output/browser-review-smoke/snapshot/.render-meta.json +10 -0
  97. package/src/output/browser-review-smoke/snapshot/frame-00.png +0 -0
  98. package/src/output/browser-review-smoke/snapshot/frame-100.png +0 -0
  99. package/src/output/browser-review-smoke/snapshot/frame-50.png +0 -0
  100. package/src/rig/README.md +35 -0
  101. package/src/rig/cutout_rig.py +211 -0
  102. package/templates/framer-motion/ui-micro.tsx +50 -0
  103. package/templates/gsap/scroll-scene.js +54 -0
  104. package/templates/lottie/README.md +21 -0
  105. package/templates/lottie/react-component.tsx +82 -0
  106. package/templates/lottie/scaffold/animation.json +57 -0
  107. package/templates/lottie/scaffold/character-rig.svg +19 -0
  108. package/templates/lottie/vanilla.js +68 -0
  109. package/templates/rive/README.md +36 -0
  110. package/tests/evals/intelligence-cases.json +131 -0
  111. package/tests/scripts/run_tests.py +843 -0
  112. package/tests/scripts/test_attestation.py +172 -0
package/LICENSE ADDED
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2026 Len Hon BP
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ SOFTWARE.
package/README.md ADDED
@@ -0,0 +1,179 @@
1
+ # MotionLoom
2
+
3
+ A coding-agent skill for professional animation development: motion, character body rigs and assets. It does not guess — it **understands the host project, plans from a signed motion spec, generates from vetted source assets, renders everything in the Dev Lab for live testing, and only then confirms into a pull request**.
4
+
5
+ ## Install from npm
6
+
7
+ MotionLoom is distributed as the `motionloom` npm package. The package ships the installable Skill contract, framework adapters, Intelligence Core schemas, evidence verifiers and a small CLI wrapper around the canonical Python scripts.
8
+
9
+ ```bash
10
+ npm install --global motionloom
11
+ motionloom doctor
12
+ motionloom --help
13
+ ```
14
+
15
+ The CLI requires **Node.js 18+** and **Python 3.11+**. Installation does not grant approval, commit changes or open a pull request; browser review and explicit repository-side-effect confirmation remain mandatory.
16
+
17
+ ## Quick start
18
+
19
+ ```bash
20
+ # 1. Understand the project
21
+ bash scripts/analyze.sh /path/to/your/project
22
+
23
+ # 1b. Start a transparent task ledger for Agent/human handoff
24
+ python3 scripts/report.py init --task-id onboarding-wave \
25
+ --scene my-scene --intent "Character wave in onboarding" \
26
+ --project-name your-project
27
+
28
+ # 2. Plan & sign a spec (example: a loading animation)
29
+ python3 src/core/spec.py generate loading --context /path/to/your/project/project-context.json \
30
+ --output motion-spec.json --loop
31
+
32
+ # 3. Generate a body rig, then pose it
33
+ python3 src/rig/cutout_rig.py build \
34
+ --input assets/library/avatar-base.svg --output rigged.svg
35
+ python3 src/rig/cutout_rig.py pose rigged.svg --pose walk \
36
+ --duration 1.2 --fps 30 --out walk.json
37
+
38
+ # 3b. Bind the scene source to an authoritative provenance record
39
+ python3 scripts/manifest.py bind-source --scene my-scene \
40
+ --source animation.json --kind project \
41
+ --authority "host project manifest" --license MIT
42
+
43
+ # 4. Render runtime verification snapshots (0/50/100%; placeholders fail)
44
+ bash scripts/render.sh my-scene
45
+
46
+ # 4b. Package the Lottie source as a dotLottie v2 archive when required
47
+ bash scripts/to-dotlottie.sh my-scene
48
+
49
+ # 4c. Verify Rive, GSAP and Framer Motion through the real browser harness
50
+ node scripts/runtime-adapters.mjs
51
+
52
+ # 4d. Capture runtime telemetry and verify evidence bindings externally
53
+ bash scripts/capture-runtime-telemetry.sh my-scene artifacts/onboarding-wave
54
+
55
+ # 4e. Derive and verify a signed task-bound statement against a managed trust policy
56
+ python3 scripts/attestation.py statement --scene-dir src/output/my-scene \
57
+ --task-dir artifacts/onboarding-wave --context /path/to/your/project/project-context.json \
58
+ --output artifacts/onboarding-wave/attestation-statement.json
59
+ python3 scripts/attestation.py build --statement artifacts/onboarding-wave/attestation-statement.json \
60
+ --private-key <managed-ed25519-key> --key-id <key-id> \
61
+ --output artifacts/onboarding-wave/attestation.json
62
+ python3 scripts/attestation-verifier.py --attestation artifacts/onboarding-wave/attestation.json \
63
+ --trust-policy artifacts/onboarding-wave/trust-policy.json \
64
+ --expected-task-id onboarding-wave --expected-scene my-scene
65
+
66
+ # 5. Boot the Dev Lab to test & fix interactively
67
+ bash scripts/devlab.sh my-scene
68
+
69
+ # 6. Run the acceptance gate, then confirm and ship
70
+ python3 scripts/quality-gate.py --scene my-scene \
71
+ --context /path/to/your/project/project-context.json \
72
+ --task-dir artifacts/onboarding-wave --require-telemetry --require-attestation
73
+
74
+ # 6. Collect evidence and render the user-facing report
75
+ python3 scripts/report.py collect --task-dir artifacts/onboarding-wave
76
+ python3 scripts/report.py render --task-dir artifacts/onboarding-wave
77
+
78
+ # 7. Confirm and ship only after review
79
+ bash scripts/pr.sh my-scene
80
+ ```
81
+
82
+ The kit is intended to run from a Git clone. Copy `project-context.example.json` only as a schema reference; always generate the real context with `scripts/analyze.sh` against the host project. Do not commit a context containing a temporary path or another project's brand tokens.
83
+
84
+ For a reproducible review fixture, keep `project-context.json`, `quality-report.json`, `review.json`, `execution-report.json`, `handoff.json` and `artifact-manifest.json` under the repository's `artifacts/<task-id>/` directory. `scripts/pr.sh` rejects task bundles outside the repository, requires the task scene to match the requested scene, runs the semantic report check, and stages the evidence bundle together with the scene. This prevents a gate from consuming evidence that is omitted from the resulting commit.
85
+
86
+ Runtime adapter evidence can be bound to a scene and its exact source/manifest bytes:
87
+
88
+ ```bash
89
+ RUNTIME_SCENE=my-scene \
90
+ RUNTIME_SOURCE_PATH=src/output/my-scene/animation.json \
91
+ RUNTIME_MANIFEST_PATH=src/output/my-scene/manifest.json \
92
+ node scripts/runtime-adapters.mjs
93
+ ```
94
+
95
+ When these variables are supplied, `runtime-evidence.json` records `scene`, `source_sha256` and `manifest_sha256`; the quality gate rejects evidence copied from another scene or generated against an older manifest.
96
+
97
+ ### Intelligence Core v0.1 + P1 feedback intelligence + trust-boundary hardening + evidence interoperability + signed attestation
98
+
99
+ After render and before strict acceptance, build the task-bound Intelligence Core artifacts. They give an Agent a single relationship graph, step-level provenance, framework-neutral Motion IR, capability selection policy and deterministic replay inventory instead of requiring it to infer relationships from prose and unrelated files:
100
+
101
+ ```bash
102
+ python3 scripts/intelligence.py motion-ir build --task-dir artifacts/onboarding-wave
103
+ python3 scripts/intelligence.py graph build --task-dir artifacts/onboarding-wave
104
+ python3 scripts/intelligence.py provenance build --task-dir artifacts/onboarding-wave
105
+ python3 scripts/intelligence.py replay capture --root . --task-dir artifacts/onboarding-wave
106
+ python3 scripts/intelligence.py semantic-lint build --task-dir artifacts/onboarding-wave
107
+ python3 scripts/intelligence.py semantic-lint benchmark --task-dir artifacts/onboarding-wave \
108
+ --iterations 25 --threshold-ms 500
109
+ bash scripts/capture-runtime-telemetry.sh my-scene artifacts/onboarding-wave
110
+ python3 scripts/intelligence.py continuity build --task-dirs artifacts/onboarding-wave
111
+ python3 scripts/intelligence.py fix-plan build --task-dir artifacts/onboarding-wave \
112
+ --reports semantic-lint-report.json continuity-report.json
113
+ python3 scripts/quality-gate.py --scene my-scene \
114
+ --context /path/to/your/project/project-context.json \
115
+ --task-dir artifacts/onboarding-wave \
116
+ --require-browser-review --require-intelligence --require-p1 --require-benchmark --require-telemetry --require-attestation
117
+ python3 scripts/eval-intelligence.py
118
+ ```
119
+
120
+ Semantic lint reports intent, timing, easing, accessibility and performance findings with severity, confidence and evidence. The benchmark records rule coverage and p95 execution time against a 500 ms default threshold; it does not claim to measure human visual quality. Continuity analysis checks context and transition drift across an ordered scene set. `fix-plan.json` converts findings into root cause, affected artifacts, selective rerun scope and verification commands; it does not auto-approve a scene. The 1.8.0 hardening layer rejects symlinked or cross-task Intelligence artifacts, binds replay to task identity, chooses one deterministic passing report bundle per scene, and makes the Dev Lab reject cross-origin or mismatched task/candidate evidence. The 1.9.0 evidence layer captures scrub-point, RAF timing, runtime-state and source/manifest/Motion IR hash bindings, then lets a read-only external verifier reject stale, tampered, cross-task or path-escaped evidence. The 2.0.0 attestation layer signs canonical task-bound hashes with a DSSE-compatible Ed25519 envelope and checks signer lifecycle through fail-closed trust policy. A verifier pass still means integrity only: runtime assertions, Dev Lab review and user consent remain mandatory; `approval` is always `false`. See [Intelligence Core](references/intelligence-core.md), [signed attestation reference](references/signed-attestation.md), the [1.9.0 threat model](docs/audits/1.9.0-evidence-interoperability-threat-model.md) and the [2.0.0 release note](docs/releases/2.0.0.md).
121
+
122
+ ## Pipeline
123
+
124
+ | Step | Module | What it does |
125
+ |------|--------|--------------|
126
+ | 01 · Understand | `src/core/analyzer.py` | Reads package.json, design tokens and existing motion language; emits `project-context.json` inside the target project |
127
+ | 02 · Plan | `src/core/spec.py` | Generates & validates the motion spec against the framework matrix, easing canon and performance budget |
128
+ | 03 · Source | `assets/library/` | Vetted, traceable source assets with an attribution table — the authoritative geometry |
129
+ | 04 · Generate | `src/rig/cutout_rig.py`, `templates/` | Canonical templates per framework; 20-bone cutout body rigs with parent-first order |
130
+ | 05 · Dev Lab | `dev-lab/` | Self-contained static workbench: preview rendered evidence, scrub, quality checklist, fix notes, review export |
131
+ | 06 · Confirm → PR | `scripts/pr.sh` | Commits scene + spec + snapshots, opens the PR with an evidence body |
132
+
133
+ ## Repository layout
134
+
135
+ | Path | Purpose |
136
+ |------|---------|
137
+ | `SKILL.md` | The agent-skill definition (installable into any coding agent) |
138
+ | `src/core/` | Analyzer, spec validator, snapshot renderer |
139
+ | `src/rig/` | Cutout character body rig engine |
140
+ | `templates/` | Canonical Lottie / Rive / GSAP / Framer Motion templates |
141
+ | `assets/library/` | Vetted source assets + attribution, including the MIT Rive adapter fixture |
142
+ | `scripts/` | Pipeline CLI plus Intelligence Core (`analyze`, `render`, `devlab`, `pr`, `quality-gate`, `validate-lottie`, `to-dotlottie`, `runtime-adapters`, `capture-runtime-telemetry`, `evidence-verifier`, `attestation`, `attestation-verifier`, `attestation-keygen`, `skill-doctor`, `report`, `report-contract`, `intelligence`, `eval-intelligence`) |
143
+ | `dev-lab/` | Self-contained static Dev Lab + Playwright snapshot harness |
144
+ | `agent-card.json` | Capability discovery, runtime levels and side-effect policy for other Agents |
145
+ | `schemas/` | Task, report, artifact-manifest, scene-manifest, handoff, Intelligence Core, signed-attestation and trust-policy JSON Schemas |
146
+ | `references/` | Progressive-disclosure contracts for reporting, runtime capability, dotLottie packaging and Intelligence Core |
147
+ | `artifacts/<task-id>/` | Per-task ledger, evidence, review, issue register and handoff bundle |
148
+ | `tests/` | Deterministic engine tests |
149
+ | `.github/workflows/quality.yml` | CI that re-runs the quality gate on every PR |
150
+
151
+ ## The quality gate
152
+
153
+ A scene is only "ready" when, together, the Dev Lab checklist passes, runtime snapshot frames exist at 0/50/100%, the context-bound JSON spec matches the implementation, brand tokens come from the target project's `project-context.json`, the required `source_binding` traces `manifest.file` to an authoritative source with a matching checksum, the P1 reports have been validated and the semantic-lint benchmark is below threshold. For strict observability runs, runtime telemetry and the external verifier report must also pass their identity, freshness and hash checks; for production trust runs, the signed attestation must verify against an active trust-policy key and bind the same task/scene/material hashes. A warning or valid signature may require human review and a selective fix; neither is silently converted into approval. CI reproduces these checks on every PR — see [CHECKLIST.md](docs/CHECKLIST.md).
154
+
155
+ ## Transparent task reporting
156
+
157
+ The Skill does not end with a prose claim that an animation is complete. Each task can be represented by `artifacts/<task-id>/`, which records the lifecycle state, decisions, changed artifacts, checksums, quality result, review decision, open problems and the next Agent handoff. Generate the report with `python3 scripts/report.py render --task-dir artifacts/<task-id>`.
158
+
159
+ The report must distinguish **completed**, **verified**, **not completed**, **blocked/failed**, **structure problems** and **recommended next Agent/Skill**. A scaffold-only runtime must be reported as `scaffold`; it cannot be described as `runtime-verified` until its adapter test has produced evidence.
160
+
161
+ Run `python3 scripts/skill-doctor.py --json` when changing the Skill package. It checks the frontmatter, required directories, schemas, Agent Card and references. CI also requires a task report/handoff bundle for changed scenes, so a future Agent cannot silently modify a scene without leaving a reviewable trail.
162
+
163
+ ## Agent interoperability and public skills
164
+
165
+ `agent-card.json` is the discovery surface. It declares inputs, outputs, verified versus scaffold-only runtimes and Git side effects. Use official or public skills as focused references and adapters rather than copying their prompts into this repository: [LottieFiles dotLottie Web](https://github.com/LottieFiles/dotlottie-web/blob/main/SKILL.md) for runtime APIs, [Diffusion Studio text-to-lottie](https://github.com/diffusionstudio/lottie) for optional scene scaffolding, [Claude Lottie Skill](https://github.com/b1rdmania/claude-lottie-skill/blob/main/SKILL.md) for optional brand-aware asset discovery, and the [Agent Skills specification](https://agentskills.io/specification) plus [GitHub Agent Skills documentation](https://docs.github.com/en/copilot/concepts/agents/about-agent-skills) for packaging and portability.
166
+
167
+ The project-specific value remains in context binding, Motion Spec, asset provenance, runtime evidence, quality policy, review memory and handoff artifacts. The runtime adapter harness delegates rendering to the official packages; it does not reimplement Lottie/Rive runtimes, MCP transport or GitHub authentication inside this Skill.
168
+
169
+ ### Important trust boundary
170
+
171
+ `ALLOW_PLACEHOLDER=1 bash scripts/render.sh <scene>` is diagnostic only. It creates visibly marked placeholder frames and the quality gate rejects them. A PR cannot be confirmed until the official runtime or the Dev Lab browser renderer has produced `snapshot/.render-meta.json` with `mode: runtime`.
172
+
173
+ ## Standards basis
174
+
175
+ The audit and templates are grounded in first-party references: [LottieFiles runtimes](https://docs.lottiefiles.com/en/runtimes), the [dotLottie v2 specification](https://dotlottie.io/spec/2.0/), [Rive Web runtime](https://rive.app/docs/runtimes/web/web-js), [Rive state machines](https://rive.app/docs/runtimes/state-machines), and [GSAP accessibility guidance](https://gsap.com/resources/a11y/). End-to-end adapter evidence currently covers **Lottie JSON, dotLottie packaging, SVG cutout rigs, Rive, GSAP and Framer Motion**. Spine and Three.js remain scaffold-only until framework-specific runtime adapters are implemented.
176
+
177
+ ## License
178
+
179
+ MIT
package/SKILL.md ADDED
@@ -0,0 +1,122 @@
1
+ ---
2
+ name: motionloom
3
+ description: >-
4
+ Project-aware animation production and verification for UI motion, Lottie/dotLottie,
5
+ Rive, GSAP, Framer Motion, character body rigs, scene assets, runtime rendering,
6
+ Dev Lab browser review, and confirm-to-PR workflows. Use when an Agent must create, fix,
7
+ validate, review, or deliver animation inside an existing project.
8
+ license: MIT
9
+ metadata:
10
+ version: "2.0.0"
11
+ target_frameworks: "lottie,dotlottie,rive,gsap,framer-motion,spine,threejs"
12
+ verified_runtimes: "lottie-json,dotlottie-package,svg-cutout-rig,rive,gsap,framer-motion"
13
+ ---
14
+
15
+ # MotionLoom Skill
16
+
17
+ Treat every animation request as a production task, not as an isolated asset-generation prompt. Always bind the work to the host project's context, emit machine-readable artifacts, render through the target runtime, expose review evidence in Dev Lab, and stop before commit when a required gate or user confirmation is missing.
18
+
19
+ ## Required workflow
20
+
21
+ 1. **Understand** — read the host project manifest and run `bash scripts/analyze.sh <project-path>`. Load `project-context.json` from the audited project. If context is missing or ambiguous, stop at `needs_context`.
22
+ 2. **Plan** — classify the animation, select a framework, and generate a context-bound `motion-spec.json` with timing, easing, loop, accessibility, performance and source authority.
23
+ 3. **Source** — resolve an authoritative asset from the project or `assets/library/`. Record attribution, license and checksum in the scene manifest's required `source_binding`; the binding's SHA-256 must match the bytes referenced by `manifest.file`. Do not promote an unknown or placeholder asset to production.
24
+ 4. **Generate** — use the matching template or rig implementation. For body animation, preserve named anatomy, pivot and parent-first hierarchy.
25
+ 5. **Render** — run `bash scripts/render.sh <scene>` for scene output, or `node scripts/runtime-adapters.mjs` for the verified Rive/GSAP/Framer Motion adapter matrix. Acceptance requires runtime evidence at 0/50/100%, not a static placeholder. Keep the render metadata beside the snapshots.
26
+ 6. **Bind Intelligence Core** — build a framework-neutral `motion-ir.json`, `project-graph.json`, `provenance.json`, `replay-bundle.json`, `semantic-lint-report.json` and `semantic-lint-benchmark.json` with `python3 scripts/intelligence.py`. Select only a capability registry entry whose status is `verified`, whose evidence is fresh and whose compatibility matches the target environment. A confidence score or benchmark result can prioritize investigation; neither can replace deterministic or human acceptance.
27
+ 6a. **Harden the trust boundary** — keep artifact and task bundles inside the repository/task root, reject symlinked evidence, bind replay to its exact `task_dir`, `task_id` and scene, select one deterministic report bundle per scene, and require browser candidate/review identity and expiry checks before readiness. The Dev Lab must reject cross-origin or identity-mismatched artifact bases. In strict runtime-observability runs, capture `runtime-telemetry.json` and a read-only `evidence-verifier-report.json`; verifier output must preserve `approval: false`. These checks expose risk and prevent evidence mixing, but do not turn heuristics or evidence integrity into approval.
28
+ 6b. **Attest** — derive a canonical statement from the exact scene/task hashes, sign it with an Ed25519 key through `scripts/attestation.py`, and verify it with the independent `scripts/attestation-verifier.py` against a fail-closed `trust-policy.json`. DSSE/SLSA-compatible attestation proves signer and binding integrity only; `approval` must remain `false` and never replaces user review.
29
+ 7. **Browser review handoff** — run `python3 scripts/review-hook.py prepare --task-dir artifacts/<task-id> --lab-url <internal-lab-url>`. The hook prepares the exact candidate and emits a JSON action for a browser-capable Agent. Trigger or suggest that Agent to open the emitted URL, inspect frames 0/50/100, scrub the timeline and ask the user to review. This is not a separate Dev Lab Skill; it is a required post-render handoff.
30
+ 8. **Review capture** — the browser Agent calls `window.__lab.getReview()` after the user approves or requests changes, then persists it with `python3 scripts/report.py review --task-dir artifacts/<task-id> --candidate-id <id> --decision approved|changes_requested --reviewer user`. A change request returns to generation; no approval means no PR.
31
+ 9. **Validate** — run `python3 scripts/review-hook.py validate --task-dir artifacts/<task-id>`, `python3 scripts/intelligence.py semantic-lint benchmark --task-dir artifacts/<task-id> --iterations 25 --threshold-ms 500`, `bash scripts/capture-runtime-telemetry.sh <scene> artifacts/<task-id>`, the independent attestation verifier, `python3 scripts/report-contract.py --root . --scenes-file <changed-scenes> --require-attestation`, `python3 scripts/quality-gate.py --scene <scene> --context <context-path> --task-dir artifacts/<task-id> --require-intelligence --require-p1 --require-benchmark --require-telemetry --require-attestation`, and `python3 scripts/skill-doctor.py --json` when validating the Skill package itself.
32
+ 10. **Report** — create or update an artifact bundle with `python3 scripts/report.py`. Record facts with `report.py add`, structural defects with `report.py structure`, collect checksums with `report.py collect`, and run `report.py check` before rendering the final report. The final report must state completed, verified, not completed, blocked/failed, structure problems, browser candidate/review evidence and the recommended next Agent/Skill.
33
+ 11. **Confirm** — only after approved browser review and a passing quality gate run `TASK_DIR=artifacts/<task-id> bash scripts/pr.sh <scene>`. Commit, push and open PR are explicit side effects.
34
+
35
+ ## Progressive disclosure
36
+
37
+ - Read `references/reporting-contract.md` when creating task, execution, issue or handoff artifacts.
38
+ - Read `references/runtime-capability.md` before claiming a framework is production-verified.
39
+ - Read `docs/FRAMEWORK-SELECTION.md` and `docs/CATEGORIES.md` when selecting a runtime.
40
+ - Read `docs/CHECKLIST.md` before marking a scene ready for review.
41
+ - Read `src/rig/README.md` for character body hierarchy and pose rules.
42
+ - Read `references/dotlottie-source-notes.md` when packaging or validating `.lottie` archives.
43
+ - Read `docs/ROADMAP-INTELLIGENCE.md` before extending graph, provenance, capability or replay behavior.
44
+ - Read `references/intelligence-core.md` before building or validating Intelligence Core artifacts.
45
+ - Read `docs/research/AGENT-PROTOCOL-FINDINGS.md` before exposing MotionLoom through Agent tools or MCP resources.
46
+
47
+ ## Non-negotiable contracts
48
+
49
+ - Every task has a lifecycle state: `created`, `needs_context`, `planning`, `sourcing`, `generating`, `rendering`, `review_required`, `blocked`, `failed`, `validated`, `ready_for_pr`, or `confirmed`.
50
+ - Every production scene has context, motion spec, manifest, source binding, runtime metadata, 0/50/100 snapshots, browser-review candidate, checklist result and review artifact.
51
+ - `scaffold` and `static-validated` are not equivalent to `runtime-verified` or `project-integrated`.
52
+ - Never hide a missing dependency, failed render, missing license, context drift, incomplete review or unimplemented framework behind a successful prose response.
53
+ - Use JSON output and stable exit codes for Agent-to-Agent composition; do not require another Agent to parse chat text. The external evidence verifier is read-only and must never emit an approval decision.
54
+ - Destructive Git actions require explicit confirmation. Use `OPEN_PR=0` for local review-only runs.
55
+ - Intelligence Core artifacts are task-bound: graph, provenance, Motion IR and replay evidence must not be reused across tasks without revalidation.
56
+ - Provenance hashes materials and products; replay must fail on tampered or missing files; stale capability evidence must not be selected for production acceptance.
57
+ - Browser-review candidates are single-use, time-bounded and bound to the exact task, scene and candidate identity; Dev Lab artifact/task bases must be same-origin and identity-consistent before staging a review decision.
58
+ - Report completeness must select one deterministic passing task bundle per scene and fail on ambiguous ties; a valid artifact is never sufficient to bypass explicit user approval.
59
+ - Runtime telemetry must bind task, scene, source, manifest, Motion IR and deterministic scrub points; tampered, stale, missing or cross-task telemetry is a verification failure.
60
+ - Signed attestation must bind the same task, scene, context, source, manifest, Motion IR and evidence hashes; unknown, expired or revoked signers fail closed. Attestation verification is an integrity result only and must preserve `approval: false`.
61
+
62
+ ## Framework boundary
63
+
64
+ The audited production paths are **Lottie JSON runtime rendering, dotLottie v2 packaging, SVG cutout rigging, Rive Canvas, GSAP and Framer Motion**. Their evidence is generated by `node scripts/runtime-adapters.mjs` and includes deterministic scrub points, runtime state and PNG snapshots. Spine and Three.js remain scaffold/selection paths until their adapter-specific runtime tests pass and their capability level is upgraded in `agent-card.json`.
65
+
66
+ ## Provenance and runtime commands
67
+
68
+ Every production `src/output/<scene>/manifest.json` must include a `source_binding` object matching `schemas/scene-manifest.schema.json`. The acceptance gate rejects a missing binding, a mismatched source path, an unknown license/authority or a stale SHA-256.
69
+
70
+ The Intelligence Core contracts are defined in `schemas/project-graph.schema.json`, `schemas/provenance.schema.json`, `schemas/capability-registry.schema.json`, `schemas/motion-ir.schema.json`, `schemas/signed-attestation.schema.json` and `schemas/trust-policy.schema.json`. They make project relationships, supply-chain steps, runtime selection, framework-neutral intent and signer trust inspectable without relying on prose.
71
+
72
+ ```bash
73
+ # Package a Lottie JSON scene as a dotLottie v2 archive.
74
+ bash scripts/to-dotlottie.sh <scene> [output.lottie]
75
+
76
+ # Run the official runtime adapters in a real browser harness.
77
+ node scripts/runtime-adapters.mjs
78
+
79
+ # Build the task-bound Intelligence Core artifacts.
80
+ python3 scripts/intelligence.py motion-ir build --task-dir artifacts/<task-id>
81
+ python3 scripts/intelligence.py graph build --task-dir artifacts/<task-id>
82
+ python3 scripts/intelligence.py provenance build --task-dir artifacts/<task-id>
83
+ python3 scripts/intelligence.py replay capture --task-dir artifacts/<task-id>
84
+
85
+ # Derive, sign and independently verify the exact task-bound attestation.
86
+ python3 scripts/attestation.py statement --scene-dir src/output/<scene> \
87
+ --task-dir artifacts/<task-id> --context <project-context.json> \
88
+ --output artifacts/<task-id>/attestation-statement.json
89
+ python3 scripts/attestation.py build --statement artifacts/<task-id>/attestation-statement.json \
90
+ --private-key <managed-key-file> --key-id <key-id> \
91
+ --output artifacts/<task-id>/attestation.json
92
+ python3 scripts/attestation-verifier.py --attestation artifacts/<task-id>/attestation.json \
93
+ --trust-policy artifacts/<task-id>/trust-policy.json \
94
+ --expected-task-id <task-id> --expected-scene <scene>
95
+ ```
96
+
97
+ `runtime-evidence.json` records the runtime package, three scrub points, observed state and generated snapshots. A template alone is never enough to upgrade a framework from `scaffold_only` to `verified`.
98
+
99
+ For an observability-enabled run, `bash scripts/capture-runtime-telemetry.sh <scene> artifacts/<task-id>` regenerates the real-browser evidence and writes telemetry under the task bundle. `scripts/evidence-verifier.py` then checks task/scene/hash/path/age bindings with stable machine-readable output. A verifier pass means the evidence is internally consistent; it does not mean the animation is approved.
100
+
101
+ ## Output contract
102
+
103
+ Create `artifacts/<task-id>/` for cross-Agent handoff. A minimal invocation is:
104
+
105
+ ```bash
106
+ python3 scripts/report.py init --task-id <task-id> --scene <scene> \
107
+ --intent "<intent>" --output artifacts/<task-id>
108
+ python3 scripts/report.py add --task-dir artifacts/<task-id> \
109
+ --section completed --id context --summary "Project analyzed" \
110
+ --status pass --evidence project-context.json
111
+ python3 scripts/report.py structure --task-dir artifacts/<task-id> \
112
+ --missing-file <path> --broken-reference <path>
113
+ python3 scripts/report.py collect --task-dir artifacts/<task-id>
114
+ python3 scripts/review-hook.py prepare --task-dir artifacts/<task-id> --lab-url http://127.0.0.1:3300
115
+ # Browser Agent opens the emitted URL; user reviews; then persist the browser payload:
116
+ python3 scripts/report.py review --task-dir artifacts/<task-id> \
117
+ --candidate-id <candidate-id> --decision approved --reviewer user
118
+ python3 scripts/report.py check --task-dir artifacts/<task-id>
119
+ python3 scripts/report.py render --task-dir artifacts/<task-id>
120
+ ```
121
+
122
+ The bundle should contain `task.json`, `execution-report.json`, `decision-log.jsonl`, `artifact-manifest.json`, `quality-report.json`, `issue-register.json`, `review.json` and `handoff.json` as applicable. Telemetry-enabled bundles additionally expose `runtime-adapters/runtime-evidence.json`, `runtime-adapters/runtime-telemetry.json` and `evidence-verifier-report.json`; strict trust bundles also expose `attestation.json`, `trust-policy.json` and `attestation-verifier-report.json`. Reports must never convert “not run” into “passed”: an absent runtime or attestation artifact is a `not_completed` item or a blocker, while an invalid path belongs in `structure_review`. A valid signature remains distinct from user approval.
@@ -0,0 +1,161 @@
1
+ {
2
+ "card_version": "1.0",
3
+ "name": "motionloom",
4
+ "version": "2.0.0",
5
+ "description": "Project-aware animation production with graph, provenance, framework-neutral motion IR, runtime verification and telemetry, DSSE-compatible signed attestation, external evidence verification, semantic feedback, continuity checks, internal browser review, trust-boundary hardening and deterministic Agent handoff.",
6
+ "capabilities": [
7
+ "project.analyze",
8
+ "project.graph.build",
9
+ "project.graph.validate",
10
+ "motion.plan",
11
+ "motion.ir.build",
12
+ "motion.ir.validate",
13
+ "asset.provenance",
14
+ "provenance.emit",
15
+ "provenance.verify",
16
+ "capability.discover",
17
+ "capability.select",
18
+ "replay.capture",
19
+ "replay.verify",
20
+ "semantic-lint.build",
21
+ "semantic-lint.validate",
22
+ "semantic-lint.benchmark",
23
+ "trust-boundary.audit",
24
+ "continuity.build",
25
+ "continuity.validate",
26
+ "fix-plan.build",
27
+ "fix-plan.validate",
28
+ "feedback.sync",
29
+ "source-binding.validate",
30
+ "rig.cutout",
31
+ "runtime.render.lottie",
32
+ "runtime.package.dotlottie",
33
+ "runtime.verify.rive",
34
+ "runtime.verify.gsap",
35
+ "runtime.verify.framer-motion",
36
+ "runtime.telemetry.capture",
37
+ "runtime.telemetry.validate",
38
+ "evidence.verify.external",
39
+ "attestation.statement.build",
40
+ "attestation.sign.ed25519",
41
+ "attestation.verify.external",
42
+ "trust-policy.validate",
43
+ "devlab.review",
44
+ "browser.review.prepare",
45
+ "browser.review.trigger",
46
+ "browser.review.capture",
47
+ "quality.gate",
48
+ "report.generate",
49
+ "handoff.prepare",
50
+ "pr.prepare"
51
+ ],
52
+ "input_artifacts": [
53
+ "host-project",
54
+ "project-manifest",
55
+ "animation-request",
56
+ "source-asset"
57
+ ],
58
+ "output_artifacts": [
59
+ "project-context",
60
+ "motion-spec",
61
+ "runtime-scene",
62
+ "source-binding",
63
+ "dotlottie-package",
64
+ "runtime-evidence",
65
+ "runtime-telemetry",
66
+ "evidence-verifier-report",
67
+ "signed-attestation",
68
+ "trust-policy",
69
+ "attestation-verifier-report",
70
+ "evidence-bundle",
71
+ "execution-report",
72
+ "handoff",
73
+ "browser-review-candidate",
74
+ "browser-review",
75
+ "project-graph",
76
+ "provenance-attestation",
77
+ "capability-registry",
78
+ "motion-ir",
79
+ "replay-bundle",
80
+ "semantic-lint-report",
81
+ "semantic-lint-benchmark",
82
+ "hardening-audit-report",
83
+ "continuity-report",
84
+ "fix-plan",
85
+ "pr-patch"
86
+ ],
87
+ "runtime_capabilities": {
88
+ "verified": ["lottie-json", "dotlottie-package", "svg-cutout-rig", "rive", "gsap", "framer-motion"],
89
+ "scaffold_only": ["spine", "threejs"]
90
+ },
91
+ "side_effects": {
92
+ "read_files": "allowed",
93
+ "write_files": "allowed",
94
+ "network": "optional-and-declared",
95
+ "git_commit": "explicit-confirmation",
96
+ "git_push": "explicit-confirmation",
97
+ "open_pull_request": "explicit-confirmation"
98
+ ,"open_internal_browser": "trigger-or-suggest-after-render; user-review-required"
99
+ },
100
+ "recommended_integrations": [
101
+ {
102
+ "id": "dotlottie-web-skill",
103
+ "url": "https://github.com/LottieFiles/dotlottie-web/blob/main/SKILL.md",
104
+ "role": "official-runtime-reference",
105
+ "trust": "official",
106
+ "use_for": ["dotLottie runtime API", "worker rendering", "state machines", "slots"],
107
+ "not_for": ["project planning", "provenance", "PR acceptance"]
108
+ },
109
+ {
110
+ "id": "text-to-lottie",
111
+ "url": "https://github.com/diffusionstudio/lottie",
112
+ "role": "optional-scaffold",
113
+ "trust": "community-open-source",
114
+ "use_for": ["scene setup", "live preview patterns", "prompt conventions"],
115
+ "not_for": ["runtime truth", "context binding"]
116
+ },
117
+ {
118
+ "id": "animation-design",
119
+ "url": "https://github.com/b1rdmania/claude-lottie-skill/blob/main/SKILL.md",
120
+ "role": "optional-asset-discovery",
121
+ "trust": "community-open-source",
122
+ "use_for": ["brand-aware Lottie/Rive search", "series coherence"],
123
+ "not_for": ["license authority", "runtime verification"]
124
+ }
125
+ ],
126
+ "entrypoints": {
127
+ "analyze": "bash scripts/analyze.sh <project-path>",
128
+ "report_init": "python3 scripts/report.py init --task-id <id>",
129
+ "report_collect": "python3 scripts/report.py collect --task-dir <dir>",
130
+ "report_render": "python3 scripts/report.py render --task-dir <dir>",
131
+ "skill_doctor": "python3 scripts/skill-doctor.py --json",
132
+ "quality_gate": "python3 scripts/quality-gate.py --scene <scene> --context <path>",
133
+ "manifest_bind_source": "python3 scripts/manifest.py bind-source --scene <scene> --source <file> --kind <kind> --authority <authority> --license <license>",
134
+ "dotlottie_package": "bash scripts/to-dotlottie.sh <scene> [output.lottie]",
135
+ "runtime_adapter_test": "node scripts/runtime-adapters.mjs",
136
+ "runtime_telemetry": "bash scripts/capture-runtime-telemetry.sh <scene> artifacts/<task-id>",
137
+ "evidence_verify": "python3 scripts/evidence-verifier.py --scene-dir src/output/<scene> --task-dir artifacts/<task-id> --runtime-evidence runtime-adapters/runtime-evidence.json --max-age-days 1 --output artifacts/<task-id>/evidence-verifier-report.json",
138
+ "intelligence_graph": "python3 scripts/intelligence.py graph build --task-dir artifacts/<task-id>",
139
+ "intelligence_provenance": "python3 scripts/intelligence.py provenance build --task-dir artifacts/<task-id>",
140
+ "intelligence_capabilities": "python3 scripts/intelligence.py capabilities build --output capability-registry.json",
141
+ "intelligence_motion_ir": "python3 scripts/intelligence.py motion-ir build --task-dir artifacts/<task-id>",
142
+ "intelligence_replay": "python3 scripts/intelligence.py replay capture --task-dir artifacts/<task-id>",
143
+ "semantic_lint": "python3 scripts/intelligence.py semantic-lint build --task-dir artifacts/<task-id>",
144
+ "semantic_lint_benchmark": "python3 scripts/intelligence.py semantic-lint benchmark --task-dir artifacts/<task-id> --iterations 25 --threshold-ms 500",
145
+ "continuity": "python3 scripts/intelligence.py continuity build --task-dirs artifacts/<task-id>...",
146
+ "fix_plan": "python3 scripts/intelligence.py fix-plan build --task-dir artifacts/<task-id> --reports semantic-lint-report.json continuity-report.json",
147
+ "quality_gate_p1": "python3 scripts/quality-gate.py --scene <scene> --context <path> --task-dir artifacts/<task-id> --require-browser-review --require-intelligence --require-p1 --require-benchmark --require-telemetry",
148
+ "attestation_statement": "python3 scripts/attestation.py statement --scene-dir src/output/<scene> --task-dir artifacts/<task-id> --context <project-context.json> --output artifacts/<task-id>/attestation-statement.json",
149
+ "attestation_build": "python3 scripts/attestation.py build --statement artifacts/<task-id>/attestation-statement.json --private-key <key> --key-id <key-id> --output artifacts/<task-id>/attestation.json",
150
+ "attestation_verify": "python3 scripts/attestation-verifier.py --attestation artifacts/<task-id>/attestation.json --trust-policy artifacts/<task-id>/trust-policy.json --expected-task-id <task-id> --expected-scene <scene>",
151
+ "attestation_report": "python3 scripts/attestation-verifier.py --attestation artifacts/<task-id>/attestation.json --trust-policy artifacts/<task-id>/trust-policy.json --expected-task-id <task-id> --expected-scene <scene> --output artifacts/<task-id>/attestation-verifier-report.json",
152
+ "quality_gate_attestation": "python3 scripts/quality-gate.py --scene <scene> --context <path> --task-dir artifacts/<task-id> --require-browser-review --require-intelligence --require-p1 --require-benchmark --require-telemetry --require-attestation",
153
+ "browser_review_prepare": "python3 scripts/review-hook.py prepare --task-dir artifacts/<task-id> --lab-url <internal-lab-url>",
154
+ "browser_review_validate": "python3 scripts/review-hook.py validate --task-dir artifacts/<task-id>",
155
+ "pr_prepare": "bash scripts/pr.sh <scene>"
156
+ },
157
+ "report_contract": {
158
+ "required_sections": ["completed", "verified", "not_completed", "problems", "structure_review", "next_agent", "browser_review"],
159
+ "artifact_root": "artifacts/<task-id>/"
160
+ }
161
+ }
@@ -0,0 +1,6 @@
1
+ # Asset Library Attribution
2
+
3
+ | Asset | Source | License | Downloaded |
4
+ |---|---|---|---|
5
+ | `success-check.json` | https://lottiefiles.com/free-animation/success-check | LottieFiles Free (check per-asset license page) | v=4.8.0 fr=60 op=240 layers=95 |
6
+ | `error-alert.json` | https://lottiefiles.com/free-animation/error-alert | LottieFiles Free (check per-asset license page) | v=5.5.6 fr=60 op=300 layers=3 |
@@ -0,0 +1,20 @@
1
+ # Asset Library — Authoritative Sources
2
+
3
+ This directory holds the **vetted, traceable source assets** the generator must bind to. The golden rule: when an authoritative source exists here (or in the host project), never invent geometry from memory. Placeholders created by the rig engine or templates are clearly marked and must be replaced before a scene ships.
4
+
5
+ ## Contents
6
+
7
+ | Item | Purpose |
8
+ |---|---|
9
+ | `success-check.json` | Reference Lottie success state — 60 fps, 240 frames, 95 layers (use as a complexity benchmark) |
10
+ | `error-alert.json` | Reference Lottie error state — 60 fps, 300 frames, minimal layer count |
11
+ | `avatar-base.svg` | Authoritative cutout avatar base for body rigging (`src/rig/cutout_rig.py --input`) |
12
+ | `ATTRIBUTION.md` | Auto-generated provenance table: every fetched asset with source URL + license |
13
+
14
+ ## Adding assets
15
+
16
+ Use `scripts/fetch-library.sh` — it downloads from official public sources, validates the Bodymovin header (version, fps, frame count, layer count), and appends a row to `ATTRIBUTION.md`. Always open the license page of each asset before shipping it in a commercial product; LottieFiles free assets carry individual license terms.
17
+
18
+ ## Naming convention
19
+
20
+ `<category>-<variant>.<ext>` — e.g. `loading-dots.json`, `character-walk.svg`. Category must match a taxonomy entry in `docs/CATEGORIES.md`.
@@ -0,0 +1,19 @@
1
+ <svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 500 450">
2
+ <!-- Authoritative cutout avatar base. Part names map 1:1 to bones in
3
+ src/rig/cutout_rig.py (head, chest, arms, legs, feet). Replace with
4
+ owned/licensed character art before shipping. -->
5
+ <g id="parts">
6
+ <circle data-part="head" cx="250" cy="90" r="42" fill="#2d2d3a"/>
7
+ <rect data-part="chest" x="208" y="140" width="84" height="96" rx="22" fill="#2d2d3a"/>
8
+ <rect data-part="l_upper_arm" x="178" y="148" width="26" height="78" rx="13" fill="#45455a"/>
9
+ <rect data-part="r_upper_arm" x="296" y="148" width="26" height="78" rx="13" fill="#45455a"/>
10
+ <rect data-part="l_forearm" x="176" y="228" width="22" height="70" rx="11" fill="#45455a"/>
11
+ <rect data-part="r_forearm" x="302" y="228" width="22" height="70" rx="11" fill="#45455a"/>
12
+ <rect data-part="l_thigh" x="216" y="238" width="30" height="84" rx="15" fill="#37374a"/>
13
+ <rect data-part="r_thigh" x="254" y="238" width="30" height="84" rx="15" fill="#37374a"/>
14
+ <rect data-part="l_shin" x="218" y="324" width="26" height="80" rx="13" fill="#37374a"/>
15
+ <rect data-part="r_shin" x="256" y="324" width="26" height="80" rx="13" fill="#37374a"/>
16
+ <ellipse data-part="l_foot" cx="231" cy="408" rx="24" ry="10" fill="#1f1f2e"/>
17
+ <ellipse data-part="r_foot" cx="269" cy="408" rx="24" ry="10" fill="#1f1f2e"/>
18
+ </g>
19
+ </svg>