{
  "$schema": "https://json-schema.org/draft/2020-12/schema",
  "$id": "https://raw.githubusercontent.com/QuEraComputing/bloqade-lanes/main/docs/src/arch/archspec-schema.json",
  "title": "ArchSpec",
  "description": "Architecture specification for the Bloqade quantum device. Describes the full hardware topology: words, zones (each owning a coordinate grid and intra-zone buses), inter-zone buses, entangling pairs, operational modes, optional AOD transport paths, and device capabilities. Rules that JSON Schema cannot express (uniform grid dimensions across zones, bus well-formedness, index ranges relative to other fields, zone bounding-box overlap) are enforced by ArchSpec::validate().",
  "type": "object",
  "required": [
    "version",
    "words",
    "zones",
    "zone_buses",
    "modes"
  ],
  "additionalProperties": false,
  "properties": {
    "version": {
      "description": "Arch spec format version as a \"major.minor\" string (e.g. \"2.0\"). Both major and minor components must fit in a u16 (0..65535).",
      "type": "string",
      "pattern": "^[0-9]{1,5}\\.[0-9]{1,5}$"
    },
    "words": {
      "description": "Word definitions (atom registers). A word's ID is its index in this array. All words must have the same number of sites, and every zone's grid must be able to position every word's sites.",
      "type": "array",
      "items": {
        "$ref": "#/$defs/Word"
      },
      "minItems": 1
    },
    "zones": {
      "description": "Logical zones. Each zone owns a coordinate grid and the site/word buses that operate within it. A zone's ID is its index in this array. All zones must have the same grid dimensions, and zone bounding boxes must not overlap in physical space.",
      "type": "array",
      "items": {
        "$ref": "#/$defs/Zone"
      },
      "minItems": 1
    },
    "zone_buses": {
      "description": "Inter-zone word buses. Each entry transports words across a zone boundary: every (src[i], dst[i]) pair must have different zone_ids. A bus's ID is its index in this array. Subject to the bus well-formedness rules (see Bus).",
      "type": "array",
      "items": {
        "$ref": "#/$defs/InterZoneBus"
      }
    },
    "modes": {
      "description": "Named operational modes. Each mode selects a subset of zones and defines the bitstring ordering used for measurement results.",
      "type": "array",
      "items": {
        "$ref": "#/$defs/Mode"
      }
    },
    "paths": {
      "description": "Optional list of AOD (Acousto-Optic Deflector) transport paths. Each path identifies a transport lane and gives the sequence of [x, y] waypoints atoms follow during that transport.",
      "type": "array",
      "items": {
        "$ref": "#/$defs/TransportPath"
      }
    },
    "feed_forward": {
      "description": "Whether the device supports mid-circuit measurement with classical feedback. When false (default), control flow and multiple measure instructions are rejected during bytecode validation.",
      "type": "boolean",
      "default": false
    },
    "atom_reloading": {
      "description": "Whether the device supports reloading atoms after the initial fill. When false (default), no fill instruction is allowed (initial_fill is separate and always permitted).",
      "type": "boolean",
      "default": false
    },
    "blockade_radius": {
      "description": "Optional Rydberg blockade radius in micrometers. Metadata associated with the architecture, typically used by consumers to interpret the entangling word pairs; no relationship between the pairs and the radius is enforced by the spec itself.",
      "type": "number"
    }
  },
  "$defs": {
    "Word": {
      "title": "Word",
      "description": "A word (atom register) consisting of sites positioned on the parent zone's grid. Words are the fundamental unit of the device topology. A word's ID is its index in the top-level words array.",
      "type": "object",
      "required": ["sites"],
      "additionalProperties": false,
      "properties": {
        "sites": {
          "description": "Site positions as [x_idx, y_idx] pairs. Each pair indexes into the zone grid's computed x and y coordinate arrays respectively. All words must have the same number of sites (sites_per_word).",
          "type": "array",
          "minItems": 1,
          "items": {
            "type": "array",
            "items": {
              "type": "integer",
              "minimum": 0
            },
            "minItems": 2,
            "maxItems": 2
          }
        }
      }
    },
    "Grid": {
      "title": "Grid",
      "description": "A 2D coordinate grid for positioning atom sites within a zone, defined by start positions and spacing values. Coordinates are computed as cumulative sums: x[i] = x_start + sum(x_spacing[0..i]). The number of grid points along each axis is len(spacing) + 1. Spacings must be non-negative. Physical positions are typically in micrometers (µm).",
      "type": "object",
      "required": ["x_start", "y_start", "x_spacing", "y_spacing"],
      "additionalProperties": false,
      "properties": {
        "x_start": {
          "description": "X-coordinate of the first grid point.",
          "type": "number"
        },
        "y_start": {
          "description": "Y-coordinate of the first grid point.",
          "type": "number"
        },
        "x_spacing": {
          "description": "Spacing between consecutive x-coordinates. The number of x grid points is len(x_spacing) + 1.",
          "type": "array",
          "items": {
            "type": "number"
          }
        },
        "y_spacing": {
          "description": "Spacing between consecutive y-coordinates. The number of y grid points is len(y_spacing) + 1.",
          "type": "array",
          "items": {
            "type": "number"
          }
        }
      }
    },
    "Bus": {
      "title": "Bus",
      "description": "A transport bus that maps source positions to destination positions via parallel arrays: src[i] -> dst[i]. For site buses, entries are site indices within a word; for word buses, they are word IDs. The bus's identity is determined by its position in the parent array. The src->dst relation must be well-formed: src entries unique, dst entries unique, and no cycles (including self-loops) — a bus is a set of explicit transports executed simultaneously as one AOD operation, never a permutation. Overlapping-but-acyclic relations (conveyor chains such as 0->1, 1->2) are legal. These relational constraints cannot be expressed in JSON Schema and are enforced by ArchSpec::validate().",
      "type": "object",
      "required": ["src", "dst"],
      "additionalProperties": false,
      "properties": {
        "src": {
          "description": "Source indices (site indices for site buses, word IDs for word buses).",
          "type": "array",
          "items": {
            "type": "integer",
            "minimum": 0
          }
        },
        "dst": {
          "description": "Destination indices. Must be the same length as src.",
          "type": "array",
          "items": {
            "type": "integer",
            "minimum": 0
          }
        }
      }
    },
    "InterZoneBus": {
      "title": "InterZoneBus",
      "description": "An inter-zone word bus mapping zone-qualified words via parallel arrays: src[i] -> dst[i]. Every pair must cross a zone boundary (src[i].zone_id != dst[i].zone_id). Subject to the same well-formedness rules as Bus (unique src entries, unique dst entries, acyclic src->dst relation).",
      "type": "object",
      "required": ["src", "dst"],
      "additionalProperties": false,
      "properties": {
        "src": {
          "description": "Zone-qualified source words.",
          "type": "array",
          "items": {
            "$ref": "#/$defs/ZonedWordRef"
          }
        },
        "dst": {
          "description": "Zone-qualified destination words. Must be the same length as src.",
          "type": "array",
          "items": {
            "$ref": "#/$defs/ZonedWordRef"
          }
        }
      }
    },
    "ZonedWordRef": {
      "title": "ZonedWordRef",
      "description": "A zone-qualified word reference for inter-zone bus entries.",
      "type": "object",
      "required": ["zone_id", "word_id"],
      "additionalProperties": false,
      "properties": {
        "zone_id": {
          "description": "Zone ID (index into the zones array).",
          "type": "integer",
          "minimum": 0,
          "maximum": 255
        },
        "word_id": {
          "description": "Word ID (index into the words array).",
          "type": "integer",
          "minimum": 0,
          "maximum": 65535
        }
      }
    },
    "Zone": {
      "title": "Zone",
      "description": "A logical zone owning a coordinate grid and the site/word buses that operate within it. A zone's ID is its index in the zones array.",
      "type": "object",
      "required": [
        "grid",
        "site_buses",
        "word_buses",
        "words_with_site_buses",
        "sites_with_word_buses"
      ],
      "additionalProperties": false,
      "properties": {
        "name": {
          "description": "Human-readable zone name. Defaults to the empty string when absent.",
          "type": "string",
          "default": ""
        },
        "grid": {
          "$ref": "#/$defs/Grid"
        },
        "site_buses": {
          "description": "Site buses that move atoms between sites within words of this zone. A bus's ID is its index in this array.",
          "type": "array",
          "items": {
            "$ref": "#/$defs/Bus"
          }
        },
        "word_buses": {
          "description": "Word buses that move atoms between words within this zone. A bus's ID is its index in this array.",
          "type": "array",
          "items": {
            "$ref": "#/$defs/Bus"
          }
        },
        "words_with_site_buses": {
          "description": "Word IDs (within this zone) that have site-bus transport capability. Every entry must be a valid word ID.",
          "type": "array",
          "items": {
            "type": "integer",
            "minimum": 0
          }
        },
        "sites_with_word_buses": {
          "description": "Site indices that participate in word-bus transport within this zone. These are the 'landing pad' positions within each word where atoms arrive/depart during word-bus moves. Every entry must be less than sites_per_word.",
          "type": "array",
          "items": {
            "type": "integer",
            "minimum": 0
          }
        },
        "entangling_pairs": {
          "description": "Word pairs [w_a, w_b] within this zone that are at blockade radius for CZ gates. Word IDs must be valid, a word must not pair with itself, and pairs must be unique (order-insensitive). A zone with no entangling pairs is a storage/low-connectivity zone. Defaults to empty when absent.",
          "type": "array",
          "default": [],
          "items": {
            "type": "array",
            "items": {
              "type": "integer",
              "minimum": 0
            },
            "minItems": 2,
            "maxItems": 2
          }
        }
      }
    },
    "Mode": {
      "title": "Mode",
      "description": "A named operational mode selecting a subset of zones and the measurement bitstring ordering.",
      "type": "object",
      "required": ["name", "zones", "bitstring_order"],
      "additionalProperties": false,
      "properties": {
        "name": {
          "description": "Human-readable mode name.",
          "type": "string"
        },
        "zones": {
          "description": "Zone IDs active in this mode. Every entry must reference a defined zone.",
          "type": "array",
          "items": {
            "type": "integer",
            "minimum": 0
          }
        },
        "bitstring_order": {
          "description": "Bit-to-location mapping for measurement results. Each entry is a LocationAddr encoded as a packed integer with bit layout [zone_id:8][word_id:16][site_id:16][pad:24] (most-significant first).",
          "type": "array",
          "items": {
            "type": "integer",
            "minimum": 0
          }
        }
      }
    },
    "TransportPath": {
      "title": "TransportPath",
      "description": "A transport path for a lane, defined as a sequence of (x, y) waypoints. The lane is identified by its encoded LaneAddr as a hex string.",
      "type": "object",
      "required": ["lane", "waypoints"],
      "additionalProperties": false,
      "properties": {
        "lane": {
          "description": "Encoded LaneAddr as a 16-digit hex string (e.g. '0x2000000000000000'). Low 32 bits: [word_id:16][site_id:16]; high 32 bits: [direction:1][move_type:2][zone_id:8][pad:5][bus_id:16].",
          "type": "string",
          "pattern": "^0[xX][0-9a-fA-F]{16}$"
        },
        "waypoints": {
          "description": "Sequence of [x, y] waypoints defining the physical trajectory atoms follow during transport. Must have at least 2 entries. Coordinates must be finite.",
          "type": "array",
          "minItems": 2,
          "items": {
            "type": "array",
            "items": {
              "type": "number"
            },
            "minItems": 2,
            "maxItems": 2
          }
        }
      }
    }
  }
}
