{
  "schema": "cad-aspen-drawing-contract/v1",
  "title": "CAD JSON 绘图数据约定规则",
  "language": "zh-CN",
  "purpose": "供 AI、PFD 自动布图程序和 DXF/DWG 重建程序读取；不在 CAD 图块网页中视觉展示。",
  "version": "1.4.0",
  "human_documentation_url": "/cad-api/",
  "machine_guide_url": "/api/v1/cad-guide.json",
  "openapi_url": "/api/v1/cad-openapi.json",
  "catalog_url": "/api/v1/cad-blocks",
  "block_url_template": "/api/v1/cad-blocks/{template_id}",
  "ports_url_template": "/api/v1/cad-blocks/{template_id}/ports",
  "occupancy_url_template": "/api/v1/cad-blocks/{template_id}/occupancy",
  "placement_url_template": "/api/v1/cad-blocks/{template_id}/placement",
  "equipment_occupancy_schema_url": "/api/v1/equipment-occupancy-schema.json",
  "rules": [
    {
      "id": "manual_port_definition",
      "title": "Manual port definition",
      "requirement": "When connection_ports.status is needs_manual_definition, ports must be empty and connectable must be false. Do not infer inN/outN from equipment category, bounding box, or shape. Verified ports store local coordinates relative to insertion_base_local."
    },
    {
      "id": "local_coordinates",
      "title": "局部坐标与基点",
      "requirement": "实体几何使用图块局部坐标。插入时以 insertion_base_local 为基点，平移、缩放和旋转必须统一叠加。"
    },
    {
      "id": "reference_insertion_point",
      "title": "插入基点可视化",
      "requirement": "reference_insertion_point.local 与 insertion_base_local 使用同一局部坐标系。source_anchor 说明其来自 DWG $INSBASE、原生块定义基点或本地锚点；web_preview.marker 为 pulsing_red_dot 时，网页画布仅以红色呼吸点示意该位置，不得把它导出为 CAD 图元或工艺端口。"
    },
    {
      "id": "entity_and_style",
      "title": "实体与图层样式",
      "requirement": "保留实体类型、几何、图层、线型、线宽、透明度及颜色规则；BYLAYER 与 BYBLOCK 按继承关系解析。可选 entities[].rendering.fill 明确经审图确认的封闭图元填充或遮罩，渲染器须先填充再描边，不得从画布主题自行推断。"
    },
    {
      "id": "ports_and_routing",
      "title": "工艺端口与布线",
      "requirement": "仅 connectable 为 true 的块可接线。管线从 connection_ports.ports[].local 起算，并沿 normal 确定首段方向。"
    },
    {
      "id": "configurable_connections",
      "title": "可配置进出口实例",
      "requirement": "调用方必须先从 Aspen 设备拓扑统计目标设备实际 inlet_count 与 outlet_count，并在同一次实例请求中成对提供；服务端不推测数量。connection_configuration/v2 为每个稳定 port_uid 维护选择优先级及 geometry_binding.entity_handles。服务端按请求数量启用端口，并据绑定关系保留匹配图元、移除未启用端口的独占图元；共享图元在任一引用端口启用时保留，空关联端口只移除端口而保留设备几何。响应重新计算 entity_count、bounds_local 与 equipment_occupancy_frame，实例不得覆盖母模板。"
    },
    {
      "id": "equipment_occupancy",
      "title": "设备紧致占位框",
      "requirement": "equipment_symbol 必须提供 equipment_occupancy_frame。limits_from_insertion_base 是相对 insertion_base_local 的零留白上下左右极限；size 用于初始布图。缩放或旋转后必须变换四角并重新求世界 AABB，不能直接平移 bounds_local。"
    },
    {
      "id": "nested_blocks",
      "title": "嵌套块复现",
      "requirement": "存在 nested_block_dependencies 时，递归读取子块并叠加父块变换；不得以截图或占位图替换嵌套几何。"
    },
    {
      "id": "component_visibility",
      "title": "组件显示元数据",
      "requirement": "display_components 以 entity_handles 和 port_ids 定义网页预览的可选组成部分；勾选只改变预览可见性，不得改写原始 CAD 图元、端口坐标或自动出图数据。"
    },
    {
      "id": "drawing_frame",
      "title": "图框与布图边界",
      "requirement": "DrawingFrame_01.drawing_regions 定义可画区和标题栏禁区；自动布图不得占用禁区。"
    },
    {
      "id": "review_and_delivery",
      "title": "审查与交付",
      "requirement": "端口带 review 或未确认状态时，最终出图前必须复核；交付保留可编辑 JSON、DXF 或 DWG，而非仅位图。"
    }
  ]
}