{
  "$schema": "https://json-schema.org/draft/2020-12/schema",
  "$id": "https://github.com/kb4beast/coupon-hive/blob/main/skills/coupon-hive/references/watch-spec.schema.json",
  "title": "Coupon Hive WatchSpec",
  "description": "A user-confirmed, version-bound recurring offer watch.",
  "type": "object",
  "additionalProperties": false,
  "required": [
    "schema_version",
    "skill_version",
    "confirmation",
    "task_binding",
    "host_payload",
    "query",
    "scope",
    "economics",
    "accepted_offer_types",
    "conditions",
    "sources",
    "schedule",
    "notification",
    "status"
  ],
  "properties": {
    "schema_version": {
      "const": 1
    },
    "skill_version": {
      "const": "0.1.0"
    },
    "confirmation": {
      "type": "object",
      "additionalProperties": false,
      "required": [
        "confirmed_by_user",
        "confirmed_at",
        "watch_card_summary",
        "approved_spec_digest"
      ],
      "properties": {
        "confirmed_by_user": {
          "const": true
        },
        "confirmed_at": {
          "type": "string",
          "format": "date-time"
        },
        "watch_card_summary": {
          "type": "string",
          "minLength": 1,
          "maxLength": 4000
        },
        "approved_spec_digest": {
          "type": "string",
          "pattern": "^sha256:[0-9a-f]{64}$"
        }
      }
    },
    "task_binding": {
      "type": "object",
      "additionalProperties": false,
      "required": [
        "action",
        "existing_task_id"
      ],
      "properties": {
        "action": {
          "enum": [
            "create",
            "update"
          ]
        },
        "existing_task_id": {
          "type": [
            "string",
            "null"
          ],
          "minLength": 1,
          "maxLength": 300
        }
      }
    },
    "host_payload": {
      "type": "object",
      "additionalProperties": false,
      "required": [
        "task_title",
        "host_surface",
        "prompt_template_id",
        "recurring_prompt_sha256",
        "requested_lifecycle_actions"
      ],
      "properties": {
        "task_title": {
          "type": "string",
          "pattern": "^Coupon Hive — \\S(?:[^\\r\\n\\u0085\\u2028\\u2029]*\\S)?$",
          "minLength": 15,
          "maxLength": 120
        },
        "host_surface": {
          "enum": [
            "chatgpt_plugin",
            "codex_skill"
          ]
        },
        "prompt_template_id": {
          "const": "coupon-hive-recurring-v1"
        },
        "recurring_prompt_sha256": {
          "type": "string",
          "pattern": "^sha256:[0-9a-f]{64}$"
        },
        "requested_lifecycle_actions": {
          "type": "array",
          "maxItems": 1,
          "uniqueItems": true,
          "items": {
            "enum": [
              "pause",
              "resume"
            ]
          }
        }
      }
    },
    "query": {
      "type": "object",
      "additionalProperties": false,
      "required": [
        "description",
        "category",
        "variants",
        "condition"
      ],
      "properties": {
        "description": {
          "type": "string",
          "minLength": 1,
          "maxLength": 500
        },
        "category": {
          "enum": [
            "physical_goods",
            "free_public_event",
            "manufacturer_sample"
          ]
        },
        "variants": {
          "type": "array",
          "maxItems": 30,
          "items": {
            "type": "string",
            "maxLength": 100
          }
        },
        "condition": {
          "type": "array",
          "minItems": 1,
          "uniqueItems": true,
          "items": {
            "enum": [
              "new",
              "used",
              "refurbished",
              "open_box",
              "not_applicable"
            ]
          }
        }
      }
    },
    "scope": {
      "type": "object",
      "additionalProperties": false,
      "required": [
        "country_code",
        "currency",
        "location_precision",
        "locality",
        "online_allowed",
        "pickup_allowed",
        "deadline"
      ],
      "properties": {
        "country_code": {
          "type": "string",
          "pattern": "^[A-Z]{2}$"
        },
        "currency": {
          "type": "string",
          "pattern": "^[A-Z]{3}$"
        },
        "location_precision": {
          "enum": [
            "country",
            "region",
            "city",
            "postal_code"
          ]
        },
        "locality": {
          "type": [
            "string",
            "null"
          ],
          "maxLength": 120
        },
        "online_allowed": {
          "type": "boolean"
        },
        "pickup_allowed": {
          "type": "boolean"
        },
        "deadline": {
          "type": [
            "string",
            "null"
          ],
          "format": "date-time"
        }
      }
    },
    "economics": {
      "type": "object",
      "additionalProperties": false,
      "required": [
        "maximum_effective_price",
        "minimum_discount_percent",
        "free_definition"
      ],
      "properties": {
        "maximum_effective_price": {
          "type": [
            "number",
            "null"
          ],
          "minimum": 0,
          "maximum": 1000000000000
        },
        "minimum_discount_percent": {
          "type": [
            "number",
            "null"
          ],
          "minimum": 0,
          "maximum": 100
        },
        "free_definition": {
          "enum": [
            "free_now_only",
            "conditional_free_allowed",
            "not_applicable"
          ]
        }
      }
    },
    "accepted_offer_types": {
      "type": "array",
      "minItems": 1,
      "uniqueItems": true,
      "items": {
        "enum": [
          "price_drop",
          "public_coupon",
          "free_now",
          "free_with_purchase",
          "free_after_rebate",
          "bogo",
          "free_sample"
        ]
      }
    },
    "conditions": {
      "type": "object",
      "additionalProperties": false,
      "required": [
        "purchase_required",
        "rebate",
        "membership",
        "trial",
        "subscription_or_renewal",
        "account_required",
        "marketing_consent",
        "loyalty_points",
        "deposit_or_authorization_hold",
        "app_only",
        "new_customer",
        "eligibility_assertions"
      ],
      "properties": {
        "purchase_required": {
          "type": "boolean"
        },
        "rebate": {
          "type": "boolean"
        },
        "membership": {
          "type": "boolean"
        },
        "trial": {
          "const": false
        },
        "subscription_or_renewal": {
          "const": false
        },
        "account_required": {
          "type": "boolean"
        },
        "marketing_consent": {
          "type": "boolean"
        },
        "loyalty_points": {
          "type": "boolean"
        },
        "deposit_or_authorization_hold": {
          "type": "boolean"
        },
        "app_only": {
          "type": "boolean"
        },
        "new_customer": {
          "type": "boolean"
        },
        "eligibility_assertions": {
          "type": "array",
          "maxItems": 20,
          "items": {
            "type": "string",
            "maxLength": 100
          }
        }
      }
    },
    "sources": {
      "type": "object",
      "additionalProperties": false,
      "required": [
        "allowed_merchants",
        "blocked_merchants",
        "access_policy",
        "allow_unverified_leads",
        "maximum_queries_per_run",
        "maximum_sources_per_run"
      ],
      "properties": {
        "allowed_merchants": {
          "type": "array",
          "maxItems": 100,
          "items": {
            "type": "string",
            "maxLength": 200
          }
        },
        "blocked_merchants": {
          "type": "array",
          "maxItems": 100,
          "items": {
            "type": "string",
            "maxLength": 200
          }
        },
        "access_policy": {
          "const": "host_public_web_only"
        },
        "allow_unverified_leads": {
          "type": "boolean"
        },
        "maximum_queries_per_run": {
          "type": "integer",
          "minimum": 1,
          "maximum": 20
        },
        "maximum_sources_per_run": {
          "type": "integer",
          "minimum": 1,
          "maximum": 100
        }
      }
    },
    "schedule": {
      "type": "object",
      "additionalProperties": false,
      "required": [
        "frequency",
        "interval",
        "weekdays",
        "local_time",
        "minute",
        "day_of_month",
        "timezone",
        "quiet_hours",
        "ends_at",
        "maximum_runs"
      ],
      "properties": {
        "frequency": {
          "enum": [
            "hourly",
            "daily",
            "weekly",
            "monthly"
          ]
        },
        "interval": {
          "type": "integer",
          "minimum": 1,
          "maximum": 365
        },
        "weekdays": {
          "type": "array",
          "maxItems": 7,
          "uniqueItems": true,
          "items": {
            "enum": [
              "MO",
              "TU",
              "WE",
              "TH",
              "FR",
              "SA",
              "SU"
            ]
          }
        },
        "local_time": {
          "type": [
            "string",
            "null"
          ],
          "pattern": "^([01][0-9]|2[0-3]):[0-5][0-9]$"
        },
        "minute": {
          "type": [
            "integer",
            "null"
          ],
          "minimum": 0,
          "maximum": 59
        },
        "day_of_month": {
          "type": [
            "integer",
            "null"
          ],
          "minimum": 1,
          "maximum": 28
        },
        "timezone": {
          "type": "string",
          "pattern": "^(UTC|[A-Za-z_]+(?:/[A-Za-z0-9_+.-]+)+)$",
          "minLength": 1,
          "maxLength": 100
        },
        "quiet_hours": {
          "type": [
            "object",
            "null"
          ],
          "additionalProperties": false,
          "required": [
            "start",
            "end"
          ],
          "properties": {
            "start": {
              "type": "string",
              "pattern": "^([01][0-9]|2[0-3]):[0-5][0-9]$"
            },
            "end": {
              "type": "string",
              "pattern": "^([01][0-9]|2[0-3]):[0-5][0-9]$"
            }
          }
        },
        "ends_at": {
          "type": [
            "string",
            "null"
          ],
          "format": "date-time"
        },
        "maximum_runs": {
          "type": [
            "integer",
            "null"
          ],
          "minimum": 1,
          "maximum": 10000
        }
      }
    },
    "notification": {
      "type": "object",
      "additionalProperties": false,
      "required": [
        "events",
        "minimum_price_improvement",
        "minimum_percent_improvement",
        "expiry_warning_hours",
        "silent_when_unchanged",
        "include_digest"
      ],
      "properties": {
        "events": {
          "type": "array",
          "minItems": 1,
          "uniqueItems": true,
          "items": {
            "enum": [
              "new_verified_match",
              "price_threshold_crossed",
              "material_condition_changed",
              "expiry_warning"
            ]
          }
        },
        "minimum_price_improvement": {
          "type": [
            "number",
            "null"
          ],
          "exclusiveMinimum": 0,
          "maximum": 1000000000000
        },
        "minimum_percent_improvement": {
          "type": [
            "number",
            "null"
          ],
          "exclusiveMinimum": 0,
          "maximum": 100
        },
        "expiry_warning_hours": {
          "type": [
            "integer",
            "null"
          ],
          "minimum": 1,
          "maximum": 720
        },
        "silent_when_unchanged": {
          "const": true
        },
        "include_digest": {
          "type": "boolean"
        }
      }
    },
    "status": {
      "const": "confirmed"
    }
  },
  "allOf": [
    {
      "if": {
        "properties": {
          "schedule": {
            "properties": {
              "frequency": {
                "const": "weekly"
              }
            }
          }
        }
      },
      "then": {
        "properties": {
          "schedule": {
            "properties": {
              "weekdays": {
                "minItems": 1
              },
              "local_time": {
                "type": "string"
              },
              "minute": {
                "type": "null"
              },
              "day_of_month": {
                "type": "null"
              }
            }
          }
        }
      }
    },
    {
      "if": {
        "properties": {
          "schedule": {
            "properties": {
              "frequency": {
                "const": "monthly"
              }
            }
          }
        }
      },
      "then": {
        "properties": {
          "schedule": {
            "properties": {
              "weekdays": {
                "maxItems": 0
              },
              "local_time": {
                "type": "string"
              },
              "minute": {
                "type": "null"
              },
              "day_of_month": {
                "type": "integer"
              }
            }
          }
        }
      }
    },
    {
      "if": {
        "properties": {
          "schedule": {
            "properties": {
              "frequency": {
                "const": "daily"
              }
            }
          }
        }
      },
      "then": {
        "properties": {
          "schedule": {
            "properties": {
              "weekdays": {
                "maxItems": 0
              },
              "local_time": {
                "type": "string"
              },
              "minute": {
                "type": "null"
              },
              "day_of_month": {
                "type": "null"
              }
            }
          }
        }
      }
    },
    {
      "if": {
        "properties": {
          "schedule": {
            "properties": {
              "frequency": {
                "const": "hourly"
              }
            }
          }
        }
      },
      "then": {
        "properties": {
          "schedule": {
            "properties": {
              "weekdays": {
                "maxItems": 0
              },
              "local_time": {
                "type": "null"
              },
              "minute": {
                "type": "integer"
              },
              "day_of_month": {
                "type": "null"
              }
            }
          }
        }
      }
    },
    {
      "if": {
        "properties": {
          "task_binding": {
            "properties": {
              "action": {
                "const": "create"
              }
            }
          }
        }
      },
      "then": {
        "properties": {
          "task_binding": {
            "properties": {
              "existing_task_id": {
                "type": "null"
              }
            }
          },
          "host_payload": {
            "properties": {
              "requested_lifecycle_actions": {
                "maxItems": 0
              }
            }
          }
        }
      }
    },
    {
      "if": {
        "properties": {
          "task_binding": {
            "properties": {
              "action": {
                "const": "update"
              }
            }
          }
        }
      },
      "then": {
        "properties": {
          "task_binding": {
            "properties": {
              "existing_task_id": {
                "type": "string",
                "minLength": 1
              }
            }
          }
        }
      }
    },
    {
      "if": {
        "properties": {
          "economics": {
            "properties": {
              "free_definition": {
                "const": "free_now_only"
              }
            }
          }
        }
      },
      "then": {
        "properties": {
          "accepted_offer_types": {
            "items": {
              "const": "free_now"
            }
          }
        }
      }
    },
    {
      "if": {
        "properties": {
          "notification": {
            "properties": {
              "events": {
                "contains": {
                  "const": "price_threshold_crossed"
                }
              }
            }
          }
        }
      },
      "then": {
        "properties": {
          "notification": {
            "anyOf": [
              {
                "properties": {
                  "minimum_price_improvement": {
                    "type": "number"
                  }
                }
              },
              {
                "properties": {
                  "minimum_percent_improvement": {
                    "type": "number"
                  }
                }
              }
            ]
          }
        }
      }
    },
    {
      "if": {
        "properties": {
          "notification": {
            "properties": {
              "events": {
                "contains": {
                  "const": "expiry_warning"
                }
              }
            }
          }
        }
      },
      "then": {
        "properties": {
          "notification": {
            "properties": {
              "expiry_warning_hours": {
                "type": "integer"
              }
            }
          }
        }
      }
    }
  ]
}
