{
  "$schema": "https://json-schema.org/draft/2020-12/schema",
  "$id": "openmontage/artifacts/final_review",
  "title": "Final Review",
  "description": "Structured self-review of the rendered output. The compose stage must produce this artifact to prove the agent inspected the actual rendered video before presenting it to the user. If status is 'revise' or 'fail', the agent must not present the video as complete.",
  "type": "object",
  "required": ["version", "output_path", "status", "checks"],
  "properties": {
    "version": { "type": "string", "const": "1.0" },
    "output_path": {
      "type": "string",
      "description": "Path to the rendered output file that was reviewed"
    },
    "status": {
      "type": "string",
      "enum": ["pass", "revise", "fail"],
      "description": "pass=ready to present, revise=fixable issues found, fail=critical problems"
    },
    "checks": {
      "type": "object",
      "required": [
        "technical_probe",
        "visual_spotcheck",
        "audio_spotcheck",
        "promise_preservation",
        "subtitle_check"
      ],
      "properties": {
        "technical_probe": {
          "type": "object",
          "description": "ffprobe validation of the output file",
          "properties": {
            "valid_container": { "type": "boolean" },
            "duration_seconds": { "type": "number" },
            "resolution": { "type": "string" },
            "fps": { "type": "number" },
            "has_audio": { "type": "boolean" },
            "codec": { "type": "string" },
            "file_size_bytes": { "type": "integer" },
            "issues": {
              "type": "array",
              "items": { "type": "string" }
            }
          }
        },
        "visual_spotcheck": {
          "type": "object",
          "description": "Sample frames inspected from opening, middle, climax, ending",
          "properties": {
            "frames_sampled": { "type": "integer", "minimum": 4 },
            "frame_paths": {
              "type": "array",
              "items": { "type": "string" }
            },
            "black_frames_detected": { "type": "boolean" },
            "broken_overlays": { "type": "boolean" },
            "missing_assets": { "type": "boolean" },
            "unreadable_text": { "type": "boolean" },
            "issues": {
              "type": "array",
              "items": { "type": "string" }
            }
          }
        },
        "audio_spotcheck": {
          "type": "object",
          "description": "Audio quality verification",
          "properties": {
            "narration_present": { "type": "boolean" },
            "music_present": { "type": "boolean" },
            "unexpected_silence": { "type": "boolean" },
            "clipping_detected": { "type": "boolean" },
            "mix_intelligible": { "type": "boolean" },
            "issues": {
              "type": "array",
              "items": { "type": "string" }
            }
          }
        },
        "promise_preservation": {
          "type": "object",
          "description": "Delivery promise and renderer governance checks",
          "properties": {
            "delivery_promise_honored": { "type": "boolean" },
            "renderer_family_used": { "type": "string", "description": "Creative grammar that actually ran" },
            "render_runtime_used": {
              "type": "string",
              "enum": ["remotion", "hyperframes", "ffmpeg"],
              "description": "Technical runtime that actually executed the render. Must match the runtime locked at proposal unless a logged decision overrode it."
            },
            "runtime_swap_detected": {
              "type": "boolean",
              "description": "True if the runtime that ran differs from the runtime locked in proposal_packet. An unapproved swap is a contract violation."
            },
            "runtime_swap_check": {
              "type": "string",
              "description": "Human-readable status of the runtime-swap check: 'ok — …', 'detected — …', or 'skipped — …'. When the check was skipped, the reviewer skill is responsible for cross-artifact comparison."
            },
            "motion_ratio_actual": { "type": "number" },
            "silent_downgrade_detected": { "type": "boolean" },
            "issues": {
              "type": "array",
              "items": { "type": "string" }
            }
          }
        },
        "subtitle_check": {
          "type": "object",
          "description": "Subtitle/caption verification against source script",
          "properties": {
            "subtitles_expected": { "type": "boolean" },
            "subtitles_present": { "type": "boolean" },
            "coverage_ratio": { "type": "number", "minimum": 0, "maximum": 1 },
            "timing_drift_detected": { "type": "boolean" },
            "issues": {
              "type": "array",
              "items": { "type": "string" }
            }
          }
        },
        "transcript_comparison": {
          "type": "object",
          "description": "Optional: transcribe the output and compare to source script",
          "properties": {
            "transcript_matches_script": { "type": ["boolean", "null"] },
            "word_accuracy": { "type": ["number", "null"], "minimum": 0, "maximum": 1 },
            "issues": {
              "type": "array",
              "items": { "type": "string" }
            }
          }
        },
        "atelier": {
          "type": "object",
          "description": "Atelier-only doctrine checks (populated when composition_mode='atelier'). Generated by tools/video/video_compose.py → _run_atelier_checks.",
          "properties": {
            "stock_reuse_detected": { "type": "boolean", "description": "TRUE if the bespoke project imports from the stock creative registry — fails the render." },
            "offending_imports": {
              "type": "array",
              "description": "Files + import paths that violated the doctrine.",
              "items": {
                "type": "object",
                "properties": {
                  "file": { "type": "string" },
                  "import": { "type": "string" }
                }
              }
            },
            "art_direction_declared": { "type": "boolean" },
            "art_direction": { "type": ["string", "null"] },
            "issues": { "type": "array", "items": { "type": "string" } }
          }
        }
      },
      "additionalProperties": false
    },
    "issues_found": {
      "type": "array",
      "items": { "type": "string" },
      "description": "All issues found across all checks, summarized for the user"
    },
    "recommended_action": {
      "type": "string",
      "enum": ["present_to_user", "re_render", "revise_edit", "revise_assets", "block", "re_author"],
      "description": "What the agent should do next based on the review findings"
    },
    "metadata": { "type": "object" }
  },
  "additionalProperties": false
}
