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
@@ -0,0 +1,26 @@
1
+ {
2
+ "schema_version": "0.1",
3
+ "contract": "action-separation-verifier-evidence",
4
+ "sequence_id": "hero-walk-v1",
5
+ "action_id": "walk",
6
+ "frame_id": "walk.03",
7
+ "frame_index": 3,
8
+ "image_sha256": "161d906dc850cd3d3ee970b97406fc36bcdf1c34222ac94171a05672bf64d957",
9
+ "identity_lock_sha256": "59d6b09622b19839b8c9342fb043965ea3f515c8979d769284d413f60a5f7e2d",
10
+ "generator_agent_id": "motionloom-generator-v1",
11
+ "verifier_id": "motionloom-separation-verifier-v1",
12
+ "result": {
13
+ "expected_action": "walk",
14
+ "top_competitor": "run",
15
+ "margin": 0.32999999999999996,
16
+ "threshold": 0.2,
17
+ "status": "pass",
18
+ "method": "independent-action-rubric-v1"
19
+ },
20
+ "result_sha256": "259be183f714d57cec7721127c0dfe61b552e8fbcbb189b782b662ed57ac138b",
21
+ "provenance": {
22
+ "kind": "separate_verifier_artifact",
23
+ "producer_id": "motionloom-independent-verifier-v1",
24
+ "run_id": "fixture-run-2026-08-22"
25
+ }
26
+ }
@@ -0,0 +1,43 @@
1
+ {
2
+ "schema_version": "0.1",
3
+ "request_id": "hero-attack-pixellab-256x448",
4
+ "asset_id": "hero.character.attack",
5
+ "asset_kind": "frame_sequence",
6
+ "target": {
7
+ "canvas": {"width": 256, "height": 448},
8
+ "frame_count": 8,
9
+ "fps": 8,
10
+ "alpha_mode": "straight",
11
+ "pixel_art": true,
12
+ "anchor": "footline"
13
+ },
14
+ "generation_policy": {
15
+ "frame_isolation": "required",
16
+ "allow_crop": false,
17
+ "allow_stretch": false,
18
+ "allow_silent_resize": false,
19
+ "allow_provider_batch_as_provisional": true,
20
+ "integer_scale_only": true
21
+ },
22
+ "project_context": {
23
+ "runtime": "custom-2d-game-runtime",
24
+ "framework": "canvas-sprite-runtime",
25
+ "existing_assets": ["examples/agent-consumer/asset-consistency/assets/hero-frame-00.png"],
26
+ "rig_requirements": ["preserve footline and pivot across frames", "keep action-specific frame identity"],
27
+ "provenance_requirements": ["generation receipt", "hash-bound export manifest", "human review"],
28
+ "validation_requirements": ["MotionLoom frame geometry", "MotionLoom action separation", "MotionLoom Dev Lab review"]
29
+ },
30
+ "actions": [
31
+ {
32
+ "action_id": "attack",
33
+ "positive_cues": ["forward sword swing", "weight shifts into strike", "weapon leads the silhouette"],
34
+ "negative_cues": ["walking cycle", "running cycle", "jumping", "idle stance"],
35
+ "frame_count": 8
36
+ }
37
+ ],
38
+ "references": [
39
+ {"id": "hero-identity", "role": "identity"},
40
+ {"id": "hero-style", "role": "style"},
41
+ {"id": "attack-pose-reference", "role": "pose"}
42
+ ]
43
+ }
@@ -0,0 +1,30 @@
1
+ # Canonical live Dev Lab sprite fixture
2
+
3
+ This fixture is a small, hash-bindable sprite-sequence runtime for exercising the Dev Lab live path from a clean checkout. It deliberately contains two review-required actions, `idle` and `reverse`, so the Action Library coverage gate can be observed moving from `1/2` to `2/2`.
4
+
5
+ The PNG files are deterministic repository fixtures. They are suitable for runtime-control and provenance-contract testing; they are **not** a claim about production art quality, identity fidelity, licensing, authorship or user approval.
6
+
7
+ ## Run the live binding check
8
+
9
+ From the repository root:
10
+
11
+ ```bash
12
+ python3 - <<'PY'
13
+ import importlib.util
14
+ import sys
15
+ from pathlib import Path
16
+
17
+ root = Path(".").resolve()
18
+ sys.path.insert(0, str(root / "scripts"))
19
+ path = root / "scripts/review-hook.py"
20
+ spec = importlib.util.spec_from_file_location("motionloom_review_hook", path)
21
+ module = importlib.util.module_from_spec(spec)
22
+ spec.loader.exec_module(module)
23
+ bundle = module.runtime_bundle(root / "examples/agent-consumer/devlab-live-sprite")
24
+ assert bundle and bundle["mode"] == "sprite-sequence"
25
+ assert bundle["animations"] == ["idle", "reverse"]
26
+ print(bundle["bundle_sha256"])
27
+ PY
28
+ ```
29
+
30
+ To use the fixture in an actual review task, copy it into a rendered scene directory as `devlab-runtime.json` and run `motionloom review-hook prepare --task-dir <task-dir> --lab-url <dev-lab-url>`. Open the exact emitted candidate URL, inspect both actions, exercise play/pause/restart/seek/step/speed/loop, and obtain explicit user approval before any PR workflow.
@@ -0,0 +1,61 @@
1
+ {
2
+ "schema_version": "1.0",
3
+ "mode": "sprite-sequence",
4
+ "files": [
5
+ "frames/idle-00.png",
6
+ "frames/idle-01.png",
7
+ "frames/idle-02.png",
8
+ "frames/reverse-00.png",
9
+ "frames/reverse-01.png",
10
+ "frames/reverse-02.png"
11
+ ],
12
+ "default_animation": "idle",
13
+ "animations": [
14
+ {
15
+ "id": "idle",
16
+ "fps": 6,
17
+ "frames": [
18
+ "frames/idle-00.png",
19
+ "frames/idle-01.png",
20
+ "frames/idle-02.png"
21
+ ],
22
+ "loop": true,
23
+ "review_required": true
24
+ },
25
+ {
26
+ "id": "reverse",
27
+ "fps": 6,
28
+ "frames": [
29
+ "frames/reverse-00.png",
30
+ "frames/reverse-01.png",
31
+ "frames/reverse-02.png"
32
+ ],
33
+ "loop": false,
34
+ "review_required": true
35
+ }
36
+ ],
37
+ "controls": {
38
+ "play": true,
39
+ "pause": true,
40
+ "restart": true,
41
+ "seek": true,
42
+ "step": true,
43
+ "speed": true,
44
+ "loop": true
45
+ },
46
+ "viewport": {
47
+ "canvas_width": 1920,
48
+ "canvas_height": 1920,
49
+ "pixel_art": false
50
+ },
51
+ "review_policy": {
52
+ "require_all_animations": true
53
+ },
54
+ "action_separation": {
55
+ "status": "pass",
56
+ "action_id": "sprite-sequence",
57
+ "frame_count": 6,
58
+ "passing_frame_count": 6,
59
+ "forbidden_action_ids": ["cross-action-mix"]
60
+ }
61
+ }
@@ -1,8 +1,21 @@
1
1
  {
2
- "schema_version": "0.1",
2
+ "schema_version": "0.2",
3
3
  "lock_id": "hero-walk-v1",
4
4
  "asset_identity": "character/hero-male",
5
5
  "action_id": "walk",
6
+ "sequence_id": "hero-walk-v1",
7
+ "forbidden_action_ids": ["run", "jump", "attack"],
8
+ "action_manifest": "asset-consistency/action-sequence/hero-walk-action-manifest.json",
9
+ "action_contract": {
10
+ "positive_cues": [
11
+ "alternating contact and passing phases with an upright body",
12
+ "weight transfers along the shared footline with a natural counter-swing"
13
+ ],
14
+ "negative_cues": [
15
+ "no airborne jump, attack wind-up, or running stride",
16
+ "no casting, hurt, dodge, or second character silhouette"
17
+ ]
18
+ },
6
19
  "reference": {
7
20
  "image": "asset-consistency/assets/hero-frame-00.png",
8
21
  "sha256": "75ce90653a01a23bcfab1aef83647d6364d3edbf6e4a44b84c635338c12b9248",
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "motionloom",
3
- "version": "2.6.1",
3
+ "version": "2.7.0",
4
4
  "type": "module",
5
5
  "packageManager": "pnpm@11.20.0",
6
6
  "description": "MotionLoom: project-aware animation Skill with Agent interoperability, graph, provenance, Motion IR, runtime telemetry, Visual Truth, Remediation Learning, DSSE-compatible signed attestation, external evidence verification and Dev Lab review.",
@@ -60,9 +60,18 @@
60
60
  "schemas/control-track.schema.json",
61
61
  "schemas/export-manifest.schema.json",
62
62
  "schemas/artifact-adapter-registry.schema.json",
63
+ "schemas/action-separation-verifier-evidence.schema.json",
64
+ "schemas/asset-generation-request.schema.json",
65
+ "schemas/asset-generation-plan.schema.json",
66
+ "schemas/asset-adaptation.schema.json",
67
+ "scripts/asset-adapt.mjs",
63
68
  "artifact-adapter-registry.json",
64
69
  "examples/agent-consumer/artifact-intake",
65
70
  "tests/scripts/test_artifact_intake.py",
71
+ "scripts/asset-generation-plan.py",
72
+ "examples/agent-consumer/asset-planning",
73
+ "tests/scripts/test_asset_generation_plan.py",
74
+ "tests/scripts/test_asset_adapt.py",
66
75
  "scripts/runtime-candidate.py",
67
76
  "schemas/runtime-candidate.schema.json",
68
77
  "examples/agent-consumer/runtime-candidate",
@@ -133,6 +142,7 @@
133
142
  "test": "python3 tests/scripts/run_tests.py",
134
143
  "validate": "npm run quality:attestation",
135
144
  "doctor": "node bin/motionloom.mjs doctor --json",
145
+ "doctor:runtime": "node bin/motionloom.mjs doctor --runtime --json",
136
146
  "init": "node bin/motionloom.mjs init",
137
147
  "setup": "node bin/motionloom.mjs setup",
138
148
  "setup:dry": "node bin/motionloom.mjs setup --dry-run",
@@ -181,6 +191,10 @@
181
191
  "asset-provenance:check": "node bin/motionloom.mjs asset-provenance check --input examples/agent-consumer/ai-generated-pilot-provenance.json --root examples/agent-consumer --mode runtime --json",
182
192
  "asset:consistency": "node bin/motionloom.mjs asset-consistency validate --kind frame-geometry --input examples/agent-consumer/asset-consistency/hero-walk-frame-geometry.json --root examples/agent-consumer/asset-consistency --json",
183
193
  "asset:audit": "node bin/motionloom.mjs asset-consistency report --kind frame-geometry --input examples/agent-consumer/asset-consistency/hero-walk-frame-geometry.json --root examples/agent-consumer/asset-consistency --json",
194
+ "action:separation": "node bin/motionloom.mjs action-separation validate --input examples/agent-consumer/asset-consistency/action-sequence/hero-walk-action-manifest.json --root examples/agent-consumer/asset-consistency --json",
195
+ "asset:plan": "node bin/motionloom.mjs asset-generation-plan plan --request examples/agent-consumer/asset-planning/pixellab-hero-256x448-request.json --project-root . --json",
196
+ "asset:adapt:smoke": "node bin/motionloom.mjs asset-adapt pad --input examples/agent-consumer/asset-consistency/assets/hero-frame-00.png --output /tmp/motionloom-adapt-smoke.png --width 16 --height 16 --anchor center --report /tmp/motionloom-adapt-smoke.json --json",
197
+ "frame:preflight": "node bin/motionloom.mjs frame-set-preflight --input examples/agent-consumer/asset-consistency/hero-walk-frame-geometry.json --root examples/agent-consumer/asset-consistency --action-manifest examples/agent-consumer/asset-consistency/action-sequence/hero-walk-action-manifest.json --json",
184
198
  "artifact:intake": "node bin/motionloom.mjs artifact-intake intake --root . --registry artifact-adapter-registry.json --receipt examples/agent-consumer/artifact-intake/hero-motion-receipt.json --controls examples/agent-consumer/artifact-intake/hero-motion-controls.json --export-manifest examples/agent-consumer/artifact-intake/hero-motion-export.json --json",
185
199
  "runtime:candidate": "node bin/motionloom.mjs runtime-candidate validate --root . --input examples/agent-consumer/runtime-candidate/hero-walk-candidate.json --json",
186
200
  "rig:compatibility": "node bin/motionloom.mjs rig-compatibility validate --root . --registry rig-adapter-registry.json --input examples/agent-consumer/rig-compatibility/hero-walk-fixture-rig.json --json",
@@ -2,6 +2,20 @@
2
2
 
3
3
  This contract applies whenever MotionLoom or an Agent creates two or more source frames for the same character, object, effect or other frame-based animation. It is automatic: the user should not have to ask for consistent frame geometry, isolated source frames or atlas hygiene.
4
4
 
5
+ ## Plan the provider before generating
6
+
7
+ Before calling PixelLab, ImageGen, ChatGPT or another provider, create a provider-neutral request that describes the real runtime target. The request must include the target canvas, frame count, alpha mode, pixel-art policy, action cues and whether one source frame per request is required:
8
+
9
+ ```bash
10
+ motionloom asset-generation-plan plan \
11
+ --request examples/agent-consumer/asset-planning/pixellab-hero-256x448-request.json \
12
+ --project-root . --json
13
+ ```
14
+
15
+ Treat the result as a MotionLoom recommendation, not an approval. The planner first assesses the project/task, then separates `recommendation_status` from `execution_status`. A provisional or scaffold route may remain a useful normal-planning recommendation when its project fit is strong; strict execution still requires the active execution policy. User preference is visible and may influence ranking, but cannot override a hard incompatibility. For example, PixelLab animation tools documented with square canvases can be used as a provisional source for a `256x448` target only through an explicit transparent-padding plan and post-export action/frame validation; the planner must not silently crop, stretch, or claim that batch output satisfies per-frame isolation. If no route is execution-eligible, normal planning should still expose safe provisional/manual options while strict mode fails closed.
16
+
17
+ The registry is provider-neutral and metadata-driven. A provider adapter remains `scaffold_only` until real export bytes, generation receipt, target-runtime evidence and human review have been recorded. Availability is separate from registry existence: an unknown or unavailable route may be shown as a MotionLoom option, but the Agent must resolve connectivity before execution. Bearer tokens belong in the connector/secret layer and never in requests, prompts, receipts or project manifests.
18
+
5
19
  ## Default source policy
6
20
 
7
21
  Generated source frames are **isolated-frame assets**, not a pose sheet.
@@ -44,7 +58,7 @@ The lock binds:
44
58
  - center, pivot, footline, safe rectangle and minimum transparent padding;
45
59
  - target measured alpha-bounds plus permitted width/height drift;
46
60
  - appearance features that must be preserved and changes that are forbidden;
47
- - a hard source policy of one isolated frame per image, no pose sheet and no post-generation resize;
61
+ - a hard source policy of one isolated frame per image, no pose sheet and no silent post-generation resize;
48
62
  - every `frame_id`, its pose intent and its unique PNG output path;
49
63
  - the post-generation `frame-geometry` contract used by deterministic preflight;
50
64
  - a review-only trust boundary with `approval: false`.
@@ -61,10 +75,31 @@ motionloom frame-generation-lock compose \
61
75
  --root src/output/<scene> --frame-id <action.frame-id> --json
62
76
  ```
63
77
 
64
- For batch planning, `compose-all` emits one independent instruction per frame while preserving the same lock hash and reference hash. It does **not** authorize asking a provider for one multi-frame canvas; each returned instruction still represents one isolated source image.
78
+ For batch planning, `compose-all` emits one independent instruction per frame while preserving the same lock hash and reference hash. It does **not** authorize asking a provider for one multi-frame canvas; each returned instruction still represents one isolated source image. If the selected provider only emits a batch animation, record it as provisional and create independent envelopes after export; do not promote it to an isolated-source pass automatically.
65
79
 
66
80
  If the reference bytes change, an output path escapes the asset root, two frames target the same PNG, the lock permits a pose sheet/post-resize, or the trust boundary is weakened, validation fails closed before generation.
67
81
 
82
+ ## Keep action identity across isolated frames
83
+
84
+ Isolated canvases prevent neighboring pixels from leaking into a crop, but they do not prove that a frame belongs to the intended action. For every multi-frame action, use an action-scoped manifest with one immutable `sequence_id`, `action_id`, `identity_lock_sha256`, ordered `frame_index` values and explicit `forbidden_action_ids`. Each image must have a frame envelope binding those fields to the image SHA-256.
85
+
86
+ The action verifier must record `expected_action`, `top_competitor`, `margin`, `threshold` and `status`. A generator-created envelope is only declared evidence; independent verification requires a separate hash-bound verifier artifact. A low margin, competitor mismatch or missing verifier provenance is **quarantined**, not silently relabeled or moved to another action. Validate the manifest before packing:
87
+
88
+ ```bash
89
+ motionloom action-separation validate \\
90
+ --input src/output/<scene>/<action>-action-manifest.json \\
91
+ --root src/output/<scene> --json
92
+
93
+ motionloom frame-set-preflight \\
94
+ --input src/output/<scene>/<action>-frame-geometry.json \\
95
+ --root src/output/<scene> \\
96
+ --action-manifest src/output/<scene>/<action>-action-manifest.json --json
97
+ ```
98
+
99
+ A contact sheet may be generated after isolated frames pass as a review projection, but it is never the production source. When one frame is ambiguous, regenerate that frame from the accepted anchor and the same action lock; do not auto-move it, use a neighboring action as a reference, or let the agent infer its action from the filename.
100
+
101
+ See [`docs/ACTION-SEPARATION.md`](../docs/ACTION-SEPARATION.md) for the manifest/envelope contract and quarantine policy.
102
+
68
103
  ## Validate incrementally
69
104
 
70
105
  Do not generate the complete action and only inspect it at the end. After each candidate frame:
@@ -0,0 +1,43 @@
1
+ {
2
+ "$schema": "https://json-schema.org/draft/2020-12/schema",
3
+ "$id": "https://motionloom.dev/schemas/action-separation-verifier-evidence.schema.json",
4
+ "title": "MotionLoom Action Separation Verifier Evidence",
5
+ "description": "Separate verifier artifact bound to one frame result. Hashes verify binding integrity, not the truthfulness of an asserted producer identity.",
6
+ "type": "object",
7
+ "additionalProperties": false,
8
+ "required": ["schema_version", "contract", "sequence_id", "action_id", "frame_id", "frame_index", "image_sha256", "identity_lock_sha256", "generator_agent_id", "verifier_id", "result", "result_sha256", "provenance"],
9
+ "properties": {
10
+ "schema_version": {"const": "0.1"},
11
+ "contract": {"const": "action-separation-verifier-evidence"},
12
+ "sequence_id": {"type": "string", "pattern": "^[a-z0-9][a-z0-9._-]{1,95}$"},
13
+ "action_id": {"type": "string", "pattern": "^[a-z0-9][a-z0-9._-]{1,63}$"},
14
+ "frame_id": {"type": "string", "pattern": "^[a-z0-9][a-z0-9._-]{1,63}$"},
15
+ "frame_index": {"type": "integer", "minimum": 0},
16
+ "image_sha256": {"type": "string", "pattern": "^[a-f0-9]{64}$"},
17
+ "identity_lock_sha256": {"type": "string", "pattern": "^[a-f0-9]{64}$"},
18
+ "generator_agent_id": {"type": "string", "pattern": "^[a-z0-9][a-z0-9._-]{1,63}$"},
19
+ "verifier_id": {"type": "string", "pattern": "^[a-z0-9][a-z0-9._-]{1,63}$"},
20
+ "result": {
21
+ "type": "object", "additionalProperties": false,
22
+ "required": ["expected_action", "top_competitor", "margin", "threshold", "status", "method"],
23
+ "properties": {
24
+ "expected_action": {"type": "string", "pattern": "^[a-z0-9][a-z0-9._-]{1,63}$"},
25
+ "top_competitor": {"type": "string", "pattern": "^[a-z0-9][a-z0-9._-]{1,63}$"},
26
+ "margin": {"type": "number", "minimum": 0},
27
+ "threshold": {"type": "number", "minimum": 0},
28
+ "status": {"enum": ["pass", "quarantined"]},
29
+ "method": {"type": "string", "minLength": 1}
30
+ }
31
+ },
32
+ "result_sha256": {"type": "string", "pattern": "^[a-f0-9]{64}$"},
33
+ "provenance": {
34
+ "type": "object", "additionalProperties": false,
35
+ "required": ["kind", "producer_id", "run_id"],
36
+ "properties": {
37
+ "kind": {"const": "separate_verifier_artifact"},
38
+ "producer_id": {"type": "string", "pattern": "^[a-z0-9][a-z0-9._-]{1,63}$"},
39
+ "run_id": {"type": "string", "minLength": 1}
40
+ }
41
+ }
42
+ }
43
+ }
@@ -0,0 +1,48 @@
1
+ {
2
+ "$schema": "https://json-schema.org/draft/2020-12/schema",
3
+ "$id": "https://motionloom.dev/schemas/action-sequence-manifest.schema.json",
4
+ "title": "MotionLoom Action Sequence Manifest",
5
+ "description": "Manifest binding for isolated frame sequences and explicitly classified action-separation evidence.",
6
+ "type": "object",
7
+ "additionalProperties": false,
8
+ "required": ["schema_version", "sequence_id", "asset_identity", "action_id", "identity_lock_sha256", "generator_agent_id", "forbidden_action_ids", "actions", "frames", "status", "approval"],
9
+ "properties": {
10
+ "schema_version": {"const": "0.2"},
11
+ "sequence_id": {"type": "string", "pattern": "^[a-z0-9][a-z0-9._-]{1,95}$"},
12
+ "asset_identity": {"type": "string", "minLength": 1},
13
+ "action_id": {"type": "string", "pattern": "^[a-z0-9][a-z0-9._-]{1,63}$"},
14
+ "identity_lock_sha256": {"type": "string", "pattern": "^[a-f0-9]{64}$"},
15
+ "generator_agent_id": {"type": "string", "pattern": "^[a-z0-9][a-z0-9._-]{1,63}$"},
16
+ "forbidden_action_ids": {
17
+ "type": "array", "minItems": 1, "uniqueItems": true,
18
+ "items": {"type": "string", "pattern": "^[a-z0-9][a-z0-9._-]{1,63}$"}
19
+ },
20
+ "actions": {
21
+ "type": "array", "minItems": 2,
22
+ "items": {
23
+ "type": "object", "additionalProperties": false,
24
+ "required": ["action_id", "positive_cues", "negative_cues"],
25
+ "properties": {
26
+ "action_id": {"type": "string", "pattern": "^[a-z0-9][a-z0-9._-]{1,63}$"},
27
+ "positive_cues": {"type": "array", "minItems": 1, "items": {"type": "string", "minLength": 1}},
28
+ "negative_cues": {"type": "array", "minItems": 1, "items": {"type": "string", "minLength": 1}}
29
+ }
30
+ }
31
+ },
32
+ "frames": {
33
+ "type": "array", "minItems": 2,
34
+ "items": {
35
+ "type": "object", "additionalProperties": false,
36
+ "required": ["frame_index", "frame_id", "image", "envelope"],
37
+ "properties": {
38
+ "frame_index": {"type": "integer", "minimum": 0},
39
+ "frame_id": {"type": "string", "pattern": "^[a-z0-9][a-z0-9._-]{1,63}$"},
40
+ "image": {"type": "string", "pattern": "^.+\\.png$"},
41
+ "envelope": {"type": "string", "pattern": "^.+\\.json$"}
42
+ }
43
+ }
44
+ },
45
+ "status": {"enum": ["review_required", "quarantined"]},
46
+ "approval": {"const": false}
47
+ }
48
+ }
@@ -11,6 +11,6 @@
11
11
  "registry_id": {"type": "string", "pattern": "^[A-Za-z0-9][A-Za-z0-9._-]{2,127}$"},
12
12
  "generated_at": {"type": "string", "format": "date-time"},
13
13
  "selection_policy": {"type": "object", "additionalProperties": false, "required": ["require_verified", "allow_scaffold_only"], "properties": {"require_verified": {"type": "boolean"}, "allow_scaffold_only": {"type": "boolean"}}},
14
- "adapters": {"type": "array", "minItems": 1, "items": {"type": "object", "additionalProperties": false, "required": ["adapter_id", "kind", "status", "adapter_version", "invocation_mode", "cost_class", "inputs", "outputs", "compatibility", "evidence", "limitations", "risk_level", "side_effect_level"], "properties": {"adapter_id": {"type": "string", "pattern": "^[A-Za-z0-9][A-Za-z0-9._:-]{2,127}$"}, "kind": {"type": "string", "enum": ["fixture", "internal_skill", "external_provider", "manual_import"]}, "status": {"type": "string", "enum": ["verified", "scaffold_only", "static_validated", "project_integrated", "disabled"]}, "adapter_version": {"type": "string", "minLength": 1}, "invocation_mode": {"type": "string", "enum": ["none", "manual", "agent-mediated", "api"]}, "cost_class": {"type": "string", "enum": ["included", "metered", "external", "unknown"]}, "inputs": {"type": "array", "items": {"type": "string"}}, "outputs": {"type": "array", "items": {"type": "string"}}, "compatibility": {"type": "object", "additionalProperties": false, "required": ["os"], "properties": {"os": {"type": "array", "items": {"type": "string"}}, "browsers": {"type": "array", "items": {"type": "string"}}}}, "evidence": {"type": "array", "minItems": 1, "items": {"type": "object", "additionalProperties": false, "required": ["path", "sha256", "kind"], "properties": {"path": {"type": "string", "pattern": "^(?!/)(?!.*(?:^|/)\\.\\.(?:/|$)).+"}, "sha256": {"type": "string", "pattern": "^[a-f0-9]{64}$"}, "kind": {"type": "string", "enum": ["runtime", "ci", "browser", "static"]}}}}, "limitations": {"type": "array", "items": {"type": "string"}}, "risk_level": {"type": "string", "enum": ["low", "medium", "high"]}, "side_effect_level": {"type": "string", "enum": ["read", "local_write", "user_review_required", "remote_write"]}}}}
14
+ "adapters": {"type": "array", "minItems": 1, "items": {"type": "object", "additionalProperties": false, "required": ["adapter_id", "kind", "status", "adapter_version", "invocation_mode", "cost_class", "inputs", "outputs", "compatibility", "evidence", "limitations", "risk_level", "side_effect_level"], "properties": {"adapter_id": {"type": "string", "pattern": "^[A-Za-z0-9][A-Za-z0-9._:-]{2,127}$"}, "kind": {"type": "string", "enum": ["fixture", "internal_skill", "external_provider", "manual_import"]}, "status": {"type": "string", "enum": ["verified", "scaffold_only", "static_validated", "project_integrated", "disabled"]}, "adapter_version": {"type": "string", "minLength": 1}, "invocation_mode": {"type": "string", "enum": ["none", "manual", "agent-mediated", "api"]}, "cost_class": {"type": "string", "enum": ["included", "metered", "external", "unknown"]}, "inputs": {"type": "array", "items": {"type": "string"}}, "outputs": {"type": "array", "items": {"type": "string"}}, "compatibility": {"type": "object", "additionalProperties": false, "required": ["os"], "properties": {"os": {"type": "array", "items": {"type": "string"}}, "browsers": {"type": "array", "items": {"type": "string"}}}}, "availability": {"type": "object", "additionalProperties": false, "properties": {"status": {"type": "string", "enum": ["known", "available", "unavailable", "unknown"]}, "environment": {"type": "string"}, "checked_at": {"type": "string", "format": "date-time"}, "reason": {"type": "string"}}}, "capabilities": {"type": "object", "additionalProperties": false, "properties": {"official_docs": {"type": "array", "items": {"type": "string", "format": "uri"}}, "canvas": {"type": "object", "additionalProperties": false, "properties": {"shapes": {"type": "array", "items": {"type": "string", "enum": ["square", "portrait", "landscape"]}}, "allowed_sizes": {"type": "array", "items": {"type": "array", "minItems": 2, "maxItems": 2, "items": {"type": "integer", "minimum": 1}}}, "max_width": {"type": "integer", "minimum": 1}, "max_height": {"type": "integer", "minimum": 1}}}, "frame_behavior": {"type": "object", "additionalProperties": false, "properties": {"mode": {"type": "string", "enum": ["single_frame", "batch_animation", "interpolation", "unknown"]}, "single_frame": {"type": "boolean"}, "max_frames_per_request": {"type": "integer", "minimum": 1}, "frame_count_policy": {"type": "string", "enum": ["fixed", "depends_on_canvas_size", "unknown"]}, "limits_by_canvas": {"type": "array", "items": {"type": "object", "additionalProperties": false, "required": ["canvas", "max_frames_per_request"], "properties": {"canvas": {"type": "array", "minItems": 2, "maxItems": 2, "items": {"type": "integer", "minimum": 1}}, "max_frames_per_request": {"type": "integer", "minimum": 1}}}}}}, "adaptation": {"type": "array", "items": {"type": "string", "enum": ["pad_to_target", "provider_native_resize", "tile_stitch", "integer_upscale"]}}}}, "evidence": {"type": "array", "minItems": 1, "items": {"type": "object", "additionalProperties": false, "required": ["path", "sha256", "kind"], "properties": {"path": {"type": "string", "pattern": "^(?!/)(?!.*(?:^|/)\\.\\.(?:/|$)).+"}, "sha256": {"type": "string", "pattern": "^[a-f0-9]{64}$"}, "kind": {"type": "string", "enum": ["runtime", "ci", "browser", "static"]}}}}, "limitations": {"type": "array", "items": {"type": "string"}}, "risk_level": {"type": "string", "enum": ["low", "medium", "high"]}, "side_effect_level": {"type": "string", "enum": ["read", "local_write", "user_review_required", "remote_write"]}}}}
15
15
  }
16
16
  }
@@ -0,0 +1,21 @@
1
+ {
2
+ "$schema": "https://json-schema.org/draft/2020-12/schema",
3
+ "$id": "https://github.com/lenhonbp/MotionLoom/blob/main/schemas/asset-adaptation.schema.json",
4
+ "title": "MotionLoom asset adaptation report",
5
+ "description": "Deterministic canvas adaptation evidence. It does not grant approval or production eligibility.",
6
+ "type": "object",
7
+ "additionalProperties": false,
8
+ "required": ["contract", "schema_version", "operation", "status", "approval", "production_approved", "source", "output", "transform"],
9
+ "properties": {
10
+ "contract": {"const": "motionloom-asset-adaptation"},
11
+ "schema_version": {"const": "0.1"},
12
+ "operation": {"const": "pad"},
13
+ "status": {"const": "built"},
14
+ "approval": {"const": false},
15
+ "production_approved": {"const": false},
16
+ "source": {"type": "object", "additionalProperties": false, "required": ["path", "sha256", "canvas"], "properties": {"path": {"type": "string", "minLength": 1}, "sha256": {"type": "string", "pattern": "^[a-f0-9]{64}$"}, "canvas": {"type": "array", "minItems": 2, "maxItems": 2, "items": {"type": "integer", "minimum": 1}}}},
17
+ "output": {"type": "object", "additionalProperties": false, "required": ["path", "sha256", "canvas"], "properties": {"path": {"type": "string", "minLength": 1}, "sha256": {"type": "string", "pattern": "^[a-f0-9]{64}$"}, "canvas": {"type": "array", "minItems": 2, "maxItems": 2, "items": {"type": "integer", "minimum": 1}}}},
18
+ "transform": {"type": "object", "additionalProperties": false, "required": ["scale", "x", "y", "anchor", "crop", "stretch", "interpolation"], "properties": {"scale": {"type": "integer", "minimum": 1}, "x": {"type": "integer", "minimum": 0}, "y": {"type": "integer", "minimum": 0}, "anchor": {"type": "string", "enum": ["center", "footline"]}, "crop": {"const": false}, "stretch": {"const": false}, "interpolation": {"const": "nearest-neighbour"}}},
19
+ "note": {"type": "string"}
20
+ }
21
+ }
@@ -0,0 +1,77 @@
1
+ {
2
+ "$schema": "https://json-schema.org/draft/2020-12/schema",
3
+ "$id": "https://github.com/lenhonbp/MotionLoom/blob/main/schemas/asset-generation-plan.schema.json",
4
+ "title": "MotionLoom project-aware asset generation plan",
5
+ "description": "Advisory MotionLoom assessment. Recommendations never grant execution authorization or approval.",
6
+ "type": "object",
7
+ "additionalProperties": false,
8
+ "required": [
9
+ "contract", "schema_version", "producer", "source", "identity", "status", "decision", "execution_decision",
10
+ "approval", "production_approved", "request", "project", "registry", "providers", "selection",
11
+ "recommendations", "agent_guidance", "next_steps", "warnings"
12
+ ],
13
+ "properties": {
14
+ "contract": {"const": "motionloom-asset-generation-plan"},
15
+ "schema_version": {"const": "0.2"},
16
+ "producer": {"const": "MotionLoom"},
17
+ "source": {"type": "string", "minLength": 1},
18
+ "identity": {
19
+ "type": "object",
20
+ "additionalProperties": false,
21
+ "required": ["product", "role"],
22
+ "properties": {"product": {"const": "MotionLoom"}, "role": {"type": "string", "minLength": 1}}
23
+ },
24
+ "status": {"const": "plan_only"},
25
+ "decision": {"type": "string", "enum": ["recommendations_available", "compatible_execution_route_available", "execution_route_requires_review_or_adaptation", "no_execution_eligible_route", "no_safe_recommendation_available"]},
26
+ "execution_decision": {"type": "string", "enum": ["compatible_execution_route_available", "execution_route_requires_review_or_adaptation", "no_execution_eligible_route"]},
27
+ "approval": {"const": false},
28
+ "production_approved": {"const": false},
29
+ "request": {"type": "object"},
30
+ "project": {"type": "object"},
31
+ "registry": {"type": "object"},
32
+ "providers": {"type": "array", "items": {"type": "object"}},
33
+ "selection": {
34
+ "type": "object",
35
+ "required": ["policy", "eligible_count", "provisional_count", "blocked_count", "recommendation_count"],
36
+ "properties": {
37
+ "policy": {"type": "object"},
38
+ "eligible_count": {"type": "integer", "minimum": 0},
39
+ "provisional_count": {"type": "integer", "minimum": 0},
40
+ "blocked_count": {"type": "integer", "minimum": 0},
41
+ "recommendation_count": {"type": "integer", "minimum": 0}
42
+ }
43
+ },
44
+ "recommendations": {
45
+ "type": "array",
46
+ "items": {
47
+ "type": "object",
48
+ "required": ["adapter_id", "recommendation_status", "execution_status", "execution_evidence_status", "execution_eligible", "user_preference", "availability", "project_fit", "rationale", "agent_guidance", "approval"],
49
+ "properties": {
50
+ "adapter_id": {"type": "string"},
51
+ "recommendation_status": {"type": "string", "enum": ["recommended", "acceptable", "not_recommended"]},
52
+ "execution_status": {"type": "string", "enum": ["verified", "provisional", "blocked"]},
53
+ "execution_evidence_status": {"type": "string", "enum": ["verified", "provisional"]},
54
+ "execution_eligible": {"type": "boolean"},
55
+ "user_preference": {"type": "object"},
56
+ "availability": {"type": "object"},
57
+ "project_fit": {"type": "string", "enum": ["high", "medium", "low"]},
58
+ "rationale": {"type": "array", "items": {"type": "string"}},
59
+ "agent_guidance": {"type": "object"},
60
+ "approval": {"const": false}
61
+ }
62
+ }
63
+ },
64
+ "agent_guidance": {
65
+ "type": "object",
66
+ "required": ["recommended_by", "summary", "next_step", "validation_route"],
67
+ "properties": {
68
+ "recommended_by": {"const": "MotionLoom"},
69
+ "summary": {"type": "string"},
70
+ "next_step": {"type": "string"},
71
+ "validation_route": {"type": "array", "items": {"type": "string"}}
72
+ }
73
+ },
74
+ "next_steps": {"type": "array", "items": {"type": "string"}},
75
+ "warnings": {"type": "array", "items": {"type": "string"}}
76
+ }
77
+ }