motionloom 2.5.1 → 2.6.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.
- package/AGENTS.md +2 -0
- package/CHANGELOG.md +32 -1
- package/README.md +18 -7
- package/SECURITY.md +6 -7
- package/SKILL.md +5 -3
- package/agent-card.json +4 -4
- package/agent-surfaces.json +1 -1
- package/dev-lab/public/action-library.js +899 -0
- package/dev-lab/public/devlab.js +648 -119
- package/dev-lab/public/index.html +151 -18
- package/dev-lab/public/runtime-bridge.js +109 -0
- package/docs/CHECKLIST.md +15 -2
- package/docs/DEV-LAB-RUNTIME.md +160 -0
- package/docs/DEV-LAB-STATE-TRANSITIONS.md +121 -0
- package/docs/STATUS.md +3 -3
- package/docs/releases/2.6.0.md +38 -0
- package/package.json +3 -1
- package/schemas/browser-review-candidate.schema.json +37 -0
- package/schemas/devlab-runtime.schema.json +140 -0
- package/schemas/devlab-state-machine.schema.json +103 -0
- package/scripts/review-hook.py +255 -19
package/docs/STATUS.md
CHANGED
|
@@ -4,7 +4,7 @@
|
|
|
4
4
|
|
|
5
5
|
## Current release posture
|
|
6
6
|
|
|
7
|
-
MotionLoom's repository source and package manifest carry **2.
|
|
7
|
+
MotionLoom's repository source and package manifest carry **2.6.0 release metadata**. The publication state of the npm registry and GitHub Release/tag must be verified against the latest release workflow rather than inferred from this document. The repository has a cross-platform CLI, one-command project onboarding, durable Project Memory, Agent interoperability surfaces, artifact-first handoff, runtime evidence, Visual Truth, Remediation Learning, signed attestation, AI-first asset provenance, a truthful code-authored runtime lane and an interactive browser-based Dev Lab review workbench. Dev Lab now supports hash-bound live playback, arbitrary project-defined action libraries, and optional state/transition review flows in addition to deterministic snapshot evidence. The protected manual release workflow verifies package/changelog/release-note alignment before publication.
|
|
8
8
|
|
|
9
9
|
The repository is **engineering-ready for continued integration work**, not a universal production certification for every animation framework or every host project. CI status must be read from the latest GitHub Actions run, not inferred from historical audit prose.
|
|
10
10
|
|
|
@@ -16,7 +16,7 @@ The repository is **engineering-ready for continued integration work**, not a un
|
|
|
16
16
|
| Rive, GSAP and Framer Motion | Adapter and fixture evidence | Framework-specific runtime adapters and smoke checks can render representative scenes through browser/runtime paths | Equivalent coverage to the Lottie path across arbitrary projects |
|
|
17
17
|
| Project Memory | Contract and relocation evidence | Stable project identity, atomic persistence, integrity guard, freshness states and path rebinding after relocation | Automatic correctness of an Agent's inferred decision |
|
|
18
18
|
| Semantic intelligence | Deterministic evaluation evidence | Project graph, provenance, Motion IR, continuity, fix-plan and adversarial/deep-stress contracts; bounded analyzer reports scan budgets and truncation | Human-level design judgment, external-project product-value evidence or guaranteed first-pass acceptance |
|
|
19
|
-
| Dev Lab |
|
|
19
|
+
| Dev Lab | Interactive review infrastructure evidence | Identity-bound candidate loading, live runtime playback controls, arbitrary Action Library discovery, state/transition and review-sequence testing, deterministic snapshots, user checklist and review export | A full visual authoring editor, automatic approval or PR authorization |
|
|
20
20
|
|
|
21
21
|
## Normative sources
|
|
22
22
|
|
|
@@ -30,4 +30,4 @@ Use the following order when sources disagree:
|
|
|
30
30
|
|
|
31
31
|
## Known next work
|
|
32
32
|
|
|
33
|
-
The bounded analyzer has
|
|
33
|
+
The bounded analyzer has been exercised against a labeled external corpus; see the [dated evidence note](audits/external-project-corpus-2026-08-13.md). The 2.5.x publication chain established npm/GitHub release provenance, and 2.6.0 adds a substantially richer Dev Lab review surface without weakening the human approval boundary. The highest-value next evidence work is consumer-project review of real action sets and transitions, followed by paired product evaluation across more real projects and repeating the same provenance verification for each new release. Missing external projects are reported as `insufficient_evidence`, never as a pass. None of these items should weaken the user-review gate or convert runtime success or heuristic warnings into approval.
|
|
@@ -0,0 +1,38 @@
|
|
|
1
|
+
# MotionLoom 2.6.0
|
|
2
|
+
|
|
3
|
+
## Summary
|
|
4
|
+
|
|
5
|
+
MotionLoom 2.6.0 turns Dev Lab from a mostly checkpoint-oriented browser reviewer into an interactive runtime review workbench. The release keeps deterministic snapshots as evidence, but adds a live runtime lane for real playback, scalable project-defined action sets, and optional state/transition review flows so a user can inspect behavior much closer to the target runtime before approving a candidate.
|
|
6
|
+
|
|
7
|
+
## Added
|
|
8
|
+
|
|
9
|
+
- Interactive Dev Lab transport controls for live candidates: play, pause, restart, normalized scrub, frame stepping, playback speed and loop control.
|
|
10
|
+
- Stage inspection tools including fullscreen, zoom/fit, background selection, grid, bounds, baseline and pivot overlays; sprite candidates can opt into crisp pixel-art rendering.
|
|
11
|
+
- Data-driven animation discovery from `devlab-runtime.json`. Action names such as `idle`, `walk`, `run`, `attack`, `jump`, skills, emotes or project-specific clips are not hard-coded into MotionLoom.
|
|
12
|
+
- Scalable Action Library support with project-defined groups/categories, tags, search, collapsible sections and filters for review-required, unreviewed, looping and one-shot actions.
|
|
13
|
+
- Optional hash-bound `devlab-state-machine.json` contract with explicit states, legal transitions, multi-step review sequences and independent transition/sequence review coverage.
|
|
14
|
+
- Portable `select-animation` transitions for sprite/clip runtimes and strict `runtime-trigger` transitions for iframe runtimes through `triggerTransition(request)`.
|
|
15
|
+
- Transition history and review evidence for inspected actions, transitions, sequences and observed runtime state.
|
|
16
|
+
|
|
17
|
+
## Hardened
|
|
18
|
+
|
|
19
|
+
- Live runtime files, descriptors and state-machine bytes are bound into the browser-review candidate hash when declared; runtime-byte drift invalidates the candidate.
|
|
20
|
+
- Path traversal, absolute paths, symlink escapes, duplicate animation ids, undeclared runtime files and mismatched candidate/runtime animation sets fail closed.
|
|
21
|
+
- A declared live runtime that cannot load is shown as `LIVE RUNTIME UNAVAILABLE`; captured snapshots remain inspectable for diagnosis but approval is blocked.
|
|
22
|
+
- `runtime-trigger` transitions are counted only after the runtime reports the declared target state. MotionLoom never silently downgrades an unsupported runtime trigger into a clip switch.
|
|
23
|
+
- Search, grouping and filters affect presentation only. Hidden required actions or transitions still count as unreviewed.
|
|
24
|
+
- `runtime-bridge.js` is included in the npm package allowlist so installed-package iframe/state-machine review does not depend on source-checkout-only files.
|
|
25
|
+
|
|
26
|
+
## Verified behavior
|
|
27
|
+
|
|
28
|
+
The Dev Lab CI harness covers deterministic snapshots, live sprite playback, iframe runtime bridging, a four-action interactive dogfood set, a twelve-action Action Library fixture, sprite state transitions, real iframe runtime-trigger transitions and browser-security smoke tests. The state/transition fixtures exercise flows such as `Idle -> Run -> Attack -> Hurt -> Idle` and verify that completing runtime coverage does not create a user approval decision.
|
|
29
|
+
|
|
30
|
+
The protected release workflow reruns documentation/package validation, Skill Doctor, the full regression harness, isolated installed-package consumer smoke and release traceability before npm publication.
|
|
31
|
+
|
|
32
|
+
## Trust boundary
|
|
33
|
+
|
|
34
|
+
MotionLoom 2.6.0 does not turn runtime success into visual approval, production approval or PR authorization. Playback controls, action coverage, transition coverage, runtime state, hashes, snapshots, telemetry and automated sequence completion are evidence only. `approved` remains an explicit user decision bound to the exact browser-review candidate.
|
|
35
|
+
|
|
36
|
+
AI-generated or otherwise non-authoritative source assets retain their declared provenance and authority tier. Dev Lab review does not promote `ai_generated` material to `artist_authored`, `production_eligible` or `production_approved`.
|
|
37
|
+
|
|
38
|
+
The native macOS/iOS companion remains an unsigned source alpha. npm publication and GitHub Release creation remain explicit maintainer release actions through the protected GitHub Actions workflow.
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "motionloom",
|
|
3
|
-
"version": "2.
|
|
3
|
+
"version": "2.6.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.",
|
|
@@ -36,6 +36,8 @@
|
|
|
36
36
|
"requirements.txt",
|
|
37
37
|
"dev-lab/public/index.html",
|
|
38
38
|
"dev-lab/public/devlab.js",
|
|
39
|
+
"dev-lab/public/action-library.js",
|
|
40
|
+
"dev-lab/public/runtime-bridge.js",
|
|
39
41
|
"tests/runtime-harness",
|
|
40
42
|
"tests/evals",
|
|
41
43
|
"tests/scripts/run_tests.py",
|
|
@@ -15,6 +15,43 @@
|
|
|
15
15
|
"source_sha256": {"type": "string", "pattern": "^[a-f0-9]{64}$"},
|
|
16
16
|
"runtime": {"type": "string"},
|
|
17
17
|
"checkpoints": {"type": "array", "items": {"type": "integer", "enum": [0, 50, 100]}},
|
|
18
|
+
"runtime_review": {
|
|
19
|
+
"oneOf": [
|
|
20
|
+
{
|
|
21
|
+
"type": "object",
|
|
22
|
+
"additionalProperties": false,
|
|
23
|
+
"required": ["live", "mode", "checkpoints"],
|
|
24
|
+
"properties": {
|
|
25
|
+
"live": {"const": false},
|
|
26
|
+
"mode": {"const": "captured-evidence"},
|
|
27
|
+
"checkpoints": {"type": "array", "items": {"type": "integer", "enum": [0, 50, 100]}}
|
|
28
|
+
}
|
|
29
|
+
},
|
|
30
|
+
{
|
|
31
|
+
"type": "object",
|
|
32
|
+
"additionalProperties": false,
|
|
33
|
+
"required": ["live", "mode", "descriptor", "bundle_sha256", "animations", "review_policy"],
|
|
34
|
+
"properties": {
|
|
35
|
+
"live": {"const": true},
|
|
36
|
+
"mode": {"enum": ["sprite-sequence", "iframe"]},
|
|
37
|
+
"descriptor": {"const": "devlab-runtime.json"},
|
|
38
|
+
"bundle_sha256": {"type": "string", "pattern": "^[a-f0-9]{64}$"},
|
|
39
|
+
"animations": {
|
|
40
|
+
"type": "array",
|
|
41
|
+
"minItems": 1,
|
|
42
|
+
"uniqueItems": true,
|
|
43
|
+
"items": {"type": "string", "pattern": "^[A-Za-z0-9][A-Za-z0-9._-]{0,63}$"}
|
|
44
|
+
},
|
|
45
|
+
"review_policy": {
|
|
46
|
+
"type": "object",
|
|
47
|
+
"additionalProperties": false,
|
|
48
|
+
"required": ["require_all_animations"],
|
|
49
|
+
"properties": {"require_all_animations": {"type": "boolean"}}
|
|
50
|
+
}
|
|
51
|
+
}
|
|
52
|
+
}
|
|
53
|
+
]
|
|
54
|
+
},
|
|
18
55
|
"review_artifact": {"type": "string"},
|
|
19
56
|
"requires_user_approval": {"type": "boolean"},
|
|
20
57
|
"prepared_at": {"type": "string", "format": "date-time"},
|
|
@@ -0,0 +1,140 @@
|
|
|
1
|
+
{
|
|
2
|
+
"$schema": "https://json-schema.org/draft/2020-12/schema",
|
|
3
|
+
"$id": "https://motionloom.dev/schemas/devlab-runtime.schema.json",
|
|
4
|
+
"title": "MotionLoom Dev Lab live runtime descriptor",
|
|
5
|
+
"type": "object",
|
|
6
|
+
"additionalProperties": false,
|
|
7
|
+
"required": ["schema_version", "mode", "files", "animations", "default_animation", "controls", "review_policy"],
|
|
8
|
+
"properties": {
|
|
9
|
+
"schema_version": { "const": "1.0" },
|
|
10
|
+
"mode": { "enum": ["sprite-sequence", "iframe"] },
|
|
11
|
+
"files": {
|
|
12
|
+
"type": "array",
|
|
13
|
+
"minItems": 1,
|
|
14
|
+
"uniqueItems": true,
|
|
15
|
+
"items": { "$ref": "#/$defs/relativePath" }
|
|
16
|
+
},
|
|
17
|
+
"entrypoint": { "$ref": "#/$defs/relativePath" },
|
|
18
|
+
"default_animation": { "$ref": "#/$defs/animationId" },
|
|
19
|
+
"groups": {
|
|
20
|
+
"type": "array",
|
|
21
|
+
"uniqueItems": true,
|
|
22
|
+
"items": { "$ref": "#/$defs/group" }
|
|
23
|
+
},
|
|
24
|
+
"animations": {
|
|
25
|
+
"type": "array",
|
|
26
|
+
"minItems": 1,
|
|
27
|
+
"items": { "$ref": "#/$defs/animation" }
|
|
28
|
+
},
|
|
29
|
+
"controls": {
|
|
30
|
+
"type": "object",
|
|
31
|
+
"additionalProperties": false,
|
|
32
|
+
"required": ["play", "pause", "restart", "seek", "step", "speed", "loop"],
|
|
33
|
+
"properties": {
|
|
34
|
+
"play": { "type": "boolean" },
|
|
35
|
+
"pause": { "type": "boolean" },
|
|
36
|
+
"restart": { "type": "boolean" },
|
|
37
|
+
"seek": { "type": "boolean" },
|
|
38
|
+
"step": { "type": "boolean" },
|
|
39
|
+
"speed": { "type": "boolean" },
|
|
40
|
+
"loop": { "type": "boolean" }
|
|
41
|
+
}
|
|
42
|
+
},
|
|
43
|
+
"viewport": {
|
|
44
|
+
"type": "object",
|
|
45
|
+
"additionalProperties": false,
|
|
46
|
+
"properties": {
|
|
47
|
+
"canvas_width": { "type": "number", "exclusiveMinimum": 0 },
|
|
48
|
+
"canvas_height": { "type": "number", "exclusiveMinimum": 0 },
|
|
49
|
+
"pixel_art": { "type": "boolean" },
|
|
50
|
+
"baseline_y": { "type": "number" },
|
|
51
|
+
"pivot": {
|
|
52
|
+
"type": "object",
|
|
53
|
+
"additionalProperties": false,
|
|
54
|
+
"required": ["x", "y"],
|
|
55
|
+
"properties": {
|
|
56
|
+
"x": { "type": "number" },
|
|
57
|
+
"y": { "type": "number" }
|
|
58
|
+
}
|
|
59
|
+
},
|
|
60
|
+
"background": { "enum": ["checker", "dark", "light", "transparent", "project"] }
|
|
61
|
+
}
|
|
62
|
+
},
|
|
63
|
+
"review_policy": {
|
|
64
|
+
"type": "object",
|
|
65
|
+
"additionalProperties": false,
|
|
66
|
+
"required": ["require_all_animations"],
|
|
67
|
+
"properties": {
|
|
68
|
+
"require_all_animations": { "type": "boolean" }
|
|
69
|
+
}
|
|
70
|
+
}
|
|
71
|
+
},
|
|
72
|
+
"allOf": [
|
|
73
|
+
{
|
|
74
|
+
"if": { "properties": { "mode": { "const": "iframe" } } },
|
|
75
|
+
"then": { "required": ["entrypoint"] }
|
|
76
|
+
},
|
|
77
|
+
{
|
|
78
|
+
"if": { "properties": { "mode": { "const": "sprite-sequence" } } },
|
|
79
|
+
"then": {
|
|
80
|
+
"properties": {
|
|
81
|
+
"animations": {
|
|
82
|
+
"items": {
|
|
83
|
+
"required": ["id", "fps", "frames", "loop"]
|
|
84
|
+
}
|
|
85
|
+
}
|
|
86
|
+
}
|
|
87
|
+
}
|
|
88
|
+
}
|
|
89
|
+
],
|
|
90
|
+
"$defs": {
|
|
91
|
+
"animationId": {
|
|
92
|
+
"type": "string",
|
|
93
|
+
"pattern": "^[A-Za-z0-9][A-Za-z0-9._-]{0,63}$"
|
|
94
|
+
},
|
|
95
|
+
"groupId": {
|
|
96
|
+
"type": "string",
|
|
97
|
+
"pattern": "^[A-Za-z0-9][A-Za-z0-9._-]{0,63}$"
|
|
98
|
+
},
|
|
99
|
+
"relativePath": {
|
|
100
|
+
"type": "string",
|
|
101
|
+
"minLength": 1,
|
|
102
|
+
"pattern": "^(?!/)(?!.*(?:^|/)\\.\\.(?:/|$))(?!.*\\\\).+"
|
|
103
|
+
},
|
|
104
|
+
"group": {
|
|
105
|
+
"type": "object",
|
|
106
|
+
"additionalProperties": false,
|
|
107
|
+
"required": ["id"],
|
|
108
|
+
"properties": {
|
|
109
|
+
"id": { "$ref": "#/$defs/groupId" },
|
|
110
|
+
"label": { "type": "string", "minLength": 1, "maxLength": 120 },
|
|
111
|
+
"order": { "type": "integer", "minimum": -10000, "maximum": 10000 }
|
|
112
|
+
}
|
|
113
|
+
},
|
|
114
|
+
"animation": {
|
|
115
|
+
"type": "object",
|
|
116
|
+
"additionalProperties": false,
|
|
117
|
+
"required": ["id", "loop"],
|
|
118
|
+
"properties": {
|
|
119
|
+
"id": { "$ref": "#/$defs/animationId" },
|
|
120
|
+
"label": { "type": "string", "minLength": 1, "maxLength": 120 },
|
|
121
|
+
"group": { "$ref": "#/$defs/groupId" },
|
|
122
|
+
"tags": {
|
|
123
|
+
"type": "array",
|
|
124
|
+
"uniqueItems": true,
|
|
125
|
+
"items": { "type": "string", "minLength": 1, "maxLength": 64 }
|
|
126
|
+
},
|
|
127
|
+
"fps": { "type": "number", "exclusiveMinimum": 0 },
|
|
128
|
+
"frames": {
|
|
129
|
+
"type": "array",
|
|
130
|
+
"minItems": 1,
|
|
131
|
+
"items": { "$ref": "#/$defs/relativePath" }
|
|
132
|
+
},
|
|
133
|
+
"loop": { "type": "boolean" },
|
|
134
|
+
"duration_s": { "type": "number", "exclusiveMinimum": 0 },
|
|
135
|
+
"review_required": { "type": "boolean", "default": true },
|
|
136
|
+
"events": { "type": "array", "items": { "type": "string" } }
|
|
137
|
+
}
|
|
138
|
+
}
|
|
139
|
+
}
|
|
140
|
+
}
|
|
@@ -0,0 +1,103 @@
|
|
|
1
|
+
{
|
|
2
|
+
"$schema": "https://json-schema.org/draft/2020-12/schema",
|
|
3
|
+
"$id": "https://motionloom.dev/schemas/devlab-state-machine.schema.json",
|
|
4
|
+
"title": "MotionLoom Dev Lab state/transition review contract",
|
|
5
|
+
"type": "object",
|
|
6
|
+
"additionalProperties": false,
|
|
7
|
+
"required": ["schema_version", "initial_state", "states", "transitions", "review_policy"],
|
|
8
|
+
"properties": {
|
|
9
|
+
"schema_version": { "const": "1.0" },
|
|
10
|
+
"initial_state": { "$ref": "#/$defs/id" },
|
|
11
|
+
"states": {
|
|
12
|
+
"type": "array",
|
|
13
|
+
"minItems": 1,
|
|
14
|
+
"maxItems": 256,
|
|
15
|
+
"items": { "$ref": "#/$defs/state" }
|
|
16
|
+
},
|
|
17
|
+
"transitions": {
|
|
18
|
+
"type": "array",
|
|
19
|
+
"minItems": 1,
|
|
20
|
+
"maxItems": 512,
|
|
21
|
+
"items": { "$ref": "#/$defs/transition" }
|
|
22
|
+
},
|
|
23
|
+
"sequences": {
|
|
24
|
+
"type": "array",
|
|
25
|
+
"maxItems": 64,
|
|
26
|
+
"items": { "$ref": "#/$defs/sequence" }
|
|
27
|
+
},
|
|
28
|
+
"review_policy": {
|
|
29
|
+
"type": "object",
|
|
30
|
+
"additionalProperties": false,
|
|
31
|
+
"required": ["require_all_transitions", "require_all_sequences"],
|
|
32
|
+
"properties": {
|
|
33
|
+
"require_all_transitions": { "type": "boolean" },
|
|
34
|
+
"require_all_sequences": { "type": "boolean" }
|
|
35
|
+
}
|
|
36
|
+
}
|
|
37
|
+
},
|
|
38
|
+
"$defs": {
|
|
39
|
+
"id": {
|
|
40
|
+
"type": "string",
|
|
41
|
+
"pattern": "^[A-Za-z0-9][A-Za-z0-9._-]{0,63}$"
|
|
42
|
+
},
|
|
43
|
+
"state": {
|
|
44
|
+
"type": "object",
|
|
45
|
+
"additionalProperties": false,
|
|
46
|
+
"required": ["id", "animation"],
|
|
47
|
+
"properties": {
|
|
48
|
+
"id": { "$ref": "#/$defs/id" },
|
|
49
|
+
"label": { "type": "string", "minLength": 1, "maxLength": 120 },
|
|
50
|
+
"animation": { "$ref": "#/$defs/id" },
|
|
51
|
+
"description": { "type": "string", "maxLength": 500 }
|
|
52
|
+
}
|
|
53
|
+
},
|
|
54
|
+
"transition": {
|
|
55
|
+
"type": "object",
|
|
56
|
+
"additionalProperties": false,
|
|
57
|
+
"required": ["id", "from", "to", "mode"],
|
|
58
|
+
"properties": {
|
|
59
|
+
"id": { "$ref": "#/$defs/id" },
|
|
60
|
+
"label": { "type": "string", "minLength": 1, "maxLength": 120 },
|
|
61
|
+
"from": {
|
|
62
|
+
"oneOf": [
|
|
63
|
+
{ "$ref": "#/$defs/id" },
|
|
64
|
+
{ "const": "*" }
|
|
65
|
+
]
|
|
66
|
+
},
|
|
67
|
+
"to": { "$ref": "#/$defs/id" },
|
|
68
|
+
"trigger": { "type": "string", "minLength": 1, "maxLength": 120 },
|
|
69
|
+
"mode": { "enum": ["select-animation", "runtime-trigger"] },
|
|
70
|
+
"auto_play": { "type": "boolean", "default": true },
|
|
71
|
+
"review_required": { "type": "boolean", "default": true },
|
|
72
|
+
"wait_ms": { "type": "integer", "minimum": 0, "maximum": 10000 },
|
|
73
|
+
"payload": { "type": "object" }
|
|
74
|
+
}
|
|
75
|
+
},
|
|
76
|
+
"sequenceStep": {
|
|
77
|
+
"type": "object",
|
|
78
|
+
"additionalProperties": false,
|
|
79
|
+
"required": ["transition"],
|
|
80
|
+
"properties": {
|
|
81
|
+
"transition": { "$ref": "#/$defs/id" },
|
|
82
|
+
"wait_ms": { "type": "integer", "minimum": 0, "maximum": 10000 }
|
|
83
|
+
}
|
|
84
|
+
},
|
|
85
|
+
"sequence": {
|
|
86
|
+
"type": "object",
|
|
87
|
+
"additionalProperties": false,
|
|
88
|
+
"required": ["id", "steps"],
|
|
89
|
+
"properties": {
|
|
90
|
+
"id": { "$ref": "#/$defs/id" },
|
|
91
|
+
"label": { "type": "string", "minLength": 1, "maxLength": 120 },
|
|
92
|
+
"description": { "type": "string", "maxLength": 500 },
|
|
93
|
+
"review_required": { "type": "boolean", "default": false },
|
|
94
|
+
"steps": {
|
|
95
|
+
"type": "array",
|
|
96
|
+
"minItems": 1,
|
|
97
|
+
"maxItems": 64,
|
|
98
|
+
"items": { "$ref": "#/$defs/sequenceStep" }
|
|
99
|
+
}
|
|
100
|
+
}
|
|
101
|
+
}
|
|
102
|
+
}
|
|
103
|
+
}
|