motionloom 2.6.1 → 2.7.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 (69) hide show
  1. package/AGENTS.md +2 -2
  2. package/CHANGELOG.md +42 -0
  3. package/CONTRIBUTING.md +3 -1
  4. package/README.md +19 -3
  5. package/SECURITY.md +5 -5
  6. package/SKILL.md +6 -3
  7. package/agent-card.json +18 -4
  8. package/agent-surfaces.json +1 -1
  9. package/artifact-adapter-registry.json +568 -20
  10. package/bin/motionloom.mjs +21 -4
  11. package/capability-registry.json +58 -234
  12. package/dev-lab/public/devlab.js +36 -3
  13. package/dev-lab/public/index.html +6 -2
  14. package/docs/ACTION-SEPARATION.md +104 -0
  15. package/docs/ASSET-GENERATION-PLANNER.md +101 -0
  16. package/docs/BRANCH-PROTECTION.md +44 -0
  17. package/docs/EXTERNAL-CORPUS.md +26 -0
  18. package/docs/STATUS.md +3 -2
  19. package/docs/audits/field-test-after-hardening-2026-08-21.md +25 -0
  20. package/docs/releases/2.7.0.md +98 -0
  21. package/examples/agent-consumer/asset-consistency/action-sequence/envelopes/walk.00.json +32 -0
  22. package/examples/agent-consumer/asset-consistency/action-sequence/envelopes/walk.01.json +32 -0
  23. package/examples/agent-consumer/asset-consistency/action-sequence/envelopes/walk.02.json +32 -0
  24. package/examples/agent-consumer/asset-consistency/action-sequence/envelopes/walk.03.json +32 -0
  25. package/examples/agent-consumer/asset-consistency/action-sequence/hero-walk-action-manifest.json +81 -0
  26. package/examples/agent-consumer/asset-consistency/action-sequence/verifier-evidence/walk.00.json +26 -0
  27. package/examples/agent-consumer/asset-consistency/action-sequence/verifier-evidence/walk.01.json +26 -0
  28. package/examples/agent-consumer/asset-consistency/action-sequence/verifier-evidence/walk.02.json +26 -0
  29. package/examples/agent-consumer/asset-consistency/action-sequence/verifier-evidence/walk.03.json +26 -0
  30. package/examples/agent-consumer/asset-planning/pixellab-hero-256x448-request.json +43 -0
  31. package/examples/agent-consumer/devlab-live-sprite/README.md +30 -0
  32. package/examples/agent-consumer/devlab-live-sprite/devlab-runtime.json +61 -0
  33. package/examples/agent-consumer/devlab-live-sprite/frames/idle-00.png +0 -0
  34. package/examples/agent-consumer/devlab-live-sprite/frames/idle-01.png +0 -0
  35. package/examples/agent-consumer/devlab-live-sprite/frames/idle-02.png +0 -0
  36. package/examples/agent-consumer/devlab-live-sprite/frames/reverse-00.png +0 -0
  37. package/examples/agent-consumer/devlab-live-sprite/frames/reverse-01.png +0 -0
  38. package/examples/agent-consumer/devlab-live-sprite/frames/reverse-02.png +0 -0
  39. package/examples/agent-consumer/frame-generation-lock/hero-walk-lock.json +14 -1
  40. package/package.json +15 -1
  41. package/references/multi-frame-asset-generation.md +37 -2
  42. package/schemas/action-separation-verifier-evidence.schema.json +43 -0
  43. package/schemas/action-sequence-manifest.schema.json +48 -0
  44. package/schemas/artifact-adapter-registry.schema.json +1 -1
  45. package/schemas/asset-adaptation.schema.json +21 -0
  46. package/schemas/asset-generation-plan.schema.json +77 -0
  47. package/schemas/asset-generation-request.schema.json +104 -0
  48. package/schemas/frame-envelope.schema.json +62 -0
  49. package/schemas/frame-generation-lock.schema.json +24 -1
  50. package/scripts/action-separation.py +410 -0
  51. package/scripts/asset-adapt.mjs +92 -0
  52. package/scripts/asset-generation-plan.py +613 -0
  53. package/scripts/browser_review_consistency.py +64 -0
  54. package/scripts/fetch-project-corpus.py +91 -0
  55. package/scripts/frame-generation-lock.py +35 -5
  56. package/scripts/frame-set-preflight.py +52 -2
  57. package/scripts/package-consumer-smoke.mjs +20 -0
  58. package/scripts/quality-gate.py +7 -0
  59. package/scripts/release-verify.py +25 -0
  60. package/scripts/report-contract.py +1 -1
  61. package/scripts/report.py +19 -4
  62. package/scripts/resolve-task-bundle.py +11 -3
  63. package/scripts/review-hook.py +51 -2
  64. package/scripts/skill-doctor.py +42 -0
  65. package/src/output/browser-review-smoke/browser-review.json +6 -6
  66. package/tests/scripts/run_tests.py +45 -2
  67. package/tests/scripts/test_asset_adapt.py +47 -0
  68. package/tests/scripts/test_asset_generation_plan.py +250 -0
  69. package/tests/scripts/test_attestation.py +24 -8
@@ -1,8 +1,11 @@
1
1
  {
2
2
  "schema_version": "0.1",
3
3
  "registry_id": "motionloom-artifact-adapters",
4
- "generated_at": "2026-08-15T00:00:00Z",
5
- "selection_policy": {"require_verified": true, "allow_scaffold_only": false},
4
+ "generated_at": "2026-08-22T00:00:00Z",
5
+ "selection_policy": {
6
+ "require_verified": true,
7
+ "allow_scaffold_only": false
8
+ },
6
9
  "adapters": [
7
10
  {
8
11
  "adapter_id": "fixture.local-artifact-intake",
@@ -11,13 +14,489 @@
11
14
  "adapter_version": "0.1",
12
15
  "invocation_mode": "none",
13
16
  "cost_class": "included",
14
- "inputs": ["hash-bound-fixture", "control-track"],
15
- "outputs": ["generation-receipt", "export-manifest"],
16
- "compatibility": {"os": ["linux", "macos", "windows"]},
17
- "evidence": [{"path": "docs/research/agent-skill-ecosystem-notes.md", "sha256": "18472ccd959191a4e769675b142076fa3c0103629d67b5be992fa524730cc530", "kind": "static"}],
18
- "limitations": ["Fixture adapter is regression evidence only and never generates an asset."],
17
+ "inputs": [
18
+ "hash-bound-fixture",
19
+ "control-track"
20
+ ],
21
+ "outputs": [
22
+ "generation-receipt",
23
+ "export-manifest",
24
+ "frame_sequence"
25
+ ],
26
+ "compatibility": {
27
+ "os": [
28
+ "linux",
29
+ "macos",
30
+ "windows"
31
+ ]
32
+ },
33
+ "capabilities": {
34
+ "canvas": {
35
+ "max_width": 8192,
36
+ "max_height": 8192,
37
+ "shapes": [
38
+ "square",
39
+ "portrait",
40
+ "landscape"
41
+ ]
42
+ },
43
+ "frame_behavior": {
44
+ "mode": "single_frame",
45
+ "single_frame": true,
46
+ "max_frames_per_request": 1
47
+ },
48
+ "adaptation": [
49
+ "pad_to_target",
50
+ "integer_upscale"
51
+ ]
52
+ },
53
+ "evidence": [
54
+ {
55
+ "path": "docs/research/agent-skill-ecosystem-notes.md",
56
+ "sha256": "18472ccd959191a4e769675b142076fa3c0103629d67b5be992fa524730cc530",
57
+ "kind": "static"
58
+ }
59
+ ],
60
+ "limitations": [
61
+ "Fixture adapter is regression evidence only and never generates an asset."
62
+ ],
19
63
  "risk_level": "low",
20
- "side_effect_level": "read"
64
+ "side_effect_level": "read",
65
+ "availability": {
66
+ "status": "available",
67
+ "environment": "repository fixture",
68
+ "reason": "static regression fixture is present in the repository"
69
+ }
70
+ },
71
+ {
72
+ "adapter_id": "manual.import-frame-sequence",
73
+ "kind": "manual_import",
74
+ "status": "static_validated",
75
+ "adapter_version": "0.1",
76
+ "invocation_mode": "manual",
77
+ "cost_class": "external",
78
+ "inputs": [
79
+ "user-provided-images",
80
+ "reference-images",
81
+ "control-track"
82
+ ],
83
+ "outputs": [
84
+ "image",
85
+ "frame_sequence",
86
+ "generation-receipt",
87
+ "export-manifest"
88
+ ],
89
+ "compatibility": {
90
+ "os": [
91
+ "linux",
92
+ "macos",
93
+ "windows"
94
+ ]
95
+ },
96
+ "capabilities": {
97
+ "canvas": {
98
+ "max_width": 16384,
99
+ "max_height": 16384,
100
+ "shapes": [
101
+ "square",
102
+ "portrait",
103
+ "landscape"
104
+ ]
105
+ },
106
+ "frame_behavior": {
107
+ "mode": "single_frame",
108
+ "single_frame": true,
109
+ "max_frames_per_request": 1
110
+ },
111
+ "adaptation": [
112
+ "pad_to_target",
113
+ "integer_upscale"
114
+ ]
115
+ },
116
+ "evidence": [
117
+ {
118
+ "path": "docs/research/ai-animation-tools-2026-report.md",
119
+ "sha256": "f1050dd77ecffd8ad4ff87cb66f7bb147998bd2743862f57606890a0305a1e37",
120
+ "kind": "static"
121
+ }
122
+ ],
123
+ "limitations": [
124
+ "This adapter does not generate or authenticate provider output; it imports user-managed bytes and remains review_required."
125
+ ],
126
+ "risk_level": "medium",
127
+ "side_effect_level": "user_review_required",
128
+ "availability": {
129
+ "status": "known",
130
+ "environment": "user-managed",
131
+ "reason": "route is known to MotionLoom but requires user-provided frame files"
132
+ }
133
+ },
134
+ {
135
+ "adapter_id": "pixellab.animate-skeleton",
136
+ "kind": "external_provider",
137
+ "status": "scaffold_only",
138
+ "adapter_version": "0.1",
139
+ "invocation_mode": "api",
140
+ "cost_class": "external",
141
+ "inputs": [
142
+ "reference-images",
143
+ "skeleton-poses",
144
+ "control-track",
145
+ "action-cues"
146
+ ],
147
+ "outputs": [
148
+ "frame_sequence",
149
+ "generation-receipt"
150
+ ],
151
+ "compatibility": {
152
+ "os": [
153
+ "linux",
154
+ "macos",
155
+ "windows"
156
+ ]
157
+ },
158
+ "capabilities": {
159
+ "official_docs": [
160
+ "https://api.pixellab.ai/v2/docs",
161
+ "https://www.pixellab.ai/docs/tools/animate-with-skeleton"
162
+ ],
163
+ "canvas": {
164
+ "shapes": [
165
+ "square"
166
+ ],
167
+ "allowed_sizes": [
168
+ [
169
+ 16,
170
+ 16
171
+ ],
172
+ [
173
+ 32,
174
+ 32
175
+ ],
176
+ [
177
+ 64,
178
+ 64
179
+ ],
180
+ [
181
+ 128,
182
+ 128
183
+ ],
184
+ [
185
+ 256,
186
+ 256
187
+ ]
188
+ ],
189
+ "max_width": 256,
190
+ "max_height": 256
191
+ },
192
+ "frame_behavior": {
193
+ "mode": "batch_animation",
194
+ "single_frame": false,
195
+ "max_frames_per_request": 4,
196
+ "frame_count_policy": "fixed"
197
+ },
198
+ "adaptation": [
199
+ "pad_to_target",
200
+ "integer_upscale"
201
+ ]
202
+ },
203
+ "evidence": [
204
+ {
205
+ "path": "docs/research/ai-animation-tools-2026-report.md",
206
+ "sha256": "f1050dd77ecffd8ad4ff87cb66f7bb147998bd2743862f57606890a0305a1e37",
207
+ "kind": "static"
208
+ }
209
+ ],
210
+ "limitations": [
211
+ "PixelLab skeleton animation is square-canvas and batch-oriented; a non-square target such as 256x448 requires explicit transparent padding and independent post-export envelopes.",
212
+ "The adapter is metadata-only and does not call PixelLab, store Bearer tokens or prove a provider-native job receipt.",
213
+ "A batch animation is not equivalent to required per-frame isolated generation."
214
+ ],
215
+ "risk_level": "medium",
216
+ "side_effect_level": "remote_write",
217
+ "availability": {
218
+ "status": "unknown",
219
+ "environment": "external API/extension",
220
+ "reason": "API key, subscription and provider connectivity are not asserted by the registry"
221
+ }
222
+ },
223
+ {
224
+ "adapter_id": "pixellab.create-animated-object-character",
225
+ "kind": "external_provider",
226
+ "status": "scaffold_only",
227
+ "adapter_version": "0.1",
228
+ "invocation_mode": "api",
229
+ "cost_class": "external",
230
+ "inputs": [
231
+ "text-description",
232
+ "action-cues",
233
+ "control-track"
234
+ ],
235
+ "outputs": [
236
+ "frame_sequence",
237
+ "generation-receipt"
238
+ ],
239
+ "compatibility": {
240
+ "os": [
241
+ "linux",
242
+ "macos",
243
+ "windows"
244
+ ]
245
+ },
246
+ "capabilities": {
247
+ "official_docs": [
248
+ "https://api.pixellab.ai/v2/docs",
249
+ "https://www.pixellab.ai/docs/tools/text2animation"
250
+ ],
251
+ "canvas": {
252
+ "shapes": [
253
+ "square"
254
+ ],
255
+ "allowed_sizes": [
256
+ [
257
+ 32,
258
+ 32
259
+ ],
260
+ [
261
+ 64,
262
+ 64
263
+ ],
264
+ [
265
+ 128,
266
+ 128
267
+ ],
268
+ [
269
+ 256,
270
+ 256
271
+ ]
272
+ ],
273
+ "max_width": 256,
274
+ "max_height": 256
275
+ },
276
+ "frame_behavior": {
277
+ "mode": "batch_animation",
278
+ "single_frame": false,
279
+ "frame_count_policy": "depends_on_canvas_size",
280
+ "limits_by_canvas": [
281
+ {
282
+ "canvas": [
283
+ 32,
284
+ 32
285
+ ],
286
+ "max_frames_per_request": 16
287
+ },
288
+ {
289
+ "canvas": [
290
+ 64,
291
+ 64
292
+ ],
293
+ "max_frames_per_request": 16
294
+ },
295
+ {
296
+ "canvas": [
297
+ 128,
298
+ 128
299
+ ],
300
+ "max_frames_per_request": 4
301
+ },
302
+ {
303
+ "canvas": [
304
+ 256,
305
+ 256
306
+ ],
307
+ "max_frames_per_request": 4
308
+ }
309
+ ]
310
+ },
311
+ "adaptation": [
312
+ "pad_to_target",
313
+ "integer_upscale"
314
+ ]
315
+ },
316
+ "evidence": [
317
+ {
318
+ "path": "docs/research/ai-animation-tools-2026-report.md",
319
+ "sha256": "f1050dd77ecffd8ad4ff87cb66f7bb147998bd2743862f57606890a0305a1e37",
320
+ "kind": "static"
321
+ }
322
+ ],
323
+ "limitations": [
324
+ "This route creates a new animated object or character from text and an action; it is not the existing-reference Animate with text route.",
325
+ "The documented tool supports square 32x32, 64x64, 128x128 and 256x256 canvas sizes with frame output depending on canvas-size tier; non-square targets require explicit adaptation.",
326
+ "The adapter is metadata-only and does not invoke PixelLab, store Bearer tokens or prove provider-native task metadata.",
327
+ "Batch output must not silently satisfy a per-frame isolation requirement."
328
+ ],
329
+ "risk_level": "medium",
330
+ "side_effect_level": "remote_write",
331
+ "availability": {
332
+ "status": "unknown",
333
+ "environment": "external API/extension",
334
+ "reason": "API key, subscription and provider connectivity are not asserted by the registry"
335
+ }
336
+ },
337
+ {
338
+ "adapter_id": "pixellab.animate-with-text",
339
+ "kind": "external_provider",
340
+ "status": "scaffold_only",
341
+ "adapter_version": "0.1",
342
+ "invocation_mode": "api",
343
+ "cost_class": "external",
344
+ "inputs": [
345
+ "reference-images",
346
+ "action-cues",
347
+ "control-track"
348
+ ],
349
+ "outputs": [
350
+ "frame_sequence",
351
+ "generation-receipt"
352
+ ],
353
+ "compatibility": {
354
+ "os": [
355
+ "linux",
356
+ "macos",
357
+ "windows"
358
+ ]
359
+ },
360
+ "availability": {
361
+ "status": "unknown",
362
+ "environment": "external API/extension",
363
+ "reason": "API key, subscription and provider connectivity are not asserted by the registry"
364
+ },
365
+ "capabilities": {
366
+ "official_docs": [
367
+ "https://api.pixellab.ai/v2/docs",
368
+ "https://www.pixellab.ai/docs/tools/animation"
369
+ ],
370
+ "canvas": {
371
+ "shapes": [
372
+ "square"
373
+ ],
374
+ "allowed_sizes": [
375
+ [
376
+ 32,
377
+ 32
378
+ ],
379
+ [
380
+ 64,
381
+ 64
382
+ ],
383
+ [
384
+ 128,
385
+ 128
386
+ ]
387
+ ],
388
+ "max_width": 128,
389
+ "max_height": 128
390
+ },
391
+ "frame_behavior": {
392
+ "mode": "batch_animation",
393
+ "single_frame": false,
394
+ "max_frames_per_request": 4,
395
+ "frame_count_policy": "fixed"
396
+ },
397
+ "adaptation": [
398
+ "pad_to_target",
399
+ "integer_upscale"
400
+ ]
401
+ },
402
+ "evidence": [
403
+ {
404
+ "path": "docs/research/ai-animation-tools-2026-report.md",
405
+ "sha256": "f1050dd77ecffd8ad4ff87cb66f7bb147998bd2743862f57606890a0305a1e37",
406
+ "kind": "static"
407
+ }
408
+ ],
409
+ "limitations": [
410
+ "This route animates an existing reference image with text/action instructions; it is distinct from Create animated object/character.",
411
+ "The official route generates four animation frames or conditioned frames in its documented workflows; target canvas and provider export details still require a verified receipt before execution.",
412
+ "The adapter is metadata-only and does not invoke PixelLab, store Bearer tokens or prove provider-native task metadata.",
413
+ "Batch output must not silently satisfy a per-frame isolation requirement."
414
+ ],
415
+ "risk_level": "medium",
416
+ "side_effect_level": "remote_write"
417
+ },
418
+ {
419
+ "adapter_id": "pixellab.animation-to-animation",
420
+ "kind": "external_provider",
421
+ "status": "scaffold_only",
422
+ "adapter_version": "0.1",
423
+ "invocation_mode": "api",
424
+ "cost_class": "external",
425
+ "inputs": [
426
+ "reference-images",
427
+ "animation-reference",
428
+ "action-cues",
429
+ "control-track"
430
+ ],
431
+ "outputs": [
432
+ "frame_sequence",
433
+ "generation-receipt"
434
+ ],
435
+ "compatibility": {
436
+ "os": [
437
+ "linux",
438
+ "macos",
439
+ "windows"
440
+ ]
441
+ },
442
+ "capabilities": {
443
+ "official_docs": [
444
+ "https://api.pixellab.ai/v2/docs",
445
+ "https://www.pixellab.ai/docs/tools/animation-to-animation"
446
+ ],
447
+ "canvas": {
448
+ "shapes": [
449
+ "square"
450
+ ],
451
+ "allowed_sizes": [
452
+ [
453
+ 16,
454
+ 16
455
+ ],
456
+ [
457
+ 32,
458
+ 32
459
+ ],
460
+ [
461
+ 64,
462
+ 64
463
+ ],
464
+ [
465
+ 128,
466
+ 128
467
+ ]
468
+ ],
469
+ "max_width": 128,
470
+ "max_height": 128
471
+ },
472
+ "frame_behavior": {
473
+ "mode": "batch_animation",
474
+ "single_frame": false,
475
+ "frame_count_policy": "depends_on_canvas_size"
476
+ },
477
+ "adaptation": [
478
+ "pad_to_target",
479
+ "integer_upscale"
480
+ ]
481
+ },
482
+ "evidence": [
483
+ {
484
+ "path": "docs/research/ai-animation-tools-2026-report.md",
485
+ "sha256": "f1050dd77ecffd8ad4ff87cb66f7bb147998bd2743862f57606890a0305a1e37",
486
+ "kind": "static"
487
+ }
488
+ ],
489
+ "limitations": [
490
+ "Animation-to-animation uses square canvas sizes and batch generation; use it as a provisional source only when the project accepts post-export isolation and validation.",
491
+ "The adapter is metadata-only and does not invoke PixelLab or prove a provider-native job receipt."
492
+ ],
493
+ "risk_level": "medium",
494
+ "side_effect_level": "remote_write",
495
+ "availability": {
496
+ "status": "unknown",
497
+ "environment": "external API/extension",
498
+ "reason": "API key, subscription and provider connectivity are not asserted by the registry"
499
+ }
21
500
  },
22
501
  {
23
502
  "adapter_id": "internal.imagegen",
@@ -26,13 +505,47 @@
26
505
  "adapter_version": "0.1",
27
506
  "invocation_mode": "agent-mediated",
28
507
  "cost_class": "included",
29
- "inputs": ["reference-images", "control-track", "prompt-hash"],
30
- "outputs": ["image", "frame-sequence", "generation-receipt"],
31
- "compatibility": {"os": ["linux", "macos", "windows"]},
32
- "evidence": [{"path": "docs/research/agent-skill-ecosystem-notes.md", "sha256": "18472ccd959191a4e769675b142076fa3c0103629d67b5be992fa524730cc530", "kind": "static"}],
33
- "limitations": ["Adapter imports Agent-mediated ImageGen output only; it does not invoke ImageGen or prove a model, seed, license, rig compatibility, runtime quality or human approval."],
508
+ "inputs": [
509
+ "reference-images",
510
+ "control-track",
511
+ "prompt-hash"
512
+ ],
513
+ "outputs": [
514
+ "image",
515
+ "frame-sequence",
516
+ "generation-receipt"
517
+ ],
518
+ "compatibility": {
519
+ "os": [
520
+ "linux",
521
+ "macos",
522
+ "windows"
523
+ ]
524
+ },
525
+ "capabilities": {
526
+ "frame_behavior": {
527
+ "mode": "unknown",
528
+ "single_frame": false
529
+ }
530
+ },
531
+ "evidence": [
532
+ {
533
+ "path": "docs/research/agent-skill-ecosystem-notes.md",
534
+ "sha256": "18472ccd959191a4e769675b142076fa3c0103629d67b5be992fa524730cc530",
535
+ "kind": "static"
536
+ }
537
+ ],
538
+ "limitations": [
539
+ "Adapter imports Agent-mediated ImageGen output only; it does not invoke ImageGen or prove a model, seed, license, rig compatibility, runtime quality or human approval.",
540
+ "Canvas and isolation capabilities are intentionally unknown until a real export contract is supplied."
541
+ ],
34
542
  "risk_level": "medium",
35
- "side_effect_level": "user_review_required"
543
+ "side_effect_level": "user_review_required",
544
+ "availability": {
545
+ "status": "unknown",
546
+ "environment": "agent-mediated",
547
+ "reason": "current Agent tool availability must be resolved outside static registry metadata"
548
+ }
36
549
  },
37
550
  {
38
551
  "adapter_id": "openai.chatgpt",
@@ -41,13 +554,48 @@
41
554
  "adapter_version": "0.1",
42
555
  "invocation_mode": "manual",
43
556
  "cost_class": "external",
44
- "inputs": ["user-provided-images", "reference-images", "control-track", "prompt-hash"],
45
- "outputs": ["image", "frame-sequence", "generation-receipt"],
46
- "compatibility": {"os": ["linux", "macos", "windows"]},
47
- "evidence": [{"path": "docs/research/agent-skill-ecosystem-notes.md", "sha256": "18472ccd959191a4e769675b142076fa3c0103629d67b5be992fa524730cc530", "kind": "static"}],
48
- "limitations": ["Adapter imports user-provided ChatGPT output only; it does not invoke ChatGPT, verify a provider-native task ID, prove a model, seed, license, rig compatibility, runtime quality or human approval."],
557
+ "inputs": [
558
+ "user-provided-images",
559
+ "reference-images",
560
+ "control-track",
561
+ "prompt-hash"
562
+ ],
563
+ "outputs": [
564
+ "image",
565
+ "frame-sequence",
566
+ "generation-receipt"
567
+ ],
568
+ "compatibility": {
569
+ "os": [
570
+ "linux",
571
+ "macos",
572
+ "windows"
573
+ ]
574
+ },
575
+ "capabilities": {
576
+ "frame_behavior": {
577
+ "mode": "unknown",
578
+ "single_frame": false
579
+ }
580
+ },
581
+ "evidence": [
582
+ {
583
+ "path": "docs/research/agent-skill-ecosystem-notes.md",
584
+ "sha256": "18472ccd959191a4e769675b142076fa3c0103629d67b5be992fa524730cc530",
585
+ "kind": "static"
586
+ }
587
+ ],
588
+ "limitations": [
589
+ "Adapter imports user-provided ChatGPT output only; it does not invoke ChatGPT, verify a provider-native task ID, prove a model, seed, license, rig compatibility, runtime quality or human approval.",
590
+ "Canvas and isolation capabilities are unknown until the user supplies a provider-specific export contract."
591
+ ],
49
592
  "risk_level": "medium",
50
- "side_effect_level": "user_review_required"
593
+ "side_effect_level": "user_review_required",
594
+ "availability": {
595
+ "status": "unknown",
596
+ "environment": "user-mediated",
597
+ "reason": "user session/output availability is not asserted by static registry metadata"
598
+ }
51
599
  }
52
600
  ]
53
601
  }
@@ -42,6 +42,8 @@ const PYTHON_COMMANDS = {
42
42
  "asset-consistency": "scripts/asset-consistency.py",
43
43
  "frame-generation-lock": "scripts/frame-generation-lock.py",
44
44
  "frame-set-preflight": "scripts/frame-set-preflight.py",
45
+ "action-separation": "scripts/action-separation.py",
46
+ "asset-generation-plan": "scripts/asset-generation-plan.py",
45
47
  "artifact-intake": "scripts/artifact-intake.py",
46
48
  "runtime-candidate": "scripts/runtime-candidate.py",
47
49
  "rig-compatibility": "scripts/rig-compatibility.py",
@@ -50,6 +52,10 @@ const PYTHON_COMMANDS = {
50
52
  "alpha-isolate": "scripts/isolate-alpha-background.py",
51
53
  };
52
54
 
55
+ const DIRECT_NODE_COMMANDS = {
56
+ "asset-adapt": "scripts/asset-adapt.mjs",
57
+ };
58
+
53
59
  const NODE_COMMANDS = {
54
60
  init: "scripts/setup.mjs",
55
61
  setup: "scripts/setup.mjs",
@@ -71,6 +77,7 @@ Start here:
71
77
  init One safe project setup; no animation gate runs
72
78
  status Short read-only readiness report
73
79
  doctor Validate the installed Skill package
80
+ doctor --runtime Also verify the Playwright Chromium executable
74
81
 
75
82
  Use when an animation task needs it:
76
83
  analyze Run project analysis and refresh Project Memory
@@ -95,7 +102,10 @@ Use when an animation task needs it:
95
102
  asset-provenance Validate, classify or report asset origin and production readiness
96
103
  asset-consistency Validate frame geometry, atlas contamination and layered-map contracts
97
104
  frame-generation-lock Validate or compose locked per-frame generation instructions
98
- frame-set-preflight Fail closed on shared canvases, scale drift and frame contamination
105
+ frame-set-preflight Fail closed on shared canvases, scale drift, frame contamination and action manifest binding
106
+ action-separation Validate action-scoped frame manifests and independent competitor-action evidence
107
+ asset-generation-plan Produce a MotionLoom project assessment, ranked routes and explicit canvas/frame guidance without invoking APIs
108
+ asset-adapt Apply deterministic transparent padding/integer upscale with a hash-bound report
99
109
  artifact-intake Bind generation controls, provenance, adapter metadata and exported bytes
100
110
  runtime-candidate Bind intake exports to consistency contracts before runtime testing
101
111
  rig-compatibility Validate rig bones, sockets, actions, events and runtime adapter evidence
@@ -112,6 +122,7 @@ Cross-platform examples:
112
122
  motionloom memory record-decision --project-root . --id ui-easing \\
113
123
  --status accepted --summary "Use ease-out for UI entry" --user-confirmed
114
124
  motionloom discovery check --root . --json
125
+ motionloom doctor --runtime --json
115
126
  motionloom discovery install-matrix --root . --json
116
127
  motionloom capability card --format json
117
128
  motionloom visual-truth validate --root . --input src/output/<scene>/visual-truth.json
@@ -119,7 +130,11 @@ Cross-platform examples:
119
130
  motionloom asset-provenance check --input <asset-provenance.json> --root <scene-dir> --mode runtime --json
120
131
  motionloom asset-consistency validate --kind frame-geometry --input <frame-geometry.json> --root <scene-dir> --json
121
132
  motionloom frame-generation-lock compose --input <frame-generation-lock.json> --root <asset-root> --frame-id walk.00 --json
122
- motionloom frame-set-preflight --input <frame-geometry.json> --root <asset-root> --json
133
+ motionloom frame-set-preflight --input <frame-geometry.json> --root <asset-root> --action-manifest <action-sequence.json> --json
134
+ motionloom action-separation validate --input <action-sequence.json> --root <asset-root> --json
135
+ motionloom asset-generation-plan plan --request <asset-generation-request.json> --project-root .
136
+ motionloom asset-generation-plan plan --request <asset-generation-request.json> --project-root . --json --strict
137
+ motionloom asset-adapt pad --input source.png --output target.png --width 256 --height 448 --anchor footline --report adaptation.json --json
123
138
  motionloom artifact-intake intake --root <asset-dir> --registry artifact-adapter-registry.json \\
124
139
  --receipt <generation-receipt.json> --controls <control-track.json> --export-manifest <export-manifest.json> --json
125
140
  motionloom alpha-isolate <opaque.png> <isolated.png> --report <alpha-report.json>
@@ -138,7 +153,7 @@ if (!command || command === "help" || command === "--help" || command === "-h")
138
153
  }
139
154
 
140
155
  const alias = COMMAND_ALIASES[command];
141
- const script = alias?.script || NODE_COMMANDS[command] || PYTHON_COMMANDS[command];
156
+ const script = alias?.script || DIRECT_NODE_COMMANDS[command] || NODE_COMMANDS[command] || PYTHON_COMMANDS[command];
142
157
  if (!script) {
143
158
  console.error(`Unknown MotionLoom command: ${command}`);
144
159
  printHelp();
@@ -148,7 +163,9 @@ if (!script) {
148
163
  const executable = script.endsWith(".mjs") ? process.execPath : PYTHON;
149
164
  const delegatedArgs = alias
150
165
  ? [...alias.args, ...args]
151
- : NODE_COMMANDS[command] && !["setup", "init"].includes(command)
166
+ : DIRECT_NODE_COMMANDS[command]
167
+ ? args
168
+ : NODE_COMMANDS[command] && !["setup", "init"].includes(command)
152
169
  ? [command, ...args]
153
170
  : command === "init"
154
171
  ? ["init", ...args]