motionloom 2.1.0 → 2.3.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 (46) hide show
  1. package/.agents/skills/motionloom/SKILL.md +14 -0
  2. package/.claude/skills/motionloom.md +5 -0
  3. package/.codex/skills/motionloom.md +11 -0
  4. package/AGENTS.md +17 -0
  5. package/CHANGELOG.md +51 -0
  6. package/README.md +60 -15
  7. package/ROADMAP.md +11 -5
  8. package/SECURITY.md +3 -2
  9. package/SKILL.md +40 -5
  10. package/agent-card.json +42 -4
  11. package/agent-surfaces.json +86 -0
  12. package/bin/motionloom.mjs +26 -3
  13. package/docs/AGENT-INTEGRATION.md +60 -0
  14. package/docs/CHECKLIST.md +7 -1
  15. package/docs/STATUS.md +2 -2
  16. package/docs/audits/ci-replay-remediation-2026-08-13.md +33 -0
  17. package/docs/releases/2.2.0.md +35 -0
  18. package/docs/releases/2.3.0.md +33 -0
  19. package/docs/releases/npm-publish-from-workstation.md +6 -6
  20. package/examples/agent-consumer/README.md +18 -0
  21. package/examples/agent-consumer/ai-generated-pilot/hero-male.json +10 -0
  22. package/examples/agent-consumer/ai-generated-pilot-provenance.json +55 -0
  23. package/examples/agent-consumer/fixture-manifest.json +82 -0
  24. package/package.json +31 -7
  25. package/references/agent-interoperability.md +40 -0
  26. package/references/intelligence-core.md +12 -2
  27. package/schemas/agent-surfaces.schema.json +78 -0
  28. package/schemas/asset-provenance.schema.json +183 -0
  29. package/schemas/remediation-history.schema.json +23 -0
  30. package/schemas/scene-manifest.schema.json +2 -0
  31. package/schemas/visual-truth.schema.json +80 -0
  32. package/scripts/asset-provenance.py +390 -0
  33. package/scripts/devlab.py +1 -1
  34. package/scripts/discovery.py +257 -0
  35. package/scripts/docs-audit.py +30 -2
  36. package/scripts/pr.py +3 -0
  37. package/scripts/quality-gate.py +81 -3
  38. package/scripts/remediation-learning.py +326 -0
  39. package/scripts/report.py +66 -0
  40. package/scripts/setup.mjs +472 -0
  41. package/scripts/skill-doctor.py +2 -1
  42. package/scripts/visual-truth.py +310 -0
  43. package/src/output/browser-review-smoke/asset-provenance.json +77 -0
  44. package/src/output/browser-review-smoke/manifest.json +2 -0
  45. package/src/output/browser-review-smoke/visual-truth.json +68 -0
  46. package/tests/scripts/run_tests.py +83 -0
package/package.json CHANGED
@@ -1,9 +1,9 @@
1
1
  {
2
2
  "name": "motionloom",
3
- "version": "2.1.0",
3
+ "version": "2.3.0",
4
4
  "type": "module",
5
5
  "packageManager": "pnpm@11.20.0",
6
- "description": "MotionLoom: project-aware animation Skill with graph, provenance, Motion IR, runtime telemetry, DSSE-compatible signed attestation, external evidence verification and Dev Lab review.",
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.",
7
7
  "author": "lenhonbp",
8
8
  "bin": {
9
9
  "motionloom": "bin/motionloom.mjs"
@@ -28,11 +28,19 @@
28
28
  "references",
29
29
  "docs",
30
30
  "examples",
31
+ "scripts/asset-provenance.py",
32
+ "schemas/asset-provenance.schema.json",
33
+ "examples/agent-consumer/ai-generated-pilot-provenance.json",
31
34
  "project-context.example.json",
32
35
  "tests/evals",
33
36
  "tests/scripts/run_tests.py",
34
37
  "tests/scripts/test_attestation.py",
35
- "tests/scripts/test_project_memory.py"
38
+ "tests/scripts/test_project_memory.py",
39
+ ".agents",
40
+ ".claude",
41
+ ".codex",
42
+ "AGENTS.md",
43
+ "agent-surfaces.json"
36
44
  ],
37
45
  "keywords": [
38
46
  "animation",
@@ -50,7 +58,10 @@
50
58
  "provenance",
51
59
  "attestation",
52
60
  "browser-review",
53
- "dev-lab"
61
+ "dev-lab",
62
+ "visual-truth",
63
+ "remediation-learning",
64
+ "agent-interoperability"
54
65
  ],
55
66
  "repository": {
56
67
  "type": "git",
@@ -70,8 +81,12 @@
70
81
  "scripts": {
71
82
  "prepack": "node scripts/prepack-clean.mjs",
72
83
  "test": "node bin/motionloom.mjs test",
73
- "validate": "node bin/motionloom.mjs quality-gate --all",
84
+ "validate": "npm run quality:attestation",
74
85
  "doctor": "node bin/motionloom.mjs doctor --json",
86
+ "setup": "node bin/motionloom.mjs setup",
87
+ "setup:dry": "node bin/motionloom.mjs setup --dry-run",
88
+ "status": "node bin/motionloom.mjs status",
89
+ "repair": "node bin/motionloom.mjs repair",
75
90
  "docs:check": "python3 scripts/docs-audit.py",
76
91
  "eval:projects": "python3 scripts/eval-projects.py --allow-insufficient",
77
92
  "release:verify": "python3 scripts/release-verify.py",
@@ -99,9 +114,18 @@
99
114
  "attestation:policy": "node bin/motionloom.mjs attestation validate-policy",
100
115
  "attestation:keygen": "node bin/motionloom.mjs attestation-keygen",
101
116
  "quality:telemetry": "node bin/motionloom.mjs quality-gate --scene browser-review-smoke --context artifacts/browser-review-smoke-task/project-context.json --task-dir artifacts/browser-review-smoke-task --require-browser-review --require-intelligence --require-p1 --require-benchmark --require-telemetry",
102
- "quality:attestation": "node bin/motionloom.mjs quality-gate --scene browser-review-smoke --context artifacts/browser-review-smoke-task/project-context.json --task-dir artifacts/browser-review-smoke-task --require-browser-review --require-intelligence --require-p1 --require-benchmark --require-telemetry --require-attestation",
117
+ "quality:attestation": "node bin/motionloom.mjs quality-gate --scene browser-review-smoke --context artifacts/browser-review-smoke-task/project-context.json --task-dir artifacts/browser-review-smoke-task --require-browser-review --require-intelligence --require-p1 --require-benchmark --require-telemetry --require-attestation --require-visual-truth",
103
118
  "pack:dotlottie": "node scripts/to-dotlottie.mjs",
104
- "runtime:test": "node scripts/runtime-adapters.mjs"
119
+ "runtime:test": "node scripts/runtime-adapters.mjs",
120
+ "visual-truth:build": "node bin/motionloom.mjs visual-truth build",
121
+ "visual-truth:check": "node bin/motionloom.mjs visual-truth validate --root . --input src/output/browser-review-smoke/visual-truth.json",
122
+ "remediation:validate": "node bin/motionloom.mjs remediation-learning validate --history artifacts/remediation-history.jsonl --json",
123
+ "remediation:summary": "node bin/motionloom.mjs remediation-learning summary --history artifacts/remediation-history.jsonl --output artifacts/remediation-summary.json --json",
124
+ "discovery:check": "node bin/motionloom.mjs discovery check --root . --json",
125
+ "discovery:show": "node bin/motionloom.mjs discovery show --root . --json",
126
+ "install:matrix": "node bin/motionloom.mjs discovery install-matrix --root . --json",
127
+ "asset-provenance:validate": "node bin/motionloom.mjs asset-provenance validate --input examples/agent-consumer/ai-generated-pilot-provenance.json --json",
128
+ "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"
105
129
  },
106
130
  "dependencies": {
107
131
  "@lottiefiles/dotlottie-web": "^0.79.0",
@@ -0,0 +1,40 @@
1
+ # Agent interoperability reference
2
+
3
+ Read this reference when installing MotionLoom into a new Agent environment or when adding a new discovery surface.
4
+
5
+ ## Contract hierarchy
6
+
7
+ 1. `SKILL.md` is the canonical workflow and must stay below the skill context budget.
8
+ 2. `agent-card.json` is the machine-readable capability and side-effect contract.
9
+ 3. `agent-surfaces.json` is the discovery/install/compatibility contract.
10
+ 4. `.agents/skills`, `.claude`, `.codex` and `AGENTS.md` are short routers that point to the canonical sources.
11
+ 5. `docs/AGENT-INTEGRATION.md` is user-facing installation and troubleshooting documentation.
12
+
13
+ Do not put divergent workflow rules into an Agent-specific file. Add reusable domain detail to `references/` or `docs/`, then update the canonical Skill navigation.
14
+
15
+ ## Discovery check output
16
+
17
+ The JSON result contains `status`, `source`, `surface_count`, `installation_count`, `errors` and `warnings`. `status=pass` means the local package has the expected files and contract values. It does not assert that the host project has been analyzed, that runtime dependencies are installed, that a candidate rendered correctly or that a user approved a change.
18
+
19
+ ## One-command onboarding
20
+
21
+ For a host project that has not installed MotionLoom, prefer:
22
+
23
+ ```bash
24
+ npx --yes motionloom setup --project-root <project-path>
25
+ npx --no-install motionloom status --project-root <project-path> --json
26
+ ```
27
+
28
+ `setup` is idempotent. It detects the project root and package manager, installs a local development dependency when needed, merges only the managed router block in `AGENTS.md`, runs discovery and bootstraps project context plus `.motionloom/project-memory.json`. Use `--dry-run --json` to preview and `repair --yes --json` to restore missing managed pieces. A setup result of `blocked` is actionable failure, not permission to continue with guessed context. Setup never commits, pushes, opens a PR or infers approval.
29
+
30
+ ## Adding a new Agent surface
31
+
32
+ Add one manifest entry with a safe relative path, a supported agent identifier, `canonical: SKILL.md` and either `load_mode: alias` or `load_mode: router`. Create a short file at that path. Add or update the installation/discovery test and run `motionloom discovery check --root . --json`, `python3 scripts/docs-audit.py` and the full test suite. Never silently overwrite an existing surface with a copied version of `SKILL.md`.
33
+
34
+ ## Source and version binding
35
+
36
+ When a user reports a discovery issue, capture the package version, source kind, resolved path, Git remote/commit where available and the discovery JSON. Treat a version mismatch as a structural problem, not as a runtime animation failure. Do not use network access in the check command; registry/Git availability belongs to the installation step.
37
+
38
+ ## Approval boundary
39
+
40
+ Discovery is deliberately orthogonal to approval. The discovery command can only tell an Agent how to load MotionLoom. It cannot transition an animation task to `ready_for_pr` or `confirmed`, and it cannot change `approval` from `false` to `true`.
@@ -8,6 +8,7 @@ Use this reference when an Agent needs to understand or extend MotionLoom's task
8
8
  | --- | --- | --- |
9
9
  | `project-graph.json` | `python3 scripts/intelligence.py graph build --task-dir <task>` | Links project, intent, scene, context, artifacts and review with task identity and hashes. |
10
10
  | `provenance.json` | `python3 scripts/intelligence.py provenance build --task-dir <task>` | Records step actor, builder, materials, products, policy, result and parent chain hash. |
11
+ | `asset-provenance.json` | `motionloom asset-provenance check --input <path> --root <scene-dir> --mode runtime|production` | Classifies asset origin/authority and effective readiness, binds file hashes and license/source metadata, and fails closed before production eligibility. It never grants `production_approved`. |
11
12
  | `capability-registry.json` | `python3 scripts/intelligence.py capabilities build --output <path>` | Describes verified/scaffold-only adapters, evidence freshness, compatibility, fallback and side effects. |
12
13
  | `motion-ir.json` | `python3 scripts/intelligence.py motion-ir build --task-dir <task>` | Binds framework-neutral tracks and accessibility policy to task, scene, context and source. |
13
14
  | `replay-bundle.json` | `python3 scripts/intelligence.py replay capture --root <root> --task-dir <task>` | Captures clean-root artifact hashes and environment metadata; verification fails on mutation or omission. |
@@ -15,6 +16,8 @@ Use this reference when an Agent needs to understand or extend MotionLoom's task
15
16
  | `semantic-lint-benchmark.json` | `python3 scripts/intelligence.py semantic-lint benchmark --task-dir <task>` | Measures in-process semantic-lint execution, rule coverage and p95 against a deterministic threshold; it is a performance contract, not visual approval. |
16
17
  | `runtime-telemetry.json` | `motionloom runtime-telemetry <scene> artifacts/<task-id>` | Records deterministic scrub-point observations, RAF timing, runtime state hashes and source/manifest/Motion IR bindings from the real adapter harness. The npm CLI is the cross-platform entrypoint; the legacy `.sh` wrapper remains for Unix compatibility. |
17
18
  | `evidence-verifier-report.json` | `python3 scripts/evidence-verifier.py --scene-dir <scene-dir> --task-dir <task> --runtime-evidence <path>` | Read-only external verification result for task/scene/path/hash/age integrity; `approval` is always `false`. |
19
+ | `visual-truth.json` | `motionloom visual-truth build|validate` | Baseline/candidate PNG hashes, dimensions, deterministic comparison signal, region-level review explanation and source/runtime/Motion IR provenance; `approval` is always `false`. |
20
+ | `remediation-history.jsonl` | `motionloom remediation-learning record-outcome|record-benchmark|summary` | Append-only, hash-chained user-confirmed corrections and deterministic benchmark runs; first-pass metrics guide future work but `approval` is always `false`. |
18
21
  | `attestation-statement.json` | `python3 scripts/attestation.py statement --scene-dir <scene-dir> --task-dir <task> --context <context>` | Derives canonical task/scene/source/manifest/Motion IR/evidence hash bindings before signing. |
19
22
  | `attestation.json` | `python3 scripts/attestation.py build --statement <statement> --private-key <key> --key-id <id>` | DSSE-compatible Ed25519 envelope over the versioned statement; `approval` is always `false`. |
20
23
  | `trust-policy.json` | `python3 scripts/attestation.py validate-policy --path <policy>` | Declares trusted keys, validity, rotation and fail-closed revocation behavior. |
@@ -24,7 +27,7 @@ Use this reference when an Agent needs to understand or extend MotionLoom's task
24
27
 
25
28
  ## Agent operating rules
26
29
 
27
- The Agent must build the graph, Motion IR, provenance, replay bundle, P1 feedback reports and semantic-lint benchmark after render and before the strict quality gate. For a strict observability run it must also capture runtime telemetry and run the external verifier before `--require-telemetry`. For a production trust run it must derive/sign `attestation.json`, copy or resolve a managed `trust-policy.json`, run the independent attestation verifier and use `--require-attestation`. It must run the report completeness contract for changed scenes; that contract selects one deterministic passing task bundle and fails on ambiguous ties. It may use a verified capability only when the registry evidence is fresh, its hash matches the referenced file and the target environment is compatible. `scaffold_only` is a planning option, never a production acceptance result.
30
+ The Agent must build the graph, Motion IR, step-level provenance, asset provenance, replay bundle, P1 feedback reports and semantic-lint benchmark after render and before the strict quality gate. For a strict observability run it must also capture runtime telemetry and run the external verifier before `--require-telemetry`. For a production trust run it must derive/sign `attestation.json`, copy or resolve a managed `trust-policy.json`, run the independent attestation verifier and use `--require-attestation` plus `--require-asset-provenance`. It must run the report completeness contract for changed scenes; that contract selects one deterministic passing task bundle and fails on ambiguous ties. It may use a verified capability only when the registry evidence is fresh, its hash matches the referenced file and the target environment is compatible. `scaffold_only` is a planning option, never a production acceptance result.
28
31
 
29
32
  The graph and provenance are evidence indexes, not approval tokens. A valid graph cannot bypass source binding, runtime assertions, browser review, reviewer consent or the `OPEN_PR=0` default. A confidence or risk value can prioritize investigation but cannot replace a deterministic rule or human decision.
30
33
 
@@ -70,7 +73,13 @@ python3 scripts/quality-gate.py \
70
73
  --scene <scene> \
71
74
  --context <project-context.json> \
72
75
  --task-dir artifacts/<task-id> \
73
- --require-browser-review --require-intelligence --require-p1 --require-benchmark --require-telemetry --require-attestation
76
+ --require-browser-review --require-intelligence --require-p1 --require-benchmark --require-telemetry --require-attestation --require-asset-provenance
77
+ motionloom asset-provenance check \
78
+ --input src/output/<scene>/asset-provenance.json \
79
+ --root src/output/<scene> --mode production \
80
+ --manifest src/output/<scene>/manifest.json --json
81
+ python3 scripts/remediation-learning.py validate --history artifacts/remediation-history.jsonl --json
82
+ python3 scripts/remediation-learning.py summary --history artifacts/remediation-history.jsonl --output artifacts/remediation-summary.json --json
74
83
  python3 scripts/eval-intelligence.py
75
84
  ```
76
85
 
@@ -94,5 +103,6 @@ The replay policy excludes generated reports and manifests because `report.py co
94
103
  | `artifact_base must share the Dev Lab origin` or identity binding failure | Dev Lab query parameters would mix an external or foreign task/candidate bundle | Reject the handoff and regenerate the review URL from the canonical task bundle. |
95
104
  | `runtime telemetry verification failed` | Scrub-point evidence is stale, tampered, missing, cross-task, path-escaped or bound to different source/manifest/Motion IR bytes | Re-run the real runtime capture from the canonical scene/task bundle, then verify again; never treat the verifier as approval. |
96
105
  | `attestation verification failed` | Payload hash, DSSE signature, signer validity/revocation, policy lookup, path binding or expected task/scene binding failed | Regenerate the statement from current artifacts, re-run the external verifier against a managed policy and investigate signer lifecycle; never flip `approval` or bypass user review. |
106
+ | `asset provenance is blocked` or `production_eligible: false` | Origin is unknown/AI-generated without the required review, a file hash/license/runtime/full-gate record is missing, or an Agent self-asserted artist authority/approval | Keep the candidate runtime-only, fix the provenance record or obtain the required human review; never rewrite the authority tier or set `production_approved` automatically. |
97
107
 
98
108
  The public eval corpus is `tests/evals/intelligence-cases.json`. It covers positive verified selection plus scaffold-only, stale evidence, tampering, graph corruption, replay tamper and foreign-task candidate failures. P1 extends the acceptance surface with semantic warning preservation, generic-intent detection, multi-scene context drift, selective rerun binding, performance budget/frame-rate warnings, perceptual easing/reduced-motion warnings and benchmark execution time. The 1.9.0 slice adds runtime telemetry happy-path, state tamper, cross-task identity, stale evidence and symlink escape cases. The 2.0.0 slice adds clean attestation, payload tamper, binding mismatch, revoked signer and unknown signer cases without weakening the approval=false and human-review invariants.
@@ -0,0 +1,78 @@
1
+ {
2
+ "$schema": "https://json-schema.org/draft/2020-12/schema",
3
+ "$id": "https://motionloom.dev/schemas/agent-surfaces.schema.json",
4
+ "title": "MotionLoom Agent Surfaces",
5
+ "type": "object",
6
+ "required": ["schema_version", "name", "version", "canonical", "surfaces", "installations", "compatibility", "rules"],
7
+ "properties": {
8
+ "schema_version": {"const": "1.0"},
9
+ "name": {"const": "motionloom"},
10
+ "version": {"type": "string", "pattern": "^[0-9]+\\.[0-9]+\\.[0-9]+$"},
11
+ "canonical": {
12
+ "type": "object",
13
+ "required": ["skill", "agent_card", "cli"],
14
+ "properties": {
15
+ "skill": {"const": "SKILL.md"},
16
+ "agent_card": {"const": "agent-card.json"},
17
+ "cli": {"const": "bin/motionloom.mjs"}
18
+ },
19
+ "additionalProperties": false
20
+ },
21
+ "surfaces": {
22
+ "type": "array",
23
+ "minItems": 4,
24
+ "items": {
25
+ "type": "object",
26
+ "required": ["id", "kind", "path", "canonical", "load_mode", "agents"],
27
+ "properties": {
28
+ "id": {"type": "string", "pattern": "^[a-z0-9-]+$"},
29
+ "kind": {"type": "string", "enum": ["agent-skill", "agent-instructions", "repository-guide"]},
30
+ "path": {"type": "string", "pattern": "^(?!/)(?!.*(?:^|/)\\.\\.(?:/|$)).+$"},
31
+ "canonical": {"const": "SKILL.md"},
32
+ "load_mode": {"type": "string", "enum": ["alias", "router"]},
33
+ "agents": {"type": "array", "minItems": 1, "items": {"type": "string"}}
34
+ },
35
+ "additionalProperties": false
36
+ }
37
+ },
38
+ "installations": {
39
+ "type": "array",
40
+ "minItems": 3,
41
+ "items": {
42
+ "type": "object",
43
+ "required": ["id", "source_kind", "command", "verification", "provenance"],
44
+ "properties": {
45
+ "id": {"type": "string"},
46
+ "source_kind": {"type": "string", "enum": ["npm", "npx", "git", "local"]},
47
+ "command": {"type": "string"},
48
+ "verification": {"type": "string"},
49
+ "provenance": {"type": "string"}
50
+ },
51
+ "additionalProperties": false
52
+ }
53
+ },
54
+ "compatibility": {
55
+ "type": "object",
56
+ "required": ["operating_systems", "node", "python", "agents"],
57
+ "properties": {
58
+ "operating_systems": {"type": "array", "items": {"type": "string"}},
59
+ "node": {"type": "string"},
60
+ "python": {"type": "string"},
61
+ "agents": {"type": "array", "items": {"type": "string"}}
62
+ },
63
+ "additionalProperties": false
64
+ },
65
+ "rules": {
66
+ "type": "object",
67
+ "required": ["canonical_instruction_source", "no_surface_copy", "no_network_required_for_check", "approval_is_never_inferred"],
68
+ "properties": {
69
+ "canonical_instruction_source": {"const": "SKILL.md"},
70
+ "no_surface_copy": {"const": true},
71
+ "no_network_required_for_check": {"const": true},
72
+ "approval_is_never_inferred": {"const": true}
73
+ },
74
+ "additionalProperties": false
75
+ }
76
+ },
77
+ "additionalProperties": false
78
+ }
@@ -0,0 +1,183 @@
1
+ {
2
+ "$schema": "https://json-schema.org/draft/2020-12/schema",
3
+ "$id": "https://github.com/lenhonbp/MotionLoom/blob/main/schemas/asset-provenance.schema.json",
4
+ "title": "MotionLoom asset provenance contract",
5
+ "description": "Asset-level origin, authority, readiness and human-governance contract. This schema never treats an Agent assertion as human approval.",
6
+ "type": "object",
7
+ "additionalProperties": false,
8
+ "required": ["schema_version", "provenance_id", "asset", "authority", "readiness", "files", "license", "provenance_chain", "created_at"],
9
+ "properties": {
10
+ "schema_version": {"const": "1.0"},
11
+ "provenance_id": {"type": "string", "pattern": "^[A-Za-z0-9][A-Za-z0-9._-]{2,127}$"},
12
+ "task_id": {"type": "string", "pattern": "^[A-Za-z0-9][A-Za-z0-9._-]{2,127}$"},
13
+ "scene": {"type": "string", "pattern": "^[A-Za-z0-9][A-Za-z0-9._-]{1,63}$"},
14
+ "created_at": {"type": "string", "format": "date-time"},
15
+ "asset": {
16
+ "type": "object",
17
+ "additionalProperties": false,
18
+ "required": ["id", "path", "type", "framework"],
19
+ "properties": {
20
+ "id": {"type": "string", "minLength": 1},
21
+ "path": {"type": "string", "pattern": "^(?!/)(?!.*(?:^|/)\\.\\.(?:/|$)).+"},
22
+ "type": {"type": "string", "minLength": 1},
23
+ "framework": {"type": "string", "minLength": 1},
24
+ "version": {"type": "string", "minLength": 1}
25
+ }
26
+ },
27
+ "authority": {
28
+ "type": "string",
29
+ "enum": ["ai_generated", "ai_assisted", "ai_assisted_human_reviewed", "artist_authored", "unknown"]
30
+ },
31
+ "readiness": {
32
+ "type": "string",
33
+ "enum": ["blocked", "runtime_ready", "review_required", "production_eligible", "production_approved"]
34
+ },
35
+ "generator": {
36
+ "type": "object",
37
+ "additionalProperties": false,
38
+ "required": ["model", "task_id", "source", "generated_at"],
39
+ "properties": {
40
+ "model": {"type": "string", "minLength": 1},
41
+ "task_id": {"type": "string", "minLength": 1},
42
+ "source": {"type": "string", "minLength": 1},
43
+ "generated_at": {"type": "string", "format": "date-time"},
44
+ "prompt_hash": {"type": "string", "pattern": "^[a-f0-9]{64}$"},
45
+ "agent": {"type": "string", "minLength": 1}
46
+ }
47
+ },
48
+ "human_attestation": {
49
+ "type": "object",
50
+ "additionalProperties": false,
51
+ "required": ["attestor", "attestor_type", "decision", "attested_at", "user_confirmed"],
52
+ "properties": {
53
+ "attestor": {"type": "string", "minLength": 1},
54
+ "attestor_type": {"type": "string", "enum": ["artist", "user"]},
55
+ "decision": {"type": "string", "enum": ["artist_authored", "accepted", "rejected"]},
56
+ "attested_at": {"type": "string", "format": "date-time"},
57
+ "user_confirmed": {"const": true},
58
+ "signature": {"type": "string", "minLength": 1}
59
+ }
60
+ },
61
+ "human_review": {
62
+ "type": "object",
63
+ "additionalProperties": false,
64
+ "required": ["reviewer", "decision", "scope", "reviewed_at", "user_confirmed"],
65
+ "properties": {
66
+ "reviewer": {"type": "string", "minLength": 1},
67
+ "decision": {"type": "string", "enum": ["approved", "rejected", "changes_requested"]},
68
+ "scope": {"type": "string", "minLength": 1},
69
+ "reviewed_at": {"type": "string", "format": "date-time"},
70
+ "user_confirmed": {"const": true},
71
+ "notes": {"type": "string"}
72
+ }
73
+ },
74
+ "human_approval": {
75
+ "type": "object",
76
+ "additionalProperties": false,
77
+ "required": ["issued_by", "decision", "approved_at", "user_confirmed"],
78
+ "properties": {
79
+ "issued_by": {
80
+ "type": "object",
81
+ "additionalProperties": false,
82
+ "required": ["id", "type"],
83
+ "properties": {
84
+ "id": {"type": "string", "minLength": 1},
85
+ "type": {"type": "string", "enum": ["user", "artist"]}
86
+ }
87
+ },
88
+ "decision": {"const": "approved"},
89
+ "approved_at": {"type": "string", "format": "date-time"},
90
+ "user_confirmed": {"const": true},
91
+ "notes": {"type": "string"}
92
+ }
93
+ },
94
+ "license": {
95
+ "type": "object",
96
+ "additionalProperties": false,
97
+ "required": ["spdx", "source", "attribution"],
98
+ "properties": {
99
+ "spdx": {"type": "string", "minLength": 1},
100
+ "source": {"type": "string", "minLength": 1},
101
+ "attribution": {"type": "string", "minLength": 1}
102
+ }
103
+ },
104
+ "files": {
105
+ "type": "array",
106
+ "minItems": 1,
107
+ "items": {
108
+ "type": "object",
109
+ "additionalProperties": false,
110
+ "required": ["path", "role", "sha256"],
111
+ "properties": {
112
+ "path": {"type": "string", "pattern": "^(?!/)(?!.*(?:^|/)\\.\\.(?:/|$)).+"},
113
+ "role": {"type": "string", "minLength": 1},
114
+ "sha256": {"type": "string", "pattern": "^[a-f0-9]{64}$"},
115
+ "bytes": {"type": "integer", "minimum": 0}
116
+ }
117
+ }
118
+ },
119
+ "provenance_chain": {
120
+ "type": "array",
121
+ "minItems": 1,
122
+ "items": {
123
+ "type": "object",
124
+ "additionalProperties": false,
125
+ "required": ["step", "actor", "source", "timestamp"],
126
+ "properties": {
127
+ "step": {"type": "string", "minLength": 1},
128
+ "actor": {"type": "string", "minLength": 1},
129
+ "source": {"type": "string", "minLength": 1},
130
+ "timestamp": {"type": "string", "format": "date-time"},
131
+ "sha256": {"type": "string", "pattern": "^[a-f0-9]{64}$"}
132
+ }
133
+ }
134
+ },
135
+ "runtime_evidence": {
136
+ "type": "object",
137
+ "additionalProperties": false,
138
+ "required": ["status", "runtime", "tested_at"],
139
+ "properties": {
140
+ "status": {"type": "string", "enum": ["pass", "fail", "not_run"]},
141
+ "runtime": {"type": "string", "minLength": 1},
142
+ "tested_at": {"type": "string", "format": "date-time"},
143
+ "evidence_path": {"type": "string", "minLength": 1},
144
+ "sha256": {"type": "string", "pattern": "^[a-f0-9]{64}$"}
145
+ }
146
+ },
147
+ "full_gate": {
148
+ "type": "object",
149
+ "additionalProperties": false,
150
+ "required": ["status", "quality_gate", "visual_truth", "license", "checked_at"],
151
+ "properties": {
152
+ "status": {"type": "string", "enum": ["pass", "fail", "not_run"]},
153
+ "quality_gate": {"const": "pass"},
154
+ "visual_truth": {"const": "pass"},
155
+ "license": {"const": "pass"},
156
+ "checked_at": {"type": "string", "format": "date-time"},
157
+ "report_path": {"type": "string", "minLength": 1}
158
+ }
159
+ }
160
+ },
161
+ "allOf": [
162
+ {
163
+ "if": {"required": ["authority"], "properties": {"authority": {"enum": ["ai_generated", "ai_assisted", "ai_assisted_human_reviewed"]}}},
164
+ "then": {"required": ["generator"]}
165
+ },
166
+ {
167
+ "if": {"required": ["authority"], "properties": {"authority": {"const": "artist_authored"}}},
168
+ "then": {"required": ["human_attestation"]}
169
+ },
170
+ {
171
+ "if": {"required": ["authority"], "properties": {"authority": {"const": "unknown"}}},
172
+ "then": {"properties": {"readiness": {"const": "blocked"}}}
173
+ },
174
+ {
175
+ "if": {"required": ["readiness"], "properties": {"readiness": {"const": "production_approved"}}},
176
+ "then": {"required": ["human_approval", "full_gate"]}
177
+ },
178
+ {
179
+ "if": {"required": ["readiness"], "properties": {"readiness": {"const": "production_eligible"}}},
180
+ "then": {"required": ["full_gate"]}
181
+ }
182
+ ]
183
+ }
@@ -0,0 +1,23 @@
1
+ {
2
+ "$schema": "https://json-schema.org/draft/2020-12/schema",
3
+ "$id": "https://github.com/lenhonbp/MotionLoom/blob/main/schemas/remediation-history.schema.json",
4
+ "title": "MotionLoom remediation and benchmark history event",
5
+ "type": "object",
6
+ "additionalProperties": true,
7
+ "required": ["schema_version", "event_id", "event_type", "recorded_at", "previous_event_sha256", "event_sha256"],
8
+ "properties": {
9
+ "schema_version": {"const": "0.1"},
10
+ "event_id": {"type": "string", "pattern": "^[A-Za-z0-9][A-Za-z0-9._-]{2,127}$"},
11
+ "event_type": {"type": "string", "enum": ["remediation_outcome", "benchmark_run"]},
12
+ "recorded_at": {"type": "string", "format": "date-time"},
13
+ "previous_event_sha256": {"type": ["string", "null"], "pattern": "^[a-f0-9]{64}$"},
14
+ "event_sha256": {"type": "string", "pattern": "^[a-f0-9]{64}$"},
15
+ "user_confirmed": {"type": "boolean"},
16
+ "first_pass_accepted": {"type": "boolean"},
17
+ "correction_count": {"type": "integer", "minimum": 0},
18
+ "result": {"type": "string", "enum": ["pass", "fail", "partial", "unknown"]},
19
+ "status": {"type": "string", "enum": ["pass", "fail"]},
20
+ "p95_ms": {"type": "number", "minimum": 0},
21
+ "threshold_ms": {"type": "number", "exclusiveMinimum": 0}
22
+ }
23
+ }
@@ -11,6 +11,8 @@
11
11
  "category": {"type": "string", "minLength": 1},
12
12
  "file": {"type": "string", "minLength": 1, "pattern": "^(?!/)(?!.*\\.\\.).+$"},
13
13
  "runtime_evidence": {"type": "string", "minLength": 1, "pattern": "^(?!/)(?!.*\\.\\.).+$"},
14
+ "visual_truth": {"type": "string", "minLength": 1, "pattern": "^(?!/)(?!.*\\.\\.).+$"},
15
+ "asset_provenance": {"type": "string", "minLength": 1, "pattern": "^(?!/)(?!.*\\.\\.).+$"},
14
16
  "source_binding": {
15
17
  "type": "object",
16
18
  "required": ["kind", "source_path", "authority", "license", "sha256"],
@@ -0,0 +1,80 @@
1
+ {
2
+ "$schema": "https://json-schema.org/draft/2020-12/schema",
3
+ "$id": "https://github.com/lenhonbp/MotionLoom/blob/main/schemas/visual-truth.schema.json",
4
+ "title": "MotionLoom Visual Truth Contract",
5
+ "type": "object",
6
+ "required": ["schema_version", "contract", "status", "scene", "frames", "comparison", "provenance", "review_boundary"],
7
+ "properties": {
8
+ "schema_version": {"const": "1.0"},
9
+ "contract": {"const": "motionloom-visual-truth"},
10
+ "status": {"enum": ["pass", "review_required"]},
11
+ "scene": {"type": "string", "minLength": 1},
12
+ "task_id": {"type": ["string", "null"]},
13
+ "frames": {
14
+ "type": "object",
15
+ "required": ["baseline", "candidate"],
16
+ "properties": {
17
+ "baseline": {"$ref": "#/$defs/frame"},
18
+ "candidate": {"$ref": "#/$defs/frame"}
19
+ },
20
+ "additionalProperties": false
21
+ },
22
+ "comparison": {
23
+ "type": "object",
24
+ "required": ["metric", "same_dimensions", "byte_identical", "changed", "interpretation"],
25
+ "properties": {
26
+ "metric": {"type": "string"},
27
+ "same_dimensions": {"type": "boolean"},
28
+ "byte_identical": {"type": "boolean"},
29
+ "changed": {"type": "boolean"},
30
+ "distance": {"type": "number", "minimum": 0},
31
+ "threshold": {"type": "number", "minimum": 0},
32
+ "interpretation": {"enum": ["equal", "review_required"]}
33
+ },
34
+ "additionalProperties": true
35
+ },
36
+ "regions": {"type": "array"},
37
+ "provenance": {
38
+ "type": "object",
39
+ "required": ["source_path", "source_sha256", "manifest_path", "manifest_sha256"],
40
+ "properties": {
41
+ "source_path": {"type": "string", "pattern": "^(?!/)(?!.*\\.\\.).+$"},
42
+ "source_sha256": {"type": "string", "pattern": "^[a-f0-9]{64}$"},
43
+ "manifest_path": {"type": "string", "pattern": "^(?!/)(?!.*\\.\\.).+$"},
44
+ "manifest_sha256": {"type": "string", "pattern": "^[a-f0-9]{64}$"},
45
+ "runtime_evidence_path": {"type": ["string", "null"]},
46
+ "runtime_evidence_sha256": {"type": ["string", "null"]},
47
+ "motion_ir_path": {"type": ["string", "null"]},
48
+ "motion_ir_sha256": {"type": ["string", "null"]}
49
+ },
50
+ "additionalProperties": true
51
+ },
52
+ "review_boundary": {
53
+ "type": "object",
54
+ "required": ["approval", "user_review_required", "decision"],
55
+ "properties": {
56
+ "approval": {"const": false},
57
+ "user_review_required": {"const": true},
58
+ "decision": {"const": "pending"}
59
+ },
60
+ "additionalProperties": true
61
+ }
62
+ },
63
+ "$defs": {
64
+ "frame": {
65
+ "type": "object",
66
+ "required": ["role", "percent", "path", "sha256", "bytes", "width", "height"],
67
+ "properties": {
68
+ "role": {"enum": ["baseline", "candidate"]},
69
+ "percent": {"type": "integer", "minimum": 0, "maximum": 100},
70
+ "path": {"type": "string", "pattern": "^(?!/)(?!.*\\.\\.).+$"},
71
+ "sha256": {"type": "string", "pattern": "^[a-f0-9]{64}$"},
72
+ "bytes": {"type": "integer", "minimum": 1},
73
+ "width": {"type": "integer", "minimum": 1},
74
+ "height": {"type": "integer", "minimum": 1}
75
+ },
76
+ "additionalProperties": true
77
+ }
78
+ },
79
+ "additionalProperties": true
80
+ }