{
  "$schema": "https://json-schema.org/draft/2020-12/schema",
  "$id": "https://polisher-suite.local/schemas/job.schema.json",
  "title": "Polisher Job Package",
  "description": "Frozen planning artifact emitted by polisher-sim. Represents planning truth.",
  "type": "object",
  "required": [
    "schema_version",
    "job_id",
    "mirror_id",
    "machine_family",
    "planner_version",
    "created_at",
    "strategy_summary",
    "passes"
  ],
  "properties": {
    "schema_version": {
      "type": "string",
      "const": "job.v1"
    },
    "job_id": {
      "type": "string",
      "description": "Stable unique identifier for this job."
    },
    "mirror_id": {
      "type": "string"
    },
    "machine_family": {
      "type": "string",
      "description": "Target machine family (e.g. swing-arm)."
    },
    "source_map_id": {
      "type": "string",
      "description": "Reference to the input surface measurement."
    },
    "target_id": {
      "type": "string",
      "description": "Reference to the target surface specification."
    },
    "created_at": {
      "type": "string",
      "format": "date-time"
    },
    "created_by": {
      "type": "string"
    },
    "planner_version": {
      "type": "string",
      "description": "Software version of polisher-sim that generated this job."
    },
    "calibration_state_ref": {
      "type": "string",
      "description": "Reference to the calibration state used during planning."
    },
    "strategy_summary": {
      "type": "object",
      "required": [
        "intent"
      ],
      "properties": {
        "intent": {
          "type": "string"
        },
        "confidence": {
          "type": "number",
          "minimum": 0,
          "maximum": 1
        },
        "notes": {
          "type": "string"
        }
      }
    },
    "passes": {
      "type": "array",
      "minItems": 1,
      "items": {
        "$ref": "#/$defs/pass"
      }
    },
    "predicted_outcome": {
      "type": "object",
      "description": "Summary of predicted post-polish surface state.",
      "properties": {
        "removal_rms_nm": {
          "type": "number"
        },
        "removal_pv_nm": {
          "type": "number"
        },
        "residual_zernikes": {
          "type": "object",
          "additionalProperties": {
            "type": "number"
          }
        }
      }
    },
    "uncertainty": {
      "type": "object",
      "description": "Planner's uncertainty estimates.",
      "properties": {
        "removal_rms_nm_range": {
          "type": "array",
          "items": {
            "type": "number"
          },
          "minItems": 2,
          "maxItems": 2
        },
        "notes": {
          "type": "string"
        }
      }
    },
    "attachments": {
      "type": "array",
      "items": {
        "type": "object",
        "required": [
          "filename",
          "role"
        ],
        "properties": {
          "filename": {
            "type": "string"
          },
          "role": {
            "type": "string"
          },
          "description": {
            "type": "string"
          }
        }
      }
    }
  },
  "$defs": {
    "pass": {
      "type": "object",
      "required": [
        "pass_id",
        "sequence_index",
        "duration_s",
        "force_n",
        "table_rpm",
        "spindle_rpm",
        "spindle_direction",
        "motion_family"
      ],
      "properties": {
        "pass_id": {
          "type": "string"
        },
        "sequence_index": {
          "type": "integer",
          "minimum": 1
        },
        "objective": {
          "type": "string"
        },
        "preset_name": {
          "type": "string"
        },
        "duration_s": {
          "type": "number",
          "minimum": 0
        },
        "force_n": {
          "type": "number",
          "minimum": 0
        },
        "table_rpm": {
          "type": "number",
          "minimum": 0
        },
        "spindle_rpm": {
          "type": "number",
          "minimum": 0
        },
        "motion_family": {
          "type": "string"
        },
        "motion_params": {
          "type": "object",
          "additionalProperties": true
        },
        "zone": {
          "type": "string"
        },
        "dither_profile": {
          "type": "string"
        },
        "force_modulation": {
          "type": "object",
          "properties": {
            "harmonic": {
              "type": "integer"
            },
            "amplitude_n": {
              "type": "number"
            },
            "phase_deg": {
              "type": "number"
            }
          }
        },
        "acceptance": {
          "type": "object",
          "additionalProperties": true
        },
        "notes": {
          "type": "string"
        },
        "spindle_direction": {
          "type": "string",
          "enum": [
            "cw",
            "ccw"
          ],
          "description": "Requested toolhead spindle rotation direction using the same physical convention as polisher-control."
        }
      }
    }
  }
}
