{
  "version": "1.1.0",
  "updatedAt": "2026-07-20",
  "rules": [
    {
      "id": "guardrail.gelios.ontology_not_runtime_store",
      "severity": "error",
      "summary": "Ontology Core describes Gelios meanings and contracts only. It must not contain access/refresh tokens, raw messages, live positions, provider command text, hardware decrypt keys or bulk geometry.",
      "entityIds": ["gelios.integration", "gelios.telemetry_snapshot", "gelios.raw_telemetry_message", "gelios.position_fix", "gelios.command_template", "gelios.geozone"]
    },
    {
      "id": "guardrail.gelios.provider_auth_pair_not_capability_scope",
      "severity": "error",
      "summary": "Gelios provider authentication consists of access and refresh tokens only. Credential labels and safe-read classifications are workflow policy, not provider token scope; internal External Data Plane capabilities are not Gelios tokens.",
      "entityIds": ["gelios.integration", "gelios.access_scope", "gelios.collection_run"]
    },
    {
      "id": "guardrail.gelios.scope_precedes_collection",
      "severity": "error",
      "summary": "A Gelios safe-read collection run must process every valid entity returned for the bound credential and selected capability. Static unit allowlists and provider-group business filters are forbidden at collection boundary; consumer visibility is handled downstream.",
      "entityIds": ["gelios.integration", "gelios.access_scope", "gelios.collection_run", "gelios.unit", "gelios.unit_group"]
    },
    {
      "id": "guardrail.gelios.commands_are_red_domain",
      "severity": "error",
      "summary": "Command template catalogue is read-only data. Command dispatch, command group mutation, history purge and every send route are separate red-domain actions requiring explicit human confirmation and audit; ingestion and map rendering may never create them.",
      "entityIds": ["gelios.command_template", "gelios.command_group", "gelios.command_dispatch", "gelios.command_delivery", "gelios.command_audit"]
    },
    {
      "id": "guardrail.gelios.map_uses_stable_subjects",
      "severity": "error",
      "summary": "Cesium pins and labels must consume stable gelios.unit and normalized gelios.position_fix through map.moving_object. They must not use raw message IDs, transient Cesium entity IDs or provider credentials as map identity.",
      "entityIds": ["gelios.unit", "gelios.position_fix", "gelios.telemetry_snapshot", "map.moving_object", "map.pin", "map.label"]
    },
    {
      "id": "guardrail.gelios.monitoring_states_are_closed",
      "severity": "error",
      "summary": "Gelios monitoring state is a closed source-evidenced contract: signal_state is active or inactive; movement_state is moving or stopped. NDC L2, Data Products and Foundry must not add unknown, stale, freshness, GPS, position-quality, parked, no-position or aggregate operational-status values.",
      "entityIds": ["gelios.telemetry_snapshot", "gelios.signal_state", "gelios.movement_state", "gelios.operational_status", "map.state_facet", "map.style_profile"]
    },
    {
      "id": "guardrail.gelios.raw_and_pii_are_restricted",
      "severity": "warning",
      "summary": "IMEI/hardware identifiers, phone fields, precise addresses, raw params, custom fields and unclassified sensor values require explicit field policy before analytics, Studio or external exposure.",
      "entityIds": ["gelios.tracker_device", "gelios.position_fix", "gelios.telemetry_parameter", "gelios.custom_field", "gelios.sensor_reading"]
    },
    {
      "id": "guardrail.gelios.geometry_requires_bounded_loading",
      "severity": "warning",
      "summary": "Geozone and report-map loading must use explicit paging, filtering, volume limits, LOD and retention policy. The unpaged provider geozone response is not an acceptable realtime renderer contract.",
      "entityIds": ["gelios.geozone", "gelios.geozone_group", "gelios.collection_run", "map.zone", "map.visibility_rule"]
    },
    {
      "id": "guardrail.gelios.history_requires_cursor",
      "severity": "warning",
      "summary": "Any future history ingestion must be bounded by connection, credential-visible entity scope, time window, field policy and durable cursor. It must not turn a historical API family into an uncontrolled account dump.",
      "entityIds": ["gelios.collection_run", "gelios.ingestion_cursor", "gelios.raw_telemetry_message", "gelios.report_result"]
    }
  ],
  "blockedConflations": [
    ["gelios.integration", "gelios.access_scope"],
    ["gelios.unit", "gelios.tracker_device"],
    ["gelios.telemetry_snapshot", "gelios.raw_telemetry_message"],
    ["gelios.position_fix", "map.moving_object"],
    ["gelios.signal_state", "gelios.movement_state"],
    ["gelios.signal_state", "gelios.operational_status"],
    ["gelios.movement_state", "gelios.operational_status"],
    ["gelios.command_template", "gelios.command_dispatch"],
    ["gelios.command_dispatch", "gelios.command_delivery"],
    ["gelios.geozone", "map.zone"]
  ]
}
