{
  "$schema": "https://json-schema.org/draft/2020-12/schema",
  "$id": "https://www.data-pulse.my/datapulse.schema.json",
  "title": "DataPulse MY dataset manifest",
  "type": "object",
  "required": [
    "$schema",
    "datasets"
  ],
  "properties": {
    "$schema": {
      "description": "Canonical manifest schema identifier, published at the www website origin. The retired GitHub Pages identifier stays accepted only so already-published manifests keep validating until their owner republishes; it is legacy compatibility, not a canonical URL.",
      "enum": [
        "https://www.data-pulse.my/datapulse.schema.json",
        "https://r3dz4r.github.io/datapulse-my/datapulse.schema.json"
      ]
    },
    "datasets": {
      "type": "array",
      "minItems": 1,
      "items": {
        "$ref": "#/$defs/dataset"
      }
    }
  },
  "additionalProperties": false,
  "$defs": {
    "healthStatus": {
      "description": "Dataset health statuses emitted by scripts/check.sh.",
      "type": "string",
      "enum": [
        "fresh",
        "aging",
        "stale",
        "discontinued",
        "degraded",
        "browser-dependent",
        "unreachable",
        "unknown",
        "unknown-freshness",
        "reference"
      ]
    },
    "dataset": {
      "type": "object",
      "required": [
        "id",
        "name",
        "source",
        "steward",
        "custodian",
        "url",
        "licence",
        "attribution",
        "refresh_frequency",
        "expected_record_count",
        "geo_coverage",
        "health_report",
        "namespace"
      ],
      "properties": {
        "id": {
          "type": "string",
          "minLength": 1
        },
        "canonical_id": {
          "description": "Canonical data.gov.my dataset identifier for this entry.",
          "type": "string",
          "minLength": 1,
          "pattern": "^[a-z0-9][a-z0-9_-]*$"
        },
        "series_code": {
          "description": "Stable code explicitly grouping datasets in the same canonical series.",
          "type": "string",
          "minLength": 1,
          "pattern": "^[a-z0-9][a-z0-9_-]*$"
        },
        "geography": {
          "description": "Exact catalogue geography key used for deterministic relationship matching.",
          "type": "string",
          "minLength": 1
        },
        "schema_id": {
          "description": "Stable identifier for an explicitly shared dataset schema.",
          "type": "string",
          "minLength": 1,
          "pattern": "^[a-z0-9][a-z0-9_.-]*$"
        },
        "supersedes": {
          "description": "Dataset ID or IDs explicitly replaced by this dataset.",
          "oneOf": [
            {
              "type": "string",
              "minLength": 1
            },
            {
              "type": "array",
              "minItems": 1,
              "uniqueItems": true,
              "items": {
                "type": "string",
                "minLength": 1
              }
            }
          ]
        },
        "data_type": {
          "description": "Dataset semantic type when date-based freshness does not apply.",
          "type": "string",
          "enum": [
            "reference"
          ]
        },
        "discontinued": {
          "description": "Operator-applied marker that the source has stopped publishing this dataset.",
          "type": "boolean",
          "default": false
        },
        "name": {
          "type": "string",
          "minLength": 1
        },
        "source": {
          "type": "string",
          "minLength": 1
        },
        "steward": {
          "type": "string",
          "minLength": 1
        },
        "custodian": {
          "description": "Stable publishing-agency ID resolved through custodians.json.",
          "type": "string",
          "minLength": 1,
          "pattern": "^[a-z0-9][a-z0-9_-]*$"
        },
        "url": {
          "type": "string",
          "format": "uri"
        },
        "vertical": {
          "description": "Opt in to the reviewed record-level evidence pipeline. Optional while vertical support is piloted.",
          "type": "boolean"
        },
        "record_evidence_schema": {
          "description": "Record-level evidence envelope version emitted for this vertical.",
          "type": "string",
          "const": "record-evidence/v1"
        },
        "record_source_url": {
          "description": "Raw tabular CSV URL ingested by the record evidence pipeline.",
          "type": "string",
          "format": "uri"
        },
        "licence": {
          "type": "string",
          "minLength": 1
        },
        "attribution": {
          "type": "string",
          "minLength": 1
        },
        "refresh_frequency": {
          "type": "string",
          "minLength": 1
        },
        "expected_record_count": {
          "type": [
            "integer",
            "null"
          ],
          "minimum": 0
        },
        "geo_coverage": {
          "type": "string",
          "minLength": 1
        },
        "health_report": {
          "type": "string",
          "pattern": "^data/[A-Za-z0-9_-]+\\.md$"
        },
        "namespace": {
          "type": "string",
          "enum": [
            "economy",
            "government_open_data",
            "environment",
            "weather",
            "healthcare",
            "financial",
            "transport",
            "other"
          ]
        },
        "real_status": {
          "description": "Observed upstream lifecycle state, independent of probe health.",
          "type": "string",
          "enum": [
            "live",
            "discontinued"
          ]
        },
        "verified_at": {
          "description": "Date the upstream lifecycle state was last verified.",
          "type": "string",
          "format": "date"
        },
        "attestation_ref": {
          "type": "string",
          "pattern": "^attestations/[0-9]{4}-[0-9]{2}-[0-9]{2}/[A-Za-z0-9_-]+\\.json$"
        },
        "methodology_version": {
          "type": "integer",
          "minimum": 1
        },
        "probe_note": {
          "description": "Operator note explaining a probe result or limitation.",
          "type": "string",
          "minLength": 1
        },
        "discontinued_reason": {
          "description": "Evidence for marking an upstream dataset discontinued.",
          "type": "string",
          "minLength": 1
        }
      },
      "additionalProperties": false
    }
  }
}
