{
  "openapi": "3.1.0",
  "info": {
    "title": "ifc-edit-service",
    "version": "0.1.0"
  },
  "paths": {
    "/models/{id}/entities/{guid}": {
      "put": {
        "summary": "Put Entity",
        "description": "Apply edits to the in-memory model and record a pending change.",
        "operationId": "put_entity_models__id__entities__guid__put",
        "parameters": [
          {
            "name": "id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "pattern": "^m_[0-9a-f]{16}$",
              "title": "Id"
            }
          },
          {
            "name": "guid",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "title": "Guid"
            }
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/EditBody"
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Successful Response",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "additionalProperties": true,
                  "title": "Response Put Entity Models  Id  Entities  Guid  Put"
                }
              }
            }
          },
          "422": {
            "description": "Validation Error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/HTTPValidationError"
                }
              }
            }
          }
        }
      }
    },
    "/models/{id}/pending": {
      "get": {
        "summary": "Get Pending",
        "description": "List the current pending changes for a model.",
        "operationId": "get_pending_models__id__pending_get",
        "parameters": [
          {
            "name": "id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "pattern": "^m_[0-9a-f]{16}$",
              "title": "Id"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Successful Response",
            "content": {
              "application/json": {
                "schema": {
                  "type": "array",
                  "items": {
                    "type": "object",
                    "additionalProperties": true
                  },
                  "title": "Response Get Pending Models  Id  Pending Get"
                }
              }
            }
          },
          "422": {
            "description": "Validation Error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/HTTPValidationError"
                }
              }
            }
          }
        }
      },
      "delete": {
        "summary": "Discard Pending",
        "description": "Discard pending changes: reload the in-memory model from disk.",
        "operationId": "discard_pending_models__id__pending_delete",
        "parameters": [
          {
            "name": "id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "pattern": "^m_[0-9a-f]{16}$",
              "title": "Id"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Successful Response",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "additionalProperties": true,
                  "title": "Response Discard Pending Models  Id  Pending Delete"
                }
              }
            }
          },
          "422": {
            "description": "Validation Error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/HTTPValidationError"
                }
              }
            }
          }
        }
      }
    },
    "/models/{id}/commit": {
      "post": {
        "summary": "Commit Pending",
        "description": "Atomically save all pending changes to disk and append them to history.\n\nThe first commit snapshots the original upload as ``v1`` before saving;\nevery commit snapshots the newly saved file as the next version. The\noptional body stamps ``operation`` onto the committed entries (default\n``update``; Go's override migration passes ``migrate``).",
        "operationId": "commit_pending_models__id__commit_post",
        "parameters": [
          {
            "name": "id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "pattern": "^m_[0-9a-f]{16}$",
              "title": "Id"
            }
          }
        ],
        "requestBody": {
          "content": {
            "application/json": {
              "schema": {
                "anyOf": [
                  {
                    "$ref": "#/components/schemas/CommitBody"
                  },
                  {
                    "type": "null"
                  }
                ],
                "title": "Body"
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Successful Response",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "additionalProperties": true,
                  "title": "Response Commit Pending Models  Id  Commit Post"
                }
              }
            }
          },
          "422": {
            "description": "Validation Error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/HTTPValidationError"
                }
              }
            }
          }
        }
      }
    },
    "/models/{id}/history": {
      "get": {
        "summary": "Get History",
        "description": "List the persisted edit history for a model.",
        "operationId": "get_history_models__id__history_get",
        "parameters": [
          {
            "name": "id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "pattern": "^m_[0-9a-f]{16}$",
              "title": "Id"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Successful Response",
            "content": {
              "application/json": {
                "schema": {
                  "type": "array",
                  "items": {
                    "type": "object",
                    "additionalProperties": true
                  },
                  "title": "Response Get History Models  Id  History Get"
                }
              }
            }
          },
          "422": {
            "description": "Validation Error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/HTTPValidationError"
                }
              }
            }
          }
        }
      }
    },
    "/models/{id}/versions": {
      "get": {
        "summary": "Get Versions",
        "description": "List version snapshots for a model (empty + current=null before any commit).",
        "operationId": "get_versions_models__id__versions_get",
        "parameters": [
          {
            "name": "id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "pattern": "^m_[0-9a-f]{16}$",
              "title": "Id"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Successful Response",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "additionalProperties": true,
                  "title": "Response Get Versions Models  Id  Versions Get"
                }
              }
            }
          },
          "422": {
            "description": "Validation Error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/HTTPValidationError"
                }
              }
            }
          }
        }
      }
    },
    "/models/{id}/diff": {
      "post": {
        "summary": "Post Diff",
        "description": "Diff two model versions (or base version vs the current upload state).",
        "operationId": "post_diff_models__id__diff_post",
        "parameters": [
          {
            "name": "id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "pattern": "^m_[0-9a-f]{16}$",
              "title": "Id"
            }
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/DiffBody"
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Successful Response",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "additionalProperties": true,
                  "title": "Response Post Diff Models  Id  Diff Post"
                }
              }
            }
          },
          "422": {
            "description": "Validation Error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/HTTPValidationError"
                }
              }
            }
          }
        }
      }
    },
    "/models/{id}/script": {
      "get": {
        "summary": "Get Script",
        "description": "Return the current script (staged state, or last saved base).",
        "operationId": "get_script_models__id__script_get",
        "parameters": [
          {
            "name": "id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "pattern": "^m_[0-9a-f]{16}$",
              "title": "Id"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Successful Response",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "additionalProperties": true,
                  "title": "Response Get Script Models  Id  Script Get"
                }
              }
            }
          },
          "422": {
            "description": "Validation Error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/HTTPValidationError"
                }
              }
            }
          }
        }
      },
      "put": {
        "summary": "Stage Script",
        "description": "Stage a script edit: full replace, or params-only PARAMS-block rewrite.",
        "operationId": "stage_script_models__id__script_put",
        "parameters": [
          {
            "name": "id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "pattern": "^m_[0-9a-f]{16}$",
              "title": "Id"
            }
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/ScriptBody"
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Successful Response",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "additionalProperties": true,
                  "title": "Response Stage Script Models  Id  Script Put"
                }
              }
            }
          },
          "422": {
            "description": "Validation Error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/HTTPValidationError"
                }
              }
            }
          }
        }
      }
    },
    "/models/{id}/script/params": {
      "get": {
        "summary": "Get Script Params",
        "description": "Return the current script's PARAMS dict (ast extraction, no execution).",
        "operationId": "get_script_params_models__id__script_params_get",
        "parameters": [
          {
            "name": "id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "pattern": "^m_[0-9a-f]{16}$",
              "title": "Id"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Successful Response",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "additionalProperties": true,
                  "title": "Response Get Script Params Models  Id  Script Params Get"
                }
              }
            }
          },
          "422": {
            "description": "Validation Error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/HTTPValidationError"
                }
              }
            }
          }
        }
      }
    },
    "/models/{id}/script/undo": {
      "post": {
        "summary": "Undo Script",
        "operationId": "undo_script_models__id__script_undo_post",
        "parameters": [
          {
            "name": "id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "pattern": "^m_[0-9a-f]{16}$",
              "title": "Id"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Successful Response",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "additionalProperties": true,
                  "title": "Response Undo Script Models  Id  Script Undo Post"
                }
              }
            }
          },
          "422": {
            "description": "Validation Error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/HTTPValidationError"
                }
              }
            }
          }
        }
      }
    },
    "/models/{id}/script/redo": {
      "post": {
        "summary": "Redo Script",
        "operationId": "redo_script_models__id__script_redo_post",
        "parameters": [
          {
            "name": "id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "pattern": "^m_[0-9a-f]{16}$",
              "title": "Id"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Successful Response",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "additionalProperties": true,
                  "title": "Response Redo Script Models  Id  Script Redo Post"
                }
              }
            }
          },
          "422": {
            "description": "Validation Error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/HTTPValidationError"
                }
              }
            }
          }
        }
      }
    },
    "/models/{id}/script/discard": {
      "post": {
        "summary": "Discard Script",
        "description": "Throw staged edits away; back to the last saved big version. No version.",
        "operationId": "discard_script_models__id__script_discard_post",
        "parameters": [
          {
            "name": "id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "pattern": "^m_[0-9a-f]{16}$",
              "title": "Id"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Successful Response",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "additionalProperties": true,
                  "title": "Response Discard Script Models  Id  Script Discard Post"
                }
              }
            }
          },
          "422": {
            "description": "Validation Error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/HTTPValidationError"
                }
              }
            }
          }
        }
      }
    },
    "/models/{id}/script/run": {
      "post": {
        "summary": "Run Script Endpoint",
        "description": "Sandbox-run the current staged script into uploads (preview; no version).",
        "operationId": "run_script_endpoint_models__id__script_run_post",
        "parameters": [
          {
            "name": "id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "pattern": "^m_[0-9a-f]{16}$",
              "title": "Id"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Successful Response",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "additionalProperties": true,
                  "title": "Response Run Script Endpoint Models  Id  Script Run Post"
                }
              }
            }
          },
          "422": {
            "description": "Validation Error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/HTTPValidationError"
                }
              }
            }
          }
        }
      }
    },
    "/models/{id}/script/save": {
      "post": {
        "summary": "Save Script",
        "description": "Promote the staged script to a big version (run → snapshot script+IFC).\n\nA failed sandbox run → 422 and no version; staging is preserved so the\nscript can be fixed and saved again.",
        "operationId": "save_script_models__id__script_save_post",
        "parameters": [
          {
            "name": "id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "pattern": "^m_[0-9a-f]{16}$",
              "title": "Id"
            }
          }
        ],
        "requestBody": {
          "content": {
            "application/json": {
              "schema": {
                "anyOf": [
                  {
                    "$ref": "#/components/schemas/SaveBody"
                  },
                  {
                    "type": "null"
                  }
                ],
                "title": "Body"
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Successful Response",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "additionalProperties": true,
                  "title": "Response Save Script Models  Id  Script Save Post"
                }
              }
            }
          },
          "422": {
            "description": "Validation Error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/HTTPValidationError"
                }
              }
            }
          }
        }
      }
    },
    "/models/{id}/scripts": {
      "get": {
        "summary": "List Scripts",
        "description": "List script big versions (empty for legacy IFC-only models).",
        "operationId": "list_scripts_models__id__scripts_get",
        "parameters": [
          {
            "name": "id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "pattern": "^m_[0-9a-f]{16}$",
              "title": "Id"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Successful Response",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "additionalProperties": true,
                  "title": "Response List Scripts Models  Id  Scripts Get"
                }
              }
            }
          },
          "422": {
            "description": "Validation Error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/HTTPValidationError"
                }
              }
            }
          }
        }
      }
    },
    "/models/{id}/script/rollback": {
      "post": {
        "summary": "Rollback Script",
        "description": "Restore a big version's script into staging and re-run it into uploads.",
        "operationId": "rollback_script_models__id__script_rollback_post",
        "parameters": [
          {
            "name": "id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "pattern": "^m_[0-9a-f]{16}$",
              "title": "Id"
            }
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/RollbackBody"
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Successful Response",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "additionalProperties": true,
                  "title": "Response Rollback Script Models  Id  Script Rollback Post"
                }
              }
            }
          },
          "422": {
            "description": "Validation Error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/HTTPValidationError"
                }
              }
            }
          }
        }
      }
    },
    "/models/{id}/script/diff": {
      "post": {
        "summary": "Diff Script Versions",
        "description": "Big-version script diff: unified text diff + PARAMS changes + stats.\n\nThis is the primary AI-facing diff (the retired design-JSON diff's\nreplacement); the IFC semantic diff stays at POST /models/{id}/diff.",
        "operationId": "diff_script_versions_models__id__script_diff_post",
        "parameters": [
          {
            "name": "id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "pattern": "^m_[0-9a-f]{16}$",
              "title": "Id"
            }
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/ScriptDiffBody"
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Successful Response",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "additionalProperties": true,
                  "title": "Response Diff Script Versions Models  Id  Script Diff Post"
                }
              }
            }
          },
          "422": {
            "description": "Validation Error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/HTTPValidationError"
                }
              }
            }
          }
        }
      }
    },
    "/models/{id}/script/staging/diff": {
      "get": {
        "summary": "Diff Staging Steps",
        "description": "Small-version diff between two staging steps (default: the last two).\n\nStep indices address the staged states ``history[0..cursor]`` (0-based).\nLightweight inline text diff + PARAMS changes; visible to both AI and user.",
        "operationId": "diff_staging_steps_models__id__script_staging_diff_get",
        "parameters": [
          {
            "name": "id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "pattern": "^m_[0-9a-f]{16}$",
              "title": "Id"
            }
          },
          {
            "name": "from",
            "in": "query",
            "required": false,
            "schema": {
              "anyOf": [
                {
                  "type": "integer",
                  "minimum": 0
                },
                {
                  "type": "null"
                }
              ],
              "title": "From"
            }
          },
          {
            "name": "to",
            "in": "query",
            "required": false,
            "schema": {
              "anyOf": [
                {
                  "type": "integer",
                  "minimum": 0
                },
                {
                  "type": "null"
                }
              ],
              "title": "To"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Successful Response",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "additionalProperties": true,
                  "title": "Response Diff Staging Steps Models  Id  Script Staging Diff Get"
                }
              }
            }
          },
          "422": {
            "description": "Validation Error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/HTTPValidationError"
                }
              }
            }
          }
        }
      }
    },
    "/health": {
      "get": {
        "summary": "Health",
        "operationId": "health_health_get",
        "responses": {
          "200": {
            "description": "Successful Response",
            "content": {
              "application/json": {
                "schema": {
                  "additionalProperties": true,
                  "type": "object",
                  "title": "Response Health Health Get"
                }
              }
            }
          }
        }
      }
    }
  },
  "components": {
    "schemas": {
      "CommitBody": {
        "properties": {
          "operation": {
            "type": "string",
            "enum": [
              "update",
              "migrate"
            ],
            "title": "Operation",
            "default": "update"
          }
        },
        "type": "object",
        "title": "CommitBody",
        "description": "Optional body of POST /models/{id}/commit."
      },
      "DiffBody": {
        "properties": {
          "base": {
            "type": "string",
            "title": "Base"
          },
          "target": {
            "type": "string",
            "title": "Target"
          }
        },
        "type": "object",
        "required": [
          "base",
          "target"
        ],
        "title": "DiffBody",
        "description": "Body of POST /models/{id}/diff. target also accepts \"current\"."
      },
      "EditBody": {
        "properties": {
          "fields": {
            "additionalProperties": true,
            "type": "object",
            "title": "Fields"
          },
          "psets": {
            "additionalProperties": {
              "additionalProperties": true,
              "type": "object"
            },
            "type": "object",
            "title": "Psets"
          },
          "author": {
            "type": "string",
            "title": "Author",
            "default": "local-user"
          },
          "provenance": {
            "$ref": "#/components/schemas/Provenance"
          }
        },
        "type": "object",
        "title": "EditBody",
        "description": "Body of PUT /models/{id}/entities/{guid}."
      },
      "HTTPValidationError": {
        "properties": {
          "detail": {
            "items": {
              "$ref": "#/components/schemas/ValidationError"
            },
            "type": "array",
            "title": "Detail"
          }
        },
        "type": "object",
        "title": "HTTPValidationError"
      },
      "Provenance": {
        "properties": {
          "source": {
            "type": "string",
            "enum": [
              "UI",
              "AI"
            ],
            "title": "Source",
            "default": "UI"
          }
        },
        "type": "object",
        "title": "Provenance",
        "description": "Who performed an edit: the web UI or an AI agent."
      },
      "RollbackBody": {
        "properties": {
          "version": {
            "type": "string",
            "pattern": "^v\\d+$",
            "title": "Version"
          }
        },
        "type": "object",
        "required": [
          "version"
        ],
        "title": "RollbackBody",
        "description": "Body of POST /models/{id}/script/rollback."
      },
      "SaveBody": {
        "properties": {
          "note": {
            "type": "string",
            "title": "Note",
            "default": ""
          }
        },
        "type": "object",
        "title": "SaveBody",
        "description": "Optional body of POST /models/{id}/script/save."
      },
      "ScriptBody": {
        "properties": {
          "script": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "title": "Script"
          },
          "params": {
            "anyOf": [
              {
                "additionalProperties": true,
                "type": "object"
              },
              {
                "type": "null"
              }
            ],
            "title": "Params"
          },
          "note": {
            "type": "string",
            "title": "Note",
            "default": ""
          }
        },
        "type": "object",
        "title": "ScriptBody",
        "description": "Body of PUT /models/{id}/script: exactly one of script / params."
      },
      "ScriptDiffBody": {
        "properties": {
          "base": {
            "type": "string",
            "pattern": "^v\\d+$",
            "title": "Base"
          },
          "target": {
            "type": "string",
            "pattern": "^v\\d+$",
            "title": "Target"
          }
        },
        "type": "object",
        "required": [
          "base",
          "target"
        ],
        "title": "ScriptDiffBody",
        "description": "Body of POST /models/{id}/script/diff: two big versions."
      },
      "ValidationError": {
        "properties": {
          "loc": {
            "items": {
              "anyOf": [
                {
                  "type": "string"
                },
                {
                  "type": "integer"
                }
              ]
            },
            "type": "array",
            "title": "Location"
          },
          "msg": {
            "type": "string",
            "title": "Message"
          },
          "type": {
            "type": "string",
            "title": "Error Type"
          },
          "input": {
            "title": "Input"
          },
          "ctx": {
            "type": "object",
            "title": "Context"
          }
        },
        "type": "object",
        "required": [
          "loc",
          "msg",
          "type"
        ],
        "title": "ValidationError"
      }
    }
  }
}
