{
 "openapi": "3.1.0",
 "info": {
  "title": "reverser.space account API",
  "version": "1.2.0",
  "description": "The signed-in API behind app.reverser.space: sessions, uploads, analysis, sharing, collaboration and agents. Authenticate with POST /api/auth/login and send the returned token as 'Authorization: Bearer <token>' on every other call.\n\nAddresses: parameters take 0x-prefixed hex strings like 0x401000. Responses return addresses as decimal byte offsets (Ghidra offsets); the one exception is /triage, which returns 0x-prefixed hex strings ready to pass back.\n\nErrors are always {\"error\": \"...\"}. A session idle long enough reopens from its saved Ghidra project on the first request, which can take a few seconds.\n\nRoles: shared access grants are viewer or editor. The immutable catalog owner is returned as creator for compatibility; operations note the role they need. 401 no or bad token; 403 role too low; 404 also covers sessions you hold no grant on, which stay indistinguishable from ones that do not exist.\n\nA WebSocket at /api/s/{sid}/ws streams live session events; it is outside this spec, as is the owner-only /api/admin surface. The read-only share-link API is documented separately in /openapi.json."
 },
 "externalDocs": {
  "description": "Guide with worked examples",
  "url": "https://app.reverser.space/agent-api.html"
 },
 "servers": [
  {
   "url": "https://api.reverser.space"
  }
 ],
 "security": [
  {
   "bearerAuth": []
  }
 ],
 "paths": {
  "/api/account/plan": {
   "get": {
    "operationId": "getAccountPlan",
    "summary": "Get plan, renewal, workspace usage and durable-storage usage",
    "responses": {
     "200": {
      "description": "Current account entitlement and quotas",
      "content": {
       "application/json": {
        "schema": {
         "type": "object",
         "required": [
          "plan",
          "subscription",
          "workspaceUsedMs",
          "workspaceLimitMs",
          "storageUsedBytes",
          "storageLimitBytes"
         ],
         "properties": {
          "plan": {
           "type": "string",
           "enum": [
            "free",
            "pro"
           ]
          },
          "priceCents": {
           "type": "integer",
           "const": 1900
          },
          "subscription": {
           "type": "object",
           "properties": {
            "status": {
             "type": "string"
            },
            "periodStart": {
             "type": "integer"
            },
            "periodEnd": {
             "type": "integer"
            },
            "cancelAtPeriodEnd": {
             "type": "boolean"
            }
           }
          },
          "workspaceUsedMs": {
           "type": "integer"
          },
          "workspaceLimitMs": {
           "type": "integer"
          },
          "workspaceRemainingMs": {
           "type": "integer"
          },
          "storageUsedBytes": {
           "type": "integer"
          },
          "storageLimitBytes": {
           "type": "integer"
          },
          "canStartCompute": {
           "type": "boolean"
          },
          "canAddStorage": {
           "type": "boolean"
          },
          "checkoutAvailable": {
           "type": "boolean"
          }
         }
        }
       }
      }
     },
     "default": {
      "$ref": "#/components/responses/error"
     }
    }
   }
  },
  "/api/account/checkout": {
   "post": {
    "operationId": "createProCheckout",
    "summary": "Create a $19/month Pro Checkout session (no trial)",
    "responses": {
     "200": {
      "description": "Stripe-hosted redirect",
      "content": {
       "application/json": {
        "schema": {
         "type": "object",
         "required": [
          "url"
         ],
         "properties": {
          "url": {
           "type": "string",
           "format": "uri"
          }
         }
        }
       }
      }
     },
     "default": {
      "$ref": "#/components/responses/error"
     }
    }
   }
  },
  "/api/account/billing-portal": {
   "post": {
    "operationId": "createBillingPortal",
    "summary": "Create a Stripe customer-portal session",
    "responses": {
     "200": {
      "description": "Stripe-hosted redirect",
      "content": {
       "application/json": {
        "schema": {
         "type": "object",
         "required": [
          "url"
         ],
         "properties": {
          "url": {
           "type": "string",
           "format": "uri"
          }
         }
        }
       }
      }
     },
     "default": {
      "$ref": "#/components/responses/error"
     }
    }
   }
  },
  "/api/auth/login": {
   "post": {
    "operationId": "login",
    "summary": "Sign in; the returned token authenticates every other call",
    "security": [],
    "requestBody": {
     "required": true,
     "content": {
      "application/json": {
       "schema": {
        "$ref": "#/components/schemas/LoginRequest"
       }
      }
     }
    },
    "responses": {
     "200": {
      "description": "JSON result",
      "content": {
       "application/json": {
        "schema": {
         "$ref": "#/components/schemas/LoginResponse"
        }
       }
      }
     },
     "401": {
      "description": "Bad username or password",
      "content": {
       "application/json": {
        "schema": {
         "$ref": "#/components/schemas/Error"
        }
       }
      }
     },
     "default": {
      "$ref": "#/components/responses/error"
     }
    }
   }
  },
  "/api/auth/logout": {
   "post": {
    "operationId": "logout",
    "summary": "Revoke the current token",
    "responses": {
     "200": {
      "description": "JSON result",
      "content": {
       "application/json": {
        "schema": {
         "$ref": "#/components/schemas/Status"
        }
       }
      }
     },
     "default": {
      "$ref": "#/components/responses/error"
     },
     "401": {
      "$ref": "#/components/responses/unauthorized"
     }
    }
   }
  },
  "/api/auth/me": {
   "get": {
    "operationId": "me",
    "summary": "The signed-in account",
    "responses": {
     "200": {
      "description": "JSON result",
      "content": {
       "application/json": {
        "schema": {
         "$ref": "#/components/schemas/PublicUser"
        }
       }
      }
     },
     "default": {
      "$ref": "#/components/responses/error"
     },
     "401": {
      "$ref": "#/components/responses/unauthorized"
     }
    }
   }
  },
  "/api/sessions": {
   "get": {
    "operationId": "sessions",
    "summary": "Sessions this account can see, with its role on each",
    "responses": {
     "200": {
      "description": "JSON result",
      "content": {
       "application/json": {
        "schema": {
         "type": "array",
         "items": {
          "$ref": "#/components/schemas/SessionInfo"
         }
        }
       }
      }
     },
     "default": {
      "$ref": "#/components/responses/error"
     },
     "401": {
      "$ref": "#/components/responses/unauthorized"
     }
    }
   }
  },
  "/api/capacity": {
   "get": {
    "operationId": "capacity",
    "summary": "How full the gateway is, and this account's own allowance",
    "responses": {
     "200": {
      "description": "JSON result",
      "content": {
       "application/json": {
        "schema": {
         "$ref": "#/components/schemas/GatewayCapacity"
        }
       }
      }
     },
     "default": {
      "$ref": "#/components/responses/error"
     },
     "401": {
      "$ref": "#/components/responses/unauthorized"
     }
    }
   }
  },
  "/api/upload": {
   "post": {
    "operationId": "upload",
    "summary": "Upload a binary; creates a private session with this account as creator",
    "description": "Analysis does not start until POST /api/s/{sid}/analyze, so symbols can be attached first. Re-uploading identical bytes returns the existing session. An optional 'symbols' part stages a PDB alongside in one request.",
    "requestBody": {
     "required": true,
     "content": {
      "multipart/form-data": {
       "schema": {
        "type": "object",
        "properties": {
         "file": {
          "type": "string",
          "format": "binary"
         },
         "symbols": {
          "type": "string",
          "format": "binary",
          "description": "Optional PDB"
         }
        },
        "required": [
         "file"
        ]
       }
      }
     }
    },
    "responses": {
     "200": {
      "description": "JSON result",
      "content": {
       "application/json": {
        "schema": {
         "$ref": "#/components/schemas/SessionInfo"
        }
       }
      }
     },
     "400": {
      "$ref": "#/components/responses/badRequest"
     },
     "409": {
      "description": "This account holds as many binaries as it may",
      "content": {
       "application/json": {
        "schema": {
         "$ref": "#/components/schemas/Error"
        }
       }
      }
     },
     "413": {
      "description": "Larger than the gateway's per-file limit",
      "content": {
       "application/json": {
        "schema": {
         "$ref": "#/components/schemas/Error"
        }
       }
      }
     },
     "default": {
      "$ref": "#/components/responses/error"
     },
     "401": {
      "$ref": "#/components/responses/unauthorized"
     }
    }
   }
  },
  "/api/agents": {
   "get": {
    "operationId": "agents",
    "summary": "Agents this gateway offers",
    "responses": {
     "200": {
      "description": "JSON result",
      "content": {
       "application/json": {
        "schema": {
         "type": "array",
         "items": {
          "$ref": "#/components/schemas/PublicAgent"
         }
        }
       }
      }
     },
     "default": {
      "$ref": "#/components/responses/error"
     },
     "401": {
      "$ref": "#/components/responses/unauthorized"
     }
    }
   }
  },
  "/api/agent-key": {
   "get": {
    "operationId": "getAgentKey",
    "summary": "Whether this account has stored agent API keys (never the keys themselves)",
    "responses": {
     "200": {
      "description": "JSON result",
      "content": {
       "application/json": {
        "schema": {
         "$ref": "#/components/schemas/KeyStatus"
        }
       }
      }
     },
     "default": {
      "$ref": "#/components/responses/error"
     },
     "401": {
      "$ref": "#/components/responses/unauthorized"
     }
    }
   },
   "post": {
    "operationId": "setAgentKey",
    "summary": "Store a provider API key for this account's agent runs",
    "requestBody": {
     "required": true,
     "content": {
      "application/json": {
       "schema": {
        "$ref": "#/components/schemas/SetKeyRequest"
       }
      }
     }
    },
    "responses": {
     "200": {
      "description": "JSON result",
      "content": {
       "application/json": {
        "schema": {
         "$ref": "#/components/schemas/KeyStatus"
        }
       }
      }
     },
     "400": {
      "$ref": "#/components/responses/badRequest"
     },
     "default": {
      "$ref": "#/components/responses/error"
     },
     "401": {
      "$ref": "#/components/responses/unauthorized"
     }
    }
   },
   "delete": {
    "operationId": "deleteAgentKey",
    "summary": "Forget this account's stored key",
    "parameters": [
     {
      "name": "provider",
      "in": "query",
      "description": "Which provider's key to forget",
      "schema": {
       "type": "string",
       "enum": [
        "gemini",
        "openai"
       ]
      }
     }
    ],
    "responses": {
     "200": {
      "description": "JSON result",
      "content": {
       "application/json": {
        "schema": {
         "$ref": "#/components/schemas/KeyStatus"
        }
       }
      }
     },
     "default": {
      "$ref": "#/components/responses/error"
     },
     "401": {
      "$ref": "#/components/responses/unauthorized"
     }
    }
   }
  },
  "/api/autorun": {
   "get": {
    "operationId": "getAutorun",
    "summary": "This account's auto-run preference for new uploads",
    "responses": {
     "200": {
      "description": "JSON result",
      "content": {
       "application/json": {
        "schema": {
         "$ref": "#/components/schemas/AutorunSetting"
        }
       }
      }
     },
     "default": {
      "$ref": "#/components/responses/error"
     },
     "401": {
      "$ref": "#/components/responses/unauthorized"
     }
    }
   },
   "post": {
    "operationId": "setAutorun",
    "summary": "Run an agent automatically on each of this account's uploads",
    "requestBody": {
     "required": true,
     "content": {
      "application/json": {
       "schema": {
        "$ref": "#/components/schemas/AutorunSetting"
       }
      }
     }
    },
    "responses": {
     "200": {
      "description": "JSON result",
      "content": {
       "application/json": {
        "schema": {
         "$ref": "#/components/schemas/AutorunSetting"
        }
       }
      }
     },
     "400": {
      "$ref": "#/components/responses/badRequest"
     },
     "default": {
      "$ref": "#/components/responses/error"
     },
     "401": {
      "$ref": "#/components/responses/unauthorized"
     }
    }
   }
  },
  "/api/s/{sid}/open": {
   "post": {
    "operationId": "openSession",
    "summary": "Start opening the session once and report where it got to",
    "description": "Kicks an idle session into reopening and returns at once; poll GET /api/sessions until status is 'ready'. 409 when the binary has not been analysed yet (call analyze) or the last open failed.",
    "parameters": [
     {
      "$ref": "#/components/parameters/sid"
     }
    ],
    "responses": {
     "200": {
      "description": "JSON result",
      "content": {
       "application/json": {
        "schema": {
         "$ref": "#/components/schemas/SessionInfo"
        }
       }
      }
     },
     "404": {
      "$ref": "#/components/responses/notFound"
     },
     "409": {
      "description": "Not analysed yet, or the last open failed",
      "content": {
       "application/json": {
        "schema": {
         "$ref": "#/components/schemas/Error"
        }
       }
      }
     },
     "default": {
      "$ref": "#/components/responses/error"
     },
     "401": {
      "$ref": "#/components/responses/unauthorized"
     }
    }
   }
  },
  "/api/s/{sid}/ready": {
   "get": {
    "operationId": "openSessionLegacy",
    "summary": "Legacy alias for POST /api/s/{sid}/open",
    "description": "Kicks an idle session into reopening and returns at once; poll until status is 'ready'. 409 when the binary has not been analysed yet (call analyze) or the last open failed.",
    "parameters": [
     {
      "$ref": "#/components/parameters/sid"
     }
    ],
    "responses": {
     "200": {
      "description": "JSON result",
      "content": {
       "application/json": {
        "schema": {
         "$ref": "#/components/schemas/SessionInfo"
        }
       }
      }
     },
     "404": {
      "$ref": "#/components/responses/notFound"
     },
     "409": {
      "description": "Not analysed yet, or the last open failed",
      "content": {
       "application/json": {
        "schema": {
         "$ref": "#/components/schemas/Error"
        }
       }
      }
     },
     "default": {
      "$ref": "#/components/responses/error"
     },
     "401": {
      "$ref": "#/components/responses/unauthorized"
     }
    }
   }
  },
  "/api/s/{sid}/analyze": {
   "post": {
    "operationId": "analyze",
    "summary": "Start the one-time analysis of a pending binary (editor)",
    "description": "Idempotent: a session already analysing, ready or idle reports its state instead of erroring. Minutes of work for a large binary; poll GET /api/sessions for the analyzing to ready transition.",
    "parameters": [
     {
      "$ref": "#/components/parameters/sid"
     }
    ],
    "requestBody": {
     "required": false,
     "content": {
      "application/json": {
       "schema": {
        "$ref": "#/components/schemas/AnalyzeRequest"
       }
      }
     }
    },
    "responses": {
     "200": {
      "description": "JSON result",
      "content": {
       "application/json": {
        "schema": {
         "$ref": "#/components/schemas/SessionInfo"
        }
       }
      }
     },
     "400": {
      "$ref": "#/components/responses/badRequest"
     },
     "404": {
      "$ref": "#/components/responses/notFound"
     },
     "default": {
      "$ref": "#/components/responses/error"
     },
     "401": {
      "$ref": "#/components/responses/unauthorized"
     }
    }
   }
  },
  "/api/s/{sid}/symbols": {
   "post": {
    "operationId": "stageSymbols",
    "summary": "Attach a PDB to a not-yet-analysed session (editor)",
    "parameters": [
     {
      "$ref": "#/components/parameters/sid"
     }
    ],
    "requestBody": {
     "required": true,
     "content": {
      "multipart/form-data": {
       "schema": {
        "type": "object",
        "properties": {
         "file": {
          "type": "string",
          "format": "binary"
         }
        },
        "required": [
         "file"
        ]
       }
      }
     }
    },
    "responses": {
     "200": {
      "description": "JSON result",
      "content": {
       "application/json": {
        "schema": {
         "$ref": "#/components/schemas/StageSymbolsResult"
        }
       }
      }
     },
     "400": {
      "$ref": "#/components/responses/badRequest"
     },
     "404": {
      "$ref": "#/components/responses/notFound"
     },
     "default": {
      "$ref": "#/components/responses/error"
     },
     "401": {
      "$ref": "#/components/responses/unauthorized"
     }
    }
   },
   "delete": {
    "operationId": "unstageSymbols",
    "summary": "Take back a staged PDB before analysis bakes it in (editor)",
    "parameters": [
     {
      "$ref": "#/components/parameters/sid"
     }
    ],
    "responses": {
     "200": {
      "description": "JSON result",
      "content": {
       "application/json": {
        "schema": {
         "$ref": "#/components/schemas/Status"
        }
       }
      }
     },
     "404": {
      "$ref": "#/components/responses/notFound"
     },
     "409": {
      "description": "Already analysed; the symbols can't be detached",
      "content": {
       "application/json": {
        "schema": {
         "$ref": "#/components/schemas/Error"
        }
       }
      }
     },
     "default": {
      "$ref": "#/components/responses/error"
     },
     "401": {
      "$ref": "#/components/responses/unauthorized"
     }
    }
   },
   "get": {
    "operationId": "symbols",
    "summary": "Every symbol with address, binding and type",
    "parameters": [
     {
      "$ref": "#/components/parameters/sid"
     }
    ],
    "responses": {
     "200": {
      "description": "JSON result",
      "content": {
       "application/json": {
        "schema": {
         "type": "array",
         "items": {
          "$ref": "#/components/schemas/Symbol"
         }
        }
       }
      }
     },
     "404": {
      "$ref": "#/components/responses/notFound"
     },
     "default": {
      "$ref": "#/components/responses/error"
     },
     "401": {
      "$ref": "#/components/responses/unauthorized"
     }
    }
   }
  },
  "/api/s/{sid}/download": {
   "get": {
    "operationId": "download",
    "summary": "The original uploaded binary",
    "parameters": [
     {
      "$ref": "#/components/parameters/sid"
     }
    ],
    "responses": {
     "200": {
      "description": "The binary itself",
      "content": {
       "application/octet-stream": {
        "schema": {
         "type": "string",
         "format": "binary"
        }
       }
      }
     },
     "403": {
      "description": "Downloads are disabled on this gateway",
      "content": {
       "application/json": {
        "schema": {
         "$ref": "#/components/schemas/Error"
        }
       }
      }
     },
     "404": {
      "$ref": "#/components/responses/notFound"
     },
     "default": {
      "$ref": "#/components/responses/error"
     },
     "401": {
      "$ref": "#/components/responses/unauthorized"
     }
    }
   }
  },
  "/api/s/{sid}": {
   "delete": {
    "operationId": "deleteSession",
    "summary": "Delete the session, its uploads and its project (creator)",
    "parameters": [
     {
      "$ref": "#/components/parameters/sid"
     }
    ],
    "requestBody": {
     "required": true,
     "content": {
      "application/json": {
       "schema": {
        "$ref": "#/components/schemas/DeleteSessionRequest"
       }
      }
     }
    },
    "responses": {
     "200": {
      "description": "JSON result",
      "content": {
       "application/json": {
        "schema": {
         "$ref": "#/components/schemas/Status"
        }
       }
      }
     },
     "400": {
      "$ref": "#/components/responses/badRequest"
     },
     "404": {
      "$ref": "#/components/responses/notFound"
     },
     "409": {
      "description": "Refused: someone is connected, or it is still analysing",
      "content": {
       "application/json": {
        "schema": {
         "$ref": "#/components/schemas/Error"
        }
       }
      }
     },
     "default": {
      "$ref": "#/components/responses/error"
     },
     "401": {
      "$ref": "#/components/responses/unauthorized"
     }
    }
   }
  },
  "/api/s/{sid}/share": {
   "get": {
    "operationId": "getShare",
    "summary": "The session's share token, if any (editor)",
    "parameters": [
     {
      "$ref": "#/components/parameters/sid"
     }
    ],
    "responses": {
     "200": {
      "description": "JSON result",
      "content": {
       "application/json": {
        "schema": {
         "$ref": "#/components/schemas/ShareResponse"
        }
       }
      }
     },
     "404": {
      "$ref": "#/components/responses/notFound"
     },
     "default": {
      "$ref": "#/components/responses/error"
     },
     "401": {
      "$ref": "#/components/responses/unauthorized"
     }
    }
   },
   "post": {
    "operationId": "createShare",
    "summary": "Mint a fresh read-only share token, replacing any existing one (editor)",
    "parameters": [
     {
      "$ref": "#/components/parameters/sid"
     }
    ],
    "responses": {
     "200": {
      "description": "JSON result",
      "content": {
       "application/json": {
        "schema": {
         "$ref": "#/components/schemas/ShareResponse"
        }
       }
      }
     },
     "404": {
      "$ref": "#/components/responses/notFound"
     },
     "default": {
      "$ref": "#/components/responses/error"
     },
     "401": {
      "$ref": "#/components/responses/unauthorized"
     }
    }
   },
   "delete": {
    "operationId": "revokeShare",
    "summary": "Revoke the share token (editor)",
    "parameters": [
     {
      "$ref": "#/components/parameters/sid"
     }
    ],
    "responses": {
     "200": {
      "description": "JSON result",
      "content": {
       "application/json": {
        "schema": {
         "$ref": "#/components/schemas/Status"
        }
       }
      }
     },
     "404": {
      "$ref": "#/components/responses/notFound"
     },
     "default": {
      "$ref": "#/components/responses/error"
     },
     "401": {
      "$ref": "#/components/responses/unauthorized"
     }
    }
   }
  },
  "/api/s/{sid}/access": {
   "get": {
    "operationId": "listAccess",
    "summary": "Who holds a grant on this session",
    "parameters": [
     {
      "$ref": "#/components/parameters/sid"
     }
    ],
    "responses": {
     "200": {
      "description": "JSON result",
      "content": {
       "application/json": {
        "schema": {
         "type": "array",
         "items": {
          "$ref": "#/components/schemas/AccessEntry"
         }
        }
       }
      }
     },
     "404": {
      "$ref": "#/components/responses/notFound"
     },
     "default": {
      "$ref": "#/components/responses/error"
     },
     "401": {
      "$ref": "#/components/responses/unauthorized"
     }
    }
   },
   "post": {
    "operationId": "grantAccess",
    "summary": "Grant an account a role on this session (editor)",
    "parameters": [
     {
      "$ref": "#/components/parameters/sid"
     }
    ],
    "requestBody": {
     "required": true,
     "content": {
      "application/json": {
       "schema": {
        "$ref": "#/components/schemas/GrantAccessRequest"
       }
      }
     }
    },
    "responses": {
     "200": {
      "description": "JSON result",
      "content": {
       "application/json": {
        "schema": {
         "type": "array",
         "items": {
          "$ref": "#/components/schemas/AccessEntry"
         }
        }
       }
      }
     },
     "400": {
      "$ref": "#/components/responses/badRequest"
     },
     "404": {
      "$ref": "#/components/responses/notFound"
     },
     "default": {
      "$ref": "#/components/responses/error"
     },
     "401": {
      "$ref": "#/components/responses/unauthorized"
     }
    }
   }
  },
  "/api/s/{sid}/access/{uid}": {
   "delete": {
    "operationId": "revokeAccess",
    "summary": "Revoke an account's grant (editor; a creator's grant is protected)",
    "parameters": [
     {
      "$ref": "#/components/parameters/sid"
     },
     {
      "name": "uid",
      "in": "path",
      "required": true,
      "schema": {
       "type": "string"
      },
      "description": "Account id from the access list"
     }
    ],
    "responses": {
     "200": {
      "description": "JSON result",
      "content": {
       "application/json": {
        "schema": {
         "type": "array",
         "items": {
          "$ref": "#/components/schemas/AccessEntry"
         }
        }
       }
      }
     },
     "403": {
      "description": "Editors cannot revoke a creator",
      "content": {
       "application/json": {
        "schema": {
         "$ref": "#/components/schemas/Error"
        }
       }
      }
     },
     "404": {
      "$ref": "#/components/responses/notFound"
     },
     "default": {
      "$ref": "#/components/responses/error"
     },
     "401": {
      "$ref": "#/components/responses/unauthorized"
     }
    }
   }
  },
  "/api/s/{sid}/layout": {
   "get": {
    "operationId": "getLayout",
    "summary": "The creator's saved panel layout",
    "parameters": [
     {
      "$ref": "#/components/parameters/sid"
     }
    ],
    "responses": {
     "200": {
      "description": "JSON result",
      "content": {
       "application/json": {
        "schema": {
         "$ref": "#/components/schemas/Layout"
        }
       }
      }
     },
     "404": {
      "$ref": "#/components/responses/notFound"
     },
     "default": {
      "$ref": "#/components/responses/error"
     },
     "401": {
      "$ref": "#/components/responses/unauthorized"
     }
    }
   },
   "put": {
    "operationId": "setLayout",
    "summary": "Save the dock layout (creator)",
    "parameters": [
     {
      "$ref": "#/components/parameters/sid"
     }
    ],
    "requestBody": {
     "required": true,
     "content": {
      "application/json": {
       "schema": {
        "$ref": "#/components/schemas/Layout"
       }
      }
     }
    },
    "responses": {
     "200": {
      "description": "JSON result",
      "content": {
       "application/json": {
        "schema": {
         "$ref": "#/components/schemas/Status"
        }
       }
      }
     },
     "404": {
      "$ref": "#/components/responses/notFound"
     },
     "default": {
      "$ref": "#/components/responses/error"
     },
     "401": {
      "$ref": "#/components/responses/unauthorized"
     }
    }
   }
  },
  "/api/s/{sid}/agents": {
   "get": {
    "operationId": "listAgentCreds",
    "summary": "Agents currently authorized on this session",
    "parameters": [
     {
      "$ref": "#/components/parameters/sid"
     }
    ],
    "responses": {
     "200": {
      "description": "JSON result",
      "content": {
       "application/json": {
        "schema": {
         "type": "array",
         "items": {
          "$ref": "#/components/schemas/AgentCred"
         }
        }
       }
      }
     },
     "404": {
      "$ref": "#/components/responses/notFound"
     },
     "default": {
      "$ref": "#/components/responses/error"
     },
     "401": {
      "$ref": "#/components/responses/unauthorized"
     }
    }
   },
   "post": {
    "operationId": "inviteAgent",
    "summary": "Invite an agent to work this session and start its run",
    "description": "The agent acts at the lower of its configured ceiling and your own role here; it can never outrank you.",
    "parameters": [
     {
      "$ref": "#/components/parameters/sid"
     }
    ],
    "requestBody": {
     "required": true,
     "content": {
      "application/json": {
       "schema": {
        "$ref": "#/components/schemas/InviteAgentRequest"
       }
      }
     }
    },
    "responses": {
     "200": {
      "description": "JSON result",
      "content": {
       "application/json": {
        "schema": {
         "$ref": "#/components/schemas/AgentCred"
        }
       }
      }
     },
     "400": {
      "description": "No funding key for the agent's provider",
      "content": {
       "application/json": {
        "schema": {
         "$ref": "#/components/schemas/Error"
        }
       }
      }
     },
     "404": {
      "$ref": "#/components/responses/notFound"
     },
     "503": {
      "description": "All agent run slots are busy",
      "content": {
       "application/json": {
        "schema": {
         "$ref": "#/components/schemas/Error"
        }
       }
      }
     },
     "default": {
      "$ref": "#/components/responses/error"
     },
     "401": {
      "$ref": "#/components/responses/unauthorized"
     }
    }
   }
  },
  "/api/s/{sid}/agents/{id}": {
   "delete": {
    "operationId": "revokeAgent",
    "summary": "Revoke an agent's authorization",
    "parameters": [
     {
      "$ref": "#/components/parameters/sid"
     },
     {
      "name": "id",
      "in": "path",
      "required": true,
      "schema": {
       "type": "string"
      },
      "description": "Credential id from the agents list"
     }
    ],
    "responses": {
     "200": {
      "description": "JSON result",
      "content": {
       "application/json": {
        "schema": {
         "$ref": "#/components/schemas/Status"
        }
       }
      }
     },
     "404": {
      "$ref": "#/components/responses/notFound"
     },
     "default": {
      "$ref": "#/components/responses/error"
     },
     "401": {
      "$ref": "#/components/responses/unauthorized"
     }
    }
   }
  },
  "/api/s/{sid}/chat": {
   "get": {
    "operationId": "getChat",
    "summary": "The session's shared chat, humans and agents alike",
    "parameters": [
     {
      "$ref": "#/components/parameters/sid"
     }
    ],
    "responses": {
     "200": {
      "description": "JSON result",
      "content": {
       "application/json": {
        "schema": {
         "type": "array",
         "items": {
          "$ref": "#/components/schemas/ChatMessage"
         }
        }
       }
      }
     },
     "404": {
      "$ref": "#/components/responses/notFound"
     },
     "default": {
      "$ref": "#/components/responses/error"
     },
     "401": {
      "$ref": "#/components/responses/unauthorized"
     }
    }
   },
   "post": {
    "operationId": "sendChat",
    "summary": "Send a message to an agent; its reply lands in the chat",
    "description": "Starts an interactive run under your own authority; the agent can read the session, and write to it when your role allows. Watch the chat (or the WebSocket) for the reply.",
    "parameters": [
     {
      "$ref": "#/components/parameters/sid"
     }
    ],
    "requestBody": {
     "required": true,
     "content": {
      "application/json": {
       "schema": {
        "$ref": "#/components/schemas/SendChatRequest"
       }
      }
     }
    },
    "responses": {
     "202": {
      "description": "The run was started; the reply arrives in the chat",
      "content": {
       "application/json": {
        "schema": {
         "$ref": "#/components/schemas/StartedRun"
        }
       }
      }
     },
     "400": {
      "$ref": "#/components/responses/badRequest"
     },
     "404": {
      "$ref": "#/components/responses/notFound"
     },
     "503": {
      "description": "All agent run slots are busy",
      "content": {
       "application/json": {
        "schema": {
         "$ref": "#/components/schemas/Error"
        }
       }
      }
     },
     "default": {
      "$ref": "#/components/responses/error"
     },
     "401": {
      "$ref": "#/components/responses/unauthorized"
     }
    }
   },
   "delete": {
    "operationId": "clearChat",
    "summary": "Wipe the shared chat history (editor)",
    "parameters": [
     {
      "$ref": "#/components/parameters/sid"
     }
    ],
    "responses": {
     "200": {
      "description": "JSON result",
      "content": {
       "application/json": {
        "schema": {
         "$ref": "#/components/schemas/Status"
        }
       }
      }
     },
     "404": {
      "$ref": "#/components/responses/notFound"
     },
     "default": {
      "$ref": "#/components/responses/error"
     },
     "401": {
      "$ref": "#/components/responses/unauthorized"
     }
    }
   }
  },
  "/api/s/{sid}/runs": {
   "get": {
    "operationId": "listRuns",
    "summary": "Agent runs in flight on this session",
    "parameters": [
     {
      "$ref": "#/components/parameters/sid"
     }
    ],
    "responses": {
     "200": {
      "description": "JSON result",
      "content": {
       "application/json": {
        "schema": {
         "type": "array",
         "items": {
          "$ref": "#/components/schemas/ActiveRun"
         }
        }
       }
      }
     },
     "404": {
      "$ref": "#/components/responses/notFound"
     },
     "default": {
      "$ref": "#/components/responses/error"
     },
     "401": {
      "$ref": "#/components/responses/unauthorized"
     }
    }
   }
  },
  "/api/s/{sid}/runs/{id}": {
   "delete": {
    "operationId": "stopRun",
    "summary": "Stop a run: your own, or anyone's as editor",
    "parameters": [
     {
      "$ref": "#/components/parameters/sid"
     },
     {
      "name": "id",
      "in": "path",
      "required": true,
      "schema": {
       "type": "string"
      },
      "description": "Run id from the runs list"
     }
    ],
    "responses": {
     "200": {
      "description": "JSON result",
      "content": {
       "application/json": {
        "schema": {
         "$ref": "#/components/schemas/Status"
        }
       }
      }
     },
     "403": {
      "description": "Not your run, and you are not an editor",
      "content": {
       "application/json": {
        "schema": {
         "$ref": "#/components/schemas/Error"
        }
       }
      }
     },
     "404": {
      "$ref": "#/components/responses/notFound"
     },
     "default": {
      "$ref": "#/components/responses/error"
     },
     "401": {
      "$ref": "#/components/responses/unauthorized"
     }
    }
   }
  },
  "/api/s/{sid}/agent-peers": {
   "get": {
    "operationId": "agentPeers",
    "summary": "Where each agent that has run here was last seen",
    "parameters": [
     {
      "$ref": "#/components/parameters/sid"
     }
    ],
    "responses": {
     "200": {
      "description": "JSON result",
      "content": {
       "application/json": {
        "schema": {
         "type": "array",
         "items": {
          "$ref": "#/components/schemas/AgentPeer"
         }
        }
       }
      }
     },
     "404": {
      "$ref": "#/components/responses/notFound"
     },
     "default": {
      "$ref": "#/components/responses/error"
     },
     "401": {
      "$ref": "#/components/responses/unauthorized"
     }
    }
   }
  },
  "/api/s/{sid}/info": {
   "get": {
    "operationId": "info",
    "summary": "File format, architecture, entry point and hardening flags",
    "parameters": [
     {
      "$ref": "#/components/parameters/sid"
     }
    ],
    "responses": {
     "200": {
      "description": "JSON result",
      "content": {
       "application/json": {
        "schema": {
         "$ref": "#/components/schemas/Info"
        }
       }
      }
     },
     "404": {
      "$ref": "#/components/responses/notFound"
     },
     "default": {
      "$ref": "#/components/responses/error"
     },
     "401": {
      "$ref": "#/components/responses/unauthorized"
     }
    }
   }
  },
  "/api/s/{sid}/overview": {
   "get": {
    "operationId": "overview",
    "summary": "Summary counts: functions, strings, symbols, imports, xrefs, calls",
    "parameters": [
     {
      "$ref": "#/components/parameters/sid"
     }
    ],
    "responses": {
     "200": {
      "description": "JSON result",
      "content": {
       "application/json": {
        "schema": {
         "$ref": "#/components/schemas/Overview"
        }
       }
      }
     },
     "404": {
      "$ref": "#/components/responses/notFound"
     },
     "default": {
      "$ref": "#/components/responses/error"
     },
     "401": {
      "$ref": "#/components/responses/unauthorized"
     }
    }
   }
  },
  "/api/s/{sid}/triage": {
   "get": {
    "operationId": "triage",
    "summary": "Functions ranked by how likely they are to repay reading first, with reasons",
    "parameters": [
     {
      "$ref": "#/components/parameters/sid"
     },
     {
      "name": "limit",
      "in": "query",
      "description": "How many ranked functions to return (default 100)",
      "schema": {
       "type": "integer",
       "minimum": 1,
       "maximum": 500,
       "default": 100
      }
     }
    ],
    "responses": {
     "200": {
      "description": "JSON result",
      "content": {
       "application/json": {
        "schema": {
         "$ref": "#/components/schemas/Triage"
        }
       }
      }
     },
     "404": {
      "$ref": "#/components/responses/notFound"
     },
     "default": {
      "$ref": "#/components/responses/error"
     },
     "401": {
      "$ref": "#/components/responses/unauthorized"
     }
    }
   }
  },
  "/api/s/{sid}/hashes": {
   "get": {
    "operationId": "hashes",
    "summary": "File hashes and whole-file entropy",
    "parameters": [
     {
      "$ref": "#/components/parameters/sid"
     }
    ],
    "responses": {
     "200": {
      "description": "JSON result",
      "content": {
       "application/json": {
        "schema": {
         "$ref": "#/components/schemas/Hashes"
        }
       }
      }
     },
     "404": {
      "$ref": "#/components/responses/notFound"
     },
     "default": {
      "$ref": "#/components/responses/error"
     },
     "401": {
      "$ref": "#/components/responses/unauthorized"
     }
    }
   }
  },
  "/api/s/{sid}/entropy": {
   "get": {
    "operationId": "entropy",
    "summary": "Shannon entropy per bucket across initialised memory, labelled by section",
    "description": "High and flat reads as compressed or encrypted; low and spiky as text or padding. Buckets never straddle sections, so the answer can hold a few more samples than asked for.",
    "parameters": [
     {
      "$ref": "#/components/parameters/sid"
     },
     {
      "name": "buckets",
      "in": "query",
      "description": "Target resolution (default 256)",
      "schema": {
       "type": "integer",
       "minimum": 16,
       "maximum": 2048,
       "default": 256
      }
     }
    ],
    "responses": {
     "200": {
      "description": "JSON result",
      "content": {
       "application/json": {
        "schema": {
         "type": "array",
         "items": {
          "$ref": "#/components/schemas/EntropyBucket"
         }
        }
       }
      }
     },
     "404": {
      "$ref": "#/components/responses/notFound"
     },
     "default": {
      "$ref": "#/components/responses/error"
     },
     "401": {
      "$ref": "#/components/responses/unauthorized"
     }
    }
   }
  },
  "/api/s/{sid}/sections": {
   "get": {
    "operationId": "sections",
    "summary": "Sections with addresses, sizes and permissions",
    "parameters": [
     {
      "$ref": "#/components/parameters/sid"
     }
    ],
    "responses": {
     "200": {
      "description": "JSON result",
      "content": {
       "application/json": {
        "schema": {
         "type": "array",
         "items": {
          "$ref": "#/components/schemas/Section"
         }
        }
       }
      }
     },
     "404": {
      "$ref": "#/components/responses/notFound"
     },
     "default": {
      "$ref": "#/components/responses/error"
     },
     "401": {
      "$ref": "#/components/responses/unauthorized"
     }
    }
   }
  },
  "/api/s/{sid}/certificates": {
   "get": {
    "operationId": "certificates",
    "summary": "Code-signing certificates where the format carries them",
    "parameters": [
     {
      "$ref": "#/components/parameters/sid"
     }
    ],
    "responses": {
     "200": {
      "description": "JSON result",
      "content": {
       "application/json": {
        "schema": {
         "type": "object",
         "additionalProperties": true
        }
       }
      }
     },
     "404": {
      "$ref": "#/components/responses/notFound"
     },
     "default": {
      "$ref": "#/components/responses/error"
     },
     "401": {
      "$ref": "#/components/responses/unauthorized"
     }
    }
   }
  },
  "/api/s/{sid}/versioninfo": {
   "get": {
    "operationId": "versioninfo",
    "summary": "Imported library version requirements",
    "parameters": [
     {
      "$ref": "#/components/parameters/sid"
     }
    ],
    "responses": {
     "200": {
      "description": "JSON result",
      "content": {
       "application/json": {
        "schema": {
         "description": "Format-specific; a list of libraries with their version tags on ELF",
         "type": [
          "array",
          "object"
         ],
         "items": {
          "type": "object",
          "additionalProperties": true
         },
         "additionalProperties": true
        }
       }
      }
     },
     "404": {
      "$ref": "#/components/responses/notFound"
     },
     "default": {
      "$ref": "#/components/responses/error"
     },
     "401": {
      "$ref": "#/components/responses/unauthorized"
     }
    }
   }
  },
  "/api/s/{sid}/libraries": {
   "get": {
    "operationId": "libraries",
    "summary": "Shared libraries the binary links against",
    "parameters": [
     {
      "$ref": "#/components/parameters/sid"
     }
    ],
    "responses": {
     "200": {
      "description": "JSON result",
      "content": {
       "application/json": {
        "schema": {
         "type": "array",
         "items": {
          "type": "string"
         }
        }
       }
      }
     },
     "404": {
      "$ref": "#/components/responses/notFound"
     },
     "default": {
      "$ref": "#/components/responses/error"
     },
     "401": {
      "$ref": "#/components/responses/unauthorized"
     }
    }
   }
  },
  "/api/s/{sid}/functions": {
   "get": {
    "operationId": "functions",
    "summary": "Every function with name, address, size and complexity",
    "parameters": [
     {
      "$ref": "#/components/parameters/sid"
     }
    ],
    "responses": {
     "200": {
      "description": "JSON result",
      "content": {
       "application/json": {
        "schema": {
         "type": "array",
         "items": {
          "$ref": "#/components/schemas/Function"
         }
        }
       }
      }
     },
     "404": {
      "$ref": "#/components/responses/notFound"
     },
     "default": {
      "$ref": "#/components/responses/error"
     },
     "401": {
      "$ref": "#/components/responses/unauthorized"
     }
    }
   }
  },
  "/api/s/{sid}/disasm": {
   "get": {
    "operationId": "disasm",
    "summary": "Disassembly of the function at an address",
    "parameters": [
     {
      "$ref": "#/components/parameters/sid"
     },
     {
      "$ref": "#/components/parameters/addr"
     }
    ],
    "responses": {
     "200": {
      "description": "JSON result",
      "content": {
       "application/json": {
        "schema": {
         "$ref": "#/components/schemas/Disasm"
        }
       }
      }
     },
     "400": {
      "$ref": "#/components/responses/badRequest"
     },
     "404": {
      "$ref": "#/components/responses/notFound"
     },
     "default": {
      "$ref": "#/components/responses/error"
     },
     "401": {
      "$ref": "#/components/responses/unauthorized"
     }
    }
   }
  },
  "/api/s/{sid}/decompile": {
   "get": {
    "operationId": "decompile",
    "summary": "Decompiled C for the function at an address",
    "parameters": [
     {
      "$ref": "#/components/parameters/sid"
     },
     {
      "$ref": "#/components/parameters/addr"
     }
    ],
    "responses": {
     "200": {
      "description": "JSON result",
      "content": {
       "application/json": {
        "schema": {
         "$ref": "#/components/schemas/Decompile"
        }
       }
      }
     },
     "400": {
      "$ref": "#/components/responses/badRequest"
     },
     "404": {
      "$ref": "#/components/responses/notFound"
     },
     "default": {
      "$ref": "#/components/responses/error"
     },
     "401": {
      "$ref": "#/components/responses/unauthorized"
     }
    }
   }
  },
  "/api/s/{sid}/vars": {
   "get": {
    "operationId": "vars",
    "summary": "The function's variables and arguments with types and storage",
    "parameters": [
     {
      "$ref": "#/components/parameters/sid"
     },
     {
      "$ref": "#/components/parameters/addr"
     }
    ],
    "responses": {
     "200": {
      "description": "JSON result",
      "content": {
       "application/json": {
        "schema": {
         "$ref": "#/components/schemas/Vars"
        }
       }
      }
     },
     "400": {
      "$ref": "#/components/responses/badRequest"
     },
     "404": {
      "$ref": "#/components/responses/notFound"
     },
     "default": {
      "$ref": "#/components/responses/error"
     },
     "401": {
      "$ref": "#/components/responses/unauthorized"
     }
    }
   }
  },
  "/api/s/{sid}/graph": {
   "get": {
    "operationId": "graph",
    "summary": "Basic-block control-flow graph of the function at an address",
    "parameters": [
     {
      "$ref": "#/components/parameters/sid"
     },
     {
      "$ref": "#/components/parameters/addr"
     }
    ],
    "responses": {
     "200": {
      "description": "JSON result",
      "content": {
       "application/json": {
        "schema": {
         "type": "array",
         "items": {
          "$ref": "#/components/schemas/Graph"
         }
        }
       }
      }
     },
     "400": {
      "$ref": "#/components/responses/badRequest"
     },
     "404": {
      "$ref": "#/components/responses/notFound"
     },
     "default": {
      "$ref": "#/components/responses/error"
     },
     "401": {
      "$ref": "#/components/responses/unauthorized"
     }
    }
   }
  },
  "/api/s/{sid}/xrefs": {
   "get": {
    "operationId": "xrefs",
    "summary": "Cross-references to an address: who reads, writes, calls or jumps here",
    "parameters": [
     {
      "$ref": "#/components/parameters/sid"
     },
     {
      "$ref": "#/components/parameters/addr"
     }
    ],
    "responses": {
     "200": {
      "description": "JSON result",
      "content": {
       "application/json": {
        "schema": {
         "type": "array",
         "items": {
          "$ref": "#/components/schemas/Xref"
         }
        }
       }
      }
     },
     "400": {
      "$ref": "#/components/responses/badRequest"
     },
     "404": {
      "$ref": "#/components/responses/notFound"
     },
     "default": {
      "$ref": "#/components/responses/error"
     },
     "401": {
      "$ref": "#/components/responses/unauthorized"
     }
    }
   }
  },
  "/api/s/{sid}/calltree": {
   "get": {
    "operationId": "calltree",
    "summary": "Callers and callees of the function at an address",
    "parameters": [
     {
      "$ref": "#/components/parameters/sid"
     },
     {
      "$ref": "#/components/parameters/addr"
     }
    ],
    "responses": {
     "200": {
      "description": "JSON result",
      "content": {
       "application/json": {
        "schema": {
         "$ref": "#/components/schemas/CallTree"
        }
       }
      }
     },
     "400": {
      "$ref": "#/components/responses/badRequest"
     },
     "404": {
      "$ref": "#/components/responses/notFound"
     },
     "default": {
      "$ref": "#/components/responses/error"
     },
     "401": {
      "$ref": "#/components/responses/unauthorized"
     }
    }
   }
  },
  "/api/s/{sid}/callgraph": {
   "get": {
    "operationId": "callgraph",
    "summary": "The whole-program call graph: every function with its callees by name",
    "parameters": [
     {
      "$ref": "#/components/parameters/sid"
     }
    ],
    "responses": {
     "200": {
      "description": "JSON result",
      "content": {
       "application/json": {
        "schema": {
         "type": "array",
         "items": {
          "$ref": "#/components/schemas/CallGraphNode"
         }
        }
       }
      }
     },
     "404": {
      "$ref": "#/components/responses/notFound"
     },
     "default": {
      "$ref": "#/components/responses/error"
     }
    }
   }
  },
  "/api/s/{sid}/instruction": {
   "get": {
    "operationId": "instruction",
    "summary": "One instruction decoded: operands, control flow, p-code",
    "parameters": [
     {
      "$ref": "#/components/parameters/sid"
     },
     {
      "$ref": "#/components/parameters/addr"
     }
    ],
    "responses": {
     "200": {
      "description": "JSON result",
      "content": {
       "application/json": {
        "schema": {
         "$ref": "#/components/schemas/Instruction"
        }
       }
      }
     },
     "400": {
      "$ref": "#/components/responses/badRequest"
     },
     "404": {
      "$ref": "#/components/responses/notFound"
     },
     "default": {
      "$ref": "#/components/responses/error"
     },
     "401": {
      "$ref": "#/components/responses/unauthorized"
     }
    }
   }
  },
  "/api/s/{sid}/resolveaddr": {
   "get": {
    "operationId": "resolveaddr",
    "summary": "The function containing an address",
    "parameters": [
     {
      "$ref": "#/components/parameters/sid"
     },
     {
      "$ref": "#/components/parameters/addr"
     }
    ],
    "responses": {
     "200": {
      "description": "JSON result",
      "content": {
       "application/json": {
        "schema": {
         "$ref": "#/components/schemas/ResolveAddr"
        }
       }
      }
     },
     "400": {
      "$ref": "#/components/responses/badRequest"
     },
     "404": {
      "$ref": "#/components/responses/notFound"
     },
     "default": {
      "$ref": "#/components/responses/error"
     },
     "401": {
      "$ref": "#/components/responses/unauthorized"
     }
    }
   }
  },
  "/api/s/{sid}/signature": {
   "get": {
    "operationId": "signature",
    "summary": "The function's C prototype and calling convention",
    "parameters": [
     {
      "$ref": "#/components/parameters/sid"
     },
     {
      "$ref": "#/components/parameters/addr"
     }
    ],
    "responses": {
     "200": {
      "description": "JSON result",
      "content": {
       "application/json": {
        "schema": {
         "$ref": "#/components/schemas/Signature"
        }
       }
      }
     },
     "400": {
      "$ref": "#/components/responses/badRequest"
     },
     "404": {
      "$ref": "#/components/responses/notFound"
     },
     "default": {
      "$ref": "#/components/responses/error"
     },
     "401": {
      "$ref": "#/components/responses/unauthorized"
     }
    }
   },
   "post": {
    "operationId": "setSignature",
    "summary": "Apply an edited C prototype to a function (editor)",
    "parameters": [
     {
      "$ref": "#/components/parameters/sid"
     }
    ],
    "responses": {
     "200": {
      "description": "JSON result",
      "content": {
       "application/json": {
        "schema": {
         "type": "object",
         "additionalProperties": true,
         "description": "The read-back state after the change; a 200 means the model really holds it"
        }
       }
      }
     },
     "400": {
      "$ref": "#/components/responses/badRequest"
     },
     "404": {
      "$ref": "#/components/responses/notFound"
     },
     "default": {
      "$ref": "#/components/responses/error"
     },
     "401": {
      "$ref": "#/components/responses/unauthorized"
     }
    },
    "requestBody": {
     "required": true,
     "content": {
      "application/json": {
       "schema": {
        "$ref": "#/components/schemas/SignatureRequest"
       }
      }
     }
    }
   }
  },
  "/api/s/{sid}/strings": {
   "get": {
    "operationId": "strings",
    "summary": "Strings with addresses and sections",
    "parameters": [
     {
      "$ref": "#/components/parameters/sid"
     },
     {
      "name": "scope",
      "in": "query",
      "description": "Pass 'all' to additionally sweep undefined memory for string-shaped runs; noisier, but finds strings compilers park in .text",
      "schema": {
       "type": "string",
       "enum": [
        "all"
       ]
      }
     }
    ],
    "responses": {
     "200": {
      "description": "JSON result",
      "content": {
       "application/json": {
        "schema": {
         "type": "array",
         "items": {
          "$ref": "#/components/schemas/StringItem"
         }
        }
       }
      }
     },
     "404": {
      "$ref": "#/components/responses/notFound"
     },
     "default": {
      "$ref": "#/components/responses/error"
     },
     "401": {
      "$ref": "#/components/responses/unauthorized"
     }
    }
   }
  },
  "/api/s/{sid}/hex": {
   "get": {
    "operationId": "hex",
    "summary": "Raw bytes at an address, as an array of byte values",
    "parameters": [
     {
      "$ref": "#/components/parameters/sid"
     },
     {
      "$ref": "#/components/parameters/addr"
     },
     {
      "name": "len",
      "in": "query",
      "description": "How many bytes (default 256)",
      "schema": {
       "type": "integer",
       "minimum": 1,
       "maximum": 4096,
       "default": 256
      }
     }
    ],
    "responses": {
     "200": {
      "description": "JSON result",
      "content": {
       "application/json": {
        "schema": {
         "type": "array",
         "items": {
          "type": "integer",
          "minimum": 0,
          "maximum": 255
         }
        }
       }
      }
     },
     "400": {
      "$ref": "#/components/responses/badRequest"
     },
     "404": {
      "$ref": "#/components/responses/notFound"
     },
     "default": {
      "$ref": "#/components/responses/error"
     },
     "401": {
      "$ref": "#/components/responses/unauthorized"
     }
    }
   }
  },
  "/api/s/{sid}/imports": {
   "get": {
    "operationId": "imports",
    "summary": "Imported functions with their thunk addresses",
    "parameters": [
     {
      "$ref": "#/components/parameters/sid"
     }
    ],
    "responses": {
     "200": {
      "description": "JSON result",
      "content": {
       "application/json": {
        "schema": {
         "type": "array",
         "items": {
          "$ref": "#/components/schemas/Import"
         }
        }
       }
      }
     },
     "404": {
      "$ref": "#/components/responses/notFound"
     },
     "default": {
      "$ref": "#/components/responses/error"
     },
     "401": {
      "$ref": "#/components/responses/unauthorized"
     }
    }
   }
  },
  "/api/s/{sid}/exports": {
   "get": {
    "operationId": "exports",
    "summary": "Exported symbols",
    "parameters": [
     {
      "$ref": "#/components/parameters/sid"
     }
    ],
    "responses": {
     "200": {
      "description": "JSON result",
      "content": {
       "application/json": {
        "schema": {
         "type": "array",
         "items": {
          "$ref": "#/components/schemas/Symbol"
         }
        }
       }
      }
     },
     "404": {
      "$ref": "#/components/responses/notFound"
     },
     "default": {
      "$ref": "#/components/responses/error"
     },
     "401": {
      "$ref": "#/components/responses/unauthorized"
     }
    }
   }
  },
  "/api/s/{sid}/types": {
   "get": {
    "operationId": "types",
    "summary": "Data types known to the program",
    "parameters": [
     {
      "$ref": "#/components/parameters/sid"
     }
    ],
    "responses": {
     "200": {
      "description": "JSON result",
      "content": {
       "application/json": {
        "schema": {
         "$ref": "#/components/schemas/Types"
        }
       }
      }
     },
     "404": {
      "$ref": "#/components/responses/notFound"
     },
     "default": {
      "$ref": "#/components/responses/error"
     },
     "401": {
      "$ref": "#/components/responses/unauthorized"
     }
    }
   }
  },
  "/api/s/{sid}/type": {
   "get": {
    "operationId": "type",
    "summary": "One type's definition: members for a composite, values for an enum",
    "parameters": [
     {
      "$ref": "#/components/parameters/sid"
     },
     {
      "name": "name",
      "in": "query",
      "required": true,
      "description": "Type name or category path, e.g. \"sockaddr_in\"",
      "schema": {
       "type": "string"
      }
     }
    ],
    "responses": {
     "200": {
      "description": "JSON result",
      "content": {
       "application/json": {
        "schema": {
         "$ref": "#/components/schemas/TypeDetail"
        }
       }
      }
     },
     "404": {
      "$ref": "#/components/responses/notFound"
     },
     "default": {
      "$ref": "#/components/responses/error"
     },
     "401": {
      "$ref": "#/components/responses/unauthorized"
     }
    }
   }
  },
  "/api/s/{sid}/type/uses": {
   "get": {
    "operationId": "typeUses",
    "summary": "How many data, variables and types would revert to undefined if this type were deleted",
    "parameters": [
     {
      "$ref": "#/components/parameters/sid"
     },
     {
      "name": "name",
      "in": "query",
      "required": true,
      "description": "Type name or category path, e.g. \"sockaddr_in\"",
      "schema": {
       "type": "string"
      }
     }
    ],
    "responses": {
     "200": {
      "description": "JSON result",
      "content": {
       "application/json": {
        "schema": {
         "$ref": "#/components/schemas/TypeUses"
        }
       }
      }
     },
     "404": {
      "$ref": "#/components/responses/notFound"
     },
     "default": {
      "$ref": "#/components/responses/error"
     },
     "401": {
      "$ref": "#/components/responses/unauthorized"
     }
    }
   }
  },
  "/api/s/{sid}/parsetypes": {
   "post": {
    "operationId": "parseTypes",
    "summary": "Define types from C declarations: structs, unions, enums, typedefs (editor)",
    "parameters": [
     {
      "$ref": "#/components/parameters/sid"
     }
    ],
    "responses": {
     "200": {
      "description": "JSON result",
      "content": {
       "application/json": {
        "schema": {
         "type": "object",
         "additionalProperties": true,
         "description": "The read-back state after the change; a 200 means the model really holds it"
        }
       }
      }
     },
     "400": {
      "$ref": "#/components/responses/badRequest"
     },
     "404": {
      "$ref": "#/components/responses/notFound"
     },
     "default": {
      "$ref": "#/components/responses/error"
     },
     "401": {
      "$ref": "#/components/responses/unauthorized"
     },
     "409": {
      "description": "A type of that name already exists; pass replace to overwrite",
      "content": {
       "application/json": {
        "schema": {
         "$ref": "#/components/schemas/Error"
        }
       }
      }
     }
    },
    "requestBody": {
     "required": true,
     "content": {
      "application/json": {
       "schema": {
        "$ref": "#/components/schemas/ParseTypesRequest"
       }
      }
     }
    }
   }
  },
  "/api/s/{sid}/deletetype": {
   "post": {
    "operationId": "deleteType",
    "summary": "Remove a type; every use of it reverts to undefined (editor)",
    "parameters": [
     {
      "$ref": "#/components/parameters/sid"
     }
    ],
    "responses": {
     "200": {
      "description": "JSON result",
      "content": {
       "application/json": {
        "schema": {
         "type": "object",
         "additionalProperties": true,
         "description": "The read-back state after the change; a 200 means the model really holds it"
        }
       }
      }
     },
     "400": {
      "$ref": "#/components/responses/badRequest"
     },
     "404": {
      "$ref": "#/components/responses/notFound"
     },
     "default": {
      "$ref": "#/components/responses/error"
     },
     "401": {
      "$ref": "#/components/responses/unauthorized"
     }
    },
    "requestBody": {
     "required": true,
     "content": {
      "application/json": {
       "schema": {
        "$ref": "#/components/schemas/DeleteTypeRequest"
       }
      }
     }
    }
   }
  },
  "/api/s/{sid}/search": {
   "get": {
    "operationId": "search",
    "summary": "Search strings, symbols and bytes across the program",
    "parameters": [
     {
      "$ref": "#/components/parameters/sid"
     },
     {
      "name": "query",
      "in": "query",
      "description": "What to search for. Literal text by default; hex bytes like 'deadbeef' with mode=hex; a Java regular expression with mode=regex",
      "schema": {
       "type": "string"
      },
      "required": true
     },
     {
      "name": "mode",
      "in": "query",
      "description": "How to interpret the query. Anything else falls back to a literal text search",
      "schema": {
       "type": "string",
       "enum": [
        "hex",
        "regex"
       ]
      }
     }
    ],
    "responses": {
     "200": {
      "description": "JSON result",
      "content": {
       "application/json": {
        "schema": {
         "type": "array",
         "items": {
          "$ref": "#/components/schemas/SearchHit"
         }
        }
       }
      }
     },
     "404": {
      "$ref": "#/components/responses/notFound"
     },
     "default": {
      "$ref": "#/components/responses/error"
     },
     "401": {
      "$ref": "#/components/responses/unauthorized"
     }
    }
   }
  },
  "/api/s/{sid}/comments": {
   "get": {
    "operationId": "comments",
    "summary": "Analyst comments with author and address",
    "parameters": [
     {
      "$ref": "#/components/parameters/sid"
     }
    ],
    "responses": {
     "200": {
      "description": "JSON result",
      "content": {
       "application/json": {
        "schema": {
         "type": "array",
         "items": {
          "$ref": "#/components/schemas/Comment"
         }
        }
       }
      }
     },
     "404": {
      "$ref": "#/components/responses/notFound"
     },
     "default": {
      "$ref": "#/components/responses/error"
     },
     "401": {
      "$ref": "#/components/responses/unauthorized"
     }
    }
   }
  },
  "/api/s/{sid}/labels": {
   "get": {
    "operationId": "labels",
    "summary": "User and analysis labels at an address",
    "parameters": [
     {
      "$ref": "#/components/parameters/sid"
     },
     {
      "$ref": "#/components/parameters/addr"
     }
    ],
    "responses": {
     "200": {
      "description": "JSON result",
      "content": {
       "application/json": {
        "schema": {
         "type": "array",
         "items": {
          "$ref": "#/components/schemas/Label"
         }
        }
       }
      }
     },
     "400": {
      "$ref": "#/components/responses/badRequest"
     },
     "404": {
      "$ref": "#/components/responses/notFound"
     },
     "default": {
      "$ref": "#/components/responses/error"
     },
     "401": {
      "$ref": "#/components/responses/unauthorized"
     }
    }
   }
  },
  "/api/s/{sid}/bookmarks": {
   "get": {
    "operationId": "bookmarks",
    "summary": "Bookmarked addresses with notes",
    "parameters": [
     {
      "$ref": "#/components/parameters/sid"
     }
    ],
    "responses": {
     "200": {
      "description": "JSON result",
      "content": {
       "application/json": {
        "schema": {
         "type": "array",
         "items": {
          "$ref": "#/components/schemas/Bookmark"
         }
        }
       }
      }
     },
     "404": {
      "$ref": "#/components/responses/notFound"
     },
     "default": {
      "$ref": "#/components/responses/error"
     },
     "401": {
      "$ref": "#/components/responses/unauthorized"
     }
    }
   }
  },
  "/api/s/{sid}/notes": {
   "get": {
    "operationId": "notes",
    "summary": "The analysts' shared write-up of this binary",
    "description": "Markdown, maintained by the people and agents working the session. Usually the best first read: it says what the binary is and where the interesting parts are.",
    "parameters": [
     {
      "$ref": "#/components/parameters/sid"
     }
    ],
    "responses": {
     "200": {
      "description": "JSON result",
      "content": {
       "application/json": {
        "schema": {
         "$ref": "#/components/schemas/Notes"
        }
       }
      }
     },
     "404": {
      "$ref": "#/components/responses/notFound"
     },
     "default": {
      "$ref": "#/components/responses/error"
     },
     "401": {
      "$ref": "#/components/responses/unauthorized"
     }
    }
   },
   "post": {
    "operationId": "setNotes",
    "summary": "Replace the shared session notes (editor)",
    "parameters": [
     {
      "$ref": "#/components/parameters/sid"
     }
    ],
    "responses": {
     "200": {
      "description": "JSON result",
      "content": {
       "application/json": {
        "schema": {
         "type": "object",
         "additionalProperties": true,
         "description": "The read-back state after the change; a 200 means the model really holds it"
        }
       }
      }
     },
     "400": {
      "$ref": "#/components/responses/badRequest"
     },
     "404": {
      "$ref": "#/components/responses/notFound"
     },
     "default": {
      "$ref": "#/components/responses/error"
     },
     "401": {
      "$ref": "#/components/responses/unauthorized"
     }
    },
    "description": "Read first and merge: this replaces the whole text, and others may have written since.",
    "requestBody": {
     "required": true,
     "content": {
      "application/json": {
       "schema": {
        "$ref": "#/components/schemas/SetNotesRequest"
       }
      }
     }
    }
   }
  },
  "/api/s/{sid}/findings": {
   "get": {
    "operationId": "listFindings",
    "summary": "The structured findings background agent runs recorded, oldest first, superseded ones marked",
    "parameters": [
     {
      "name": "sid",
      "in": "path",
      "required": true,
      "schema": {
       "type": "string"
      },
      "description": "The session id."
     }
    ],
    "responses": {
     "200": {
      "description": "JSON result",
      "content": {
       "application/json": {
        "schema": {
         "type": "array",
         "items": {
          "$ref": "#/components/schemas/Finding"
         }
        }
       }
      }
     },
     "default": {
      "$ref": "#/components/responses/error"
     }
    }
   }
  },
  "/api/s/{sid}/undostate": {
   "get": {
    "operationId": "undostate",
    "summary": "What undo would revert next, and the program's history stack",
    "responses": {
     "200": {
      "description": "JSON result",
      "content": {
       "application/json": {
        "schema": {
         "type": "object",
         "additionalProperties": false,
         "properties": {
          "canUndo": {
           "type": "boolean"
          },
          "canRedo": {
           "type": "boolean"
          },
          "undoName": {
           "type": "string",
           "description": "The next change undo would revert, named with who made it"
          },
          "redoName": {
           "type": "string"
          },
          "undoStack": {
           "type": "array",
           "items": {
            "type": "string"
           },
           "description": "Newest first"
          },
          "redoStack": {
           "type": "array",
           "items": {
            "type": "string"
           }
          }
         }
        }
       }
      }
     },
     "default": {
      "$ref": "#/components/responses/error"
     }
    },
    "parameters": [
     {
      "$ref": "#/components/parameters/sid"
     }
    ]
   }
  },
  "/api/s/{sid}/undo": {
   "post": {
    "operationId": "undo",
    "summary": "Revert the program's most recent change",
    "responses": {
     "200": {
      "description": "Applied",
      "content": {
       "application/json": {
        "schema": {
         "type": "object",
         "additionalProperties": false,
         "properties": {
          "reverted": {
           "type": "string",
           "description": "The transaction that was undone or redone"
          },
          "by": {
           "type": "string"
          }
         }
        }
       }
      }
     },
     "409": {
      "description": "Nothing to undo or redo",
      "content": {
       "application/json": {
        "schema": {
         "$ref": "#/components/schemas/Error"
        }
       }
      }
     },
     "default": {
      "$ref": "#/components/responses/error"
     }
    },
    "parameters": [
     {
      "$ref": "#/components/parameters/sid"
     }
    ]
   }
  },
  "/api/s/{sid}/redo": {
   "post": {
    "operationId": "redo",
    "summary": "Reapply the change undo last reverted",
    "responses": {
     "200": {
      "description": "Applied",
      "content": {
       "application/json": {
        "schema": {
         "type": "object",
         "additionalProperties": false,
         "properties": {
          "reverted": {
           "type": "string",
           "description": "The transaction that was undone or redone"
          },
          "by": {
           "type": "string"
          }
         }
        }
       }
      }
     },
     "409": {
      "description": "Nothing to undo or redo",
      "content": {
       "application/json": {
        "schema": {
         "$ref": "#/components/schemas/Error"
        }
       }
      }
     },
     "default": {
      "$ref": "#/components/responses/error"
     }
    },
    "parameters": [
     {
      "$ref": "#/components/parameters/sid"
     }
    ]
   }
  },
  "/api/s/{sid}/activity": {
   "get": {
    "operationId": "activity",
    "summary": "Recent session activity: renames, comments, notes edits",
    "parameters": [
     {
      "$ref": "#/components/parameters/sid"
     }
    ],
    "responses": {
     "200": {
      "description": "JSON result",
      "content": {
       "application/json": {
        "schema": {
         "type": "array",
         "items": {
          "$ref": "#/components/schemas/ActivityEvent"
         }
        }
       }
      }
     },
     "404": {
      "$ref": "#/components/responses/notFound"
     },
     "default": {
      "$ref": "#/components/responses/error"
     },
     "401": {
      "$ref": "#/components/responses/unauthorized"
     }
    }
   }
  },
  "/api/s/{sid}/rename": {
   "post": {
    "operationId": "rename",
    "summary": "Rename the function at an address (editor)",
    "parameters": [
     {
      "$ref": "#/components/parameters/sid"
     }
    ],
    "responses": {
     "200": {
      "description": "JSON result",
      "content": {
       "application/json": {
        "schema": {
         "type": "object",
         "additionalProperties": true,
         "description": "The read-back state after the change; a 200 means the model really holds it"
        }
       }
      }
     },
     "400": {
      "$ref": "#/components/responses/badRequest"
     },
     "404": {
      "$ref": "#/components/responses/notFound"
     },
     "default": {
      "$ref": "#/components/responses/error"
     },
     "401": {
      "$ref": "#/components/responses/unauthorized"
     }
    },
    "description": "The worker applies it in a transaction and reads it back before answering, so a 200 means the model really holds the new name.",
    "requestBody": {
     "required": true,
     "content": {
      "application/json": {
       "schema": {
        "$ref": "#/components/schemas/RenameRequest"
       }
      }
     }
    }
   }
  },
  "/api/s/{sid}/renamevar": {
   "post": {
    "operationId": "renameVar",
    "summary": "Rename a local or parameter (editor)",
    "parameters": [
     {
      "$ref": "#/components/parameters/sid"
     }
    ],
    "responses": {
     "200": {
      "description": "JSON result",
      "content": {
       "application/json": {
        "schema": {
         "type": "object",
         "additionalProperties": true,
         "description": "The read-back state after the change; a 200 means the model really holds it"
        }
       }
      }
     },
     "400": {
      "$ref": "#/components/responses/badRequest"
     },
     "404": {
      "$ref": "#/components/responses/notFound"
     },
     "default": {
      "$ref": "#/components/responses/error"
     },
     "401": {
      "$ref": "#/components/responses/unauthorized"
     }
    },
    "requestBody": {
     "required": true,
     "content": {
      "application/json": {
       "schema": {
        "$ref": "#/components/schemas/RenameVarRequest"
       }
      }
     }
    }
   }
  },
  "/api/s/{sid}/retypevar": {
   "post": {
    "operationId": "retypeVar",
    "summary": "Change a variable's type (editor)",
    "parameters": [
     {
      "$ref": "#/components/parameters/sid"
     }
    ],
    "responses": {
     "200": {
      "description": "JSON result",
      "content": {
       "application/json": {
        "schema": {
         "type": "object",
         "additionalProperties": true,
         "description": "The read-back state after the change; a 200 means the model really holds it"
        }
       }
      }
     },
     "400": {
      "$ref": "#/components/responses/badRequest"
     },
     "404": {
      "$ref": "#/components/responses/notFound"
     },
     "default": {
      "$ref": "#/components/responses/error"
     },
     "401": {
      "$ref": "#/components/responses/unauthorized"
     }
    },
    "requestBody": {
     "required": true,
     "content": {
      "application/json": {
       "schema": {
        "$ref": "#/components/schemas/RetypeVarRequest"
       }
      }
     }
    }
   }
  },
  "/api/s/{sid}/comment": {
   "post": {
    "operationId": "setComment",
    "summary": "Set the comment at an address (editor)",
    "parameters": [
     {
      "$ref": "#/components/parameters/sid"
     }
    ],
    "responses": {
     "200": {
      "description": "JSON result",
      "content": {
       "application/json": {
        "schema": {
         "type": "object",
         "additionalProperties": true,
         "description": "The read-back state after the change; a 200 means the model really holds it"
        }
       }
      }
     },
     "400": {
      "$ref": "#/components/responses/badRequest"
     },
     "404": {
      "$ref": "#/components/responses/notFound"
     },
     "default": {
      "$ref": "#/components/responses/error"
     },
     "401": {
      "$ref": "#/components/responses/unauthorized"
     }
    },
    "requestBody": {
     "required": true,
     "content": {
      "application/json": {
       "schema": {
        "$ref": "#/components/schemas/CommentRequest"
       }
      }
     }
    }
   },
   "delete": {
    "operationId": "deleteComment",
    "summary": "Delete the comment at an address (editor)",
    "parameters": [
     {
      "$ref": "#/components/parameters/sid"
     },
     {
      "$ref": "#/components/parameters/addr"
     }
    ],
    "responses": {
     "200": {
      "description": "JSON result",
      "content": {
       "application/json": {
        "schema": {
         "type": "object",
         "additionalProperties": true,
         "description": "The read-back state after the change; a 200 means the model really holds it"
        }
       }
      }
     },
     "400": {
      "$ref": "#/components/responses/badRequest"
     },
     "404": {
      "$ref": "#/components/responses/notFound"
     },
     "default": {
      "$ref": "#/components/responses/error"
     },
     "401": {
      "$ref": "#/components/responses/unauthorized"
     }
    }
   }
  },
  "/api/s/{sid}/label": {
   "post": {
    "operationId": "setLabel",
    "summary": "Name an address, or clear it with an empty name (editor)",
    "parameters": [
     {
      "$ref": "#/components/parameters/sid"
     }
    ],
    "responses": {
     "200": {
      "description": "JSON result",
      "content": {
       "application/json": {
        "schema": {
         "type": "object",
         "additionalProperties": true,
         "description": "The read-back state after the change; a 200 means the model really holds it"
        }
       }
      }
     },
     "400": {
      "$ref": "#/components/responses/badRequest"
     },
     "404": {
      "$ref": "#/components/responses/notFound"
     },
     "default": {
      "$ref": "#/components/responses/error"
     },
     "401": {
      "$ref": "#/components/responses/unauthorized"
     }
    },
    "requestBody": {
     "required": true,
     "content": {
      "application/json": {
       "schema": {
        "$ref": "#/components/schemas/LabelRequest"
       }
      }
     }
    }
   }
  },
  "/api/s/{sid}/data": {
   "post": {
    "operationId": "setData",
    "summary": "Define the bytes at an address as a type, or clear with an empty type (editor)",
    "parameters": [
     {
      "$ref": "#/components/parameters/sid"
     }
    ],
    "responses": {
     "200": {
      "description": "JSON result",
      "content": {
       "application/json": {
        "schema": {
         "type": "object",
         "additionalProperties": true,
         "description": "The read-back state after the change; a 200 means the model really holds it"
        }
       }
      }
     },
     "400": {
      "$ref": "#/components/responses/badRequest"
     },
     "404": {
      "$ref": "#/components/responses/notFound"
     },
     "default": {
      "$ref": "#/components/responses/error"
     },
     "401": {
      "$ref": "#/components/responses/unauthorized"
     }
    },
    "requestBody": {
     "required": true,
     "content": {
      "application/json": {
       "schema": {
        "$ref": "#/components/schemas/DataRequest"
       }
      }
     }
    }
   }
  },
  "/api/s/{sid}/bookmark": {
   "post": {
    "operationId": "setBookmark",
    "summary": "Bookmark an address, or remove it with an empty comment (editor)",
    "parameters": [
     {
      "$ref": "#/components/parameters/sid"
     }
    ],
    "responses": {
     "200": {
      "description": "JSON result",
      "content": {
       "application/json": {
        "schema": {
         "type": "object",
         "additionalProperties": true,
         "description": "The read-back state after the change; a 200 means the model really holds it"
        }
       }
      }
     },
     "400": {
      "$ref": "#/components/responses/badRequest"
     },
     "404": {
      "$ref": "#/components/responses/notFound"
     },
     "default": {
      "$ref": "#/components/responses/error"
     },
     "401": {
      "$ref": "#/components/responses/unauthorized"
     }
    },
    "requestBody": {
     "required": true,
     "content": {
      "application/json": {
       "schema": {
        "$ref": "#/components/schemas/BookmarkRequest"
       }
      }
     }
    }
   }
  },
  "/api/posts": {
   "get": {
    "operationId": "listPosts",
    "summary": "Every writeup this account has written",
    "responses": {
     "200": {
      "description": "JSON result",
      "content": {
       "application/json": {
        "schema": {
         "$ref": "#/components/schemas/Post"
        }
       }
      }
     },
     "401": {
      "$ref": "#/components/responses/unauthorized"
     },
     "404": {
      "$ref": "#/components/responses/notFound"
     },
     "default": {
      "$ref": "#/components/responses/error"
     }
    }
   }
  },
  "/api/posts/{id}": {
   "delete": {
    "operationId": "deletePost",
    "summary": "Unpublish a writeup and delete the snapshot serving it (author)",
    "parameters": [
     {
      "name": "id",
      "in": "path",
      "required": true,
      "schema": {
       "type": "string"
      },
      "description": "The writeup's id."
     }
    ],
    "responses": {
     "200": {
      "description": "JSON result",
      "content": {
       "application/json": {
        "schema": {
         "$ref": "#/components/schemas/Post"
        }
       }
      }
     },
     "401": {
      "$ref": "#/components/responses/unauthorized"
     },
     "404": {
      "$ref": "#/components/responses/notFound"
     },
     "default": {
      "$ref": "#/components/responses/error"
     }
    }
   }
  },
  "/api/p/{author}/{slug}/fork": {
   "post": {
    "operationId": "forkPost",
    "summary": "Copy a published writeup's snapshot into your own account",
    "description": "Lands in your uploads, counts against your quota, and you hold creator on it -- so you can rename, comment and run agents where the writeup itself is frozen. Refused when the writeup publishes its analysis but not the sample, since a fork hands over the binary as surely as a download does.",
    "parameters": [
     {
      "name": "author",
      "in": "path",
      "required": true,
      "schema": {
       "type": "string"
      },
      "description": "The author's username, matched case-insensitively. Slugs are unique per author, so this segment is part of the post's name."
     },
     {
      "name": "slug",
      "in": "path",
      "required": true,
      "schema": {
       "type": "string"
      },
      "description": "The writeup's published slug."
     }
    ],
    "responses": {
     "200": {
      "description": "JSON result",
      "content": {
       "application/json": {
        "schema": {
         "$ref": "#/components/schemas/ForkResponse"
        }
       }
      }
     },
     "401": {
      "$ref": "#/components/responses/unauthorized"
     },
     "403": {
      "description": "This writeup does not publish its sample."
     },
     "404": {
      "$ref": "#/components/responses/notFound"
     },
     "409": {
      "description": "You are at your binary limit."
     },
     "default": {
      "$ref": "#/components/responses/error"
     }
    }
   }
  },
  "/api/p/{author}/{slug}/download": {
   "get": {
    "operationId": "downloadPostSample",
    "summary": "Download a published writeup's sample",
    "description": "The one part of a writeup that needs an account: the prose, the analysis and the MCP tools are all public, and the sample is what a reader is asked to sign up for. Refused unless the author published the sample and the gateway releases samples through published writeups.",
    "parameters": [
     {
      "name": "author",
      "in": "path",
      "required": true,
      "schema": {
       "type": "string"
      },
      "description": "The author's username, matched case-insensitively. Slugs are unique per author, so this segment is part of the post's name."
     },
     {
      "name": "slug",
      "in": "path",
      "required": true,
      "schema": {
       "type": "string"
      },
      "description": "The writeup's published slug."
     }
    ],
    "responses": {
     "200": {
      "description": "The binary.",
      "content": {
       "application/octet-stream": {
        "schema": {
         "type": "string",
         "format": "binary"
        }
       }
      }
     },
     "401": {
      "$ref": "#/components/responses/unauthorized"
     },
     "403": {
      "description": "This writeup does not release its sample."
     },
     "404": {
      "$ref": "#/components/responses/notFound"
     },
     "default": {
      "$ref": "#/components/responses/error"
     }
    }
   }
  },
  "/api/s/{sid}/post": {
   "get": {
    "operationId": "getSessionPost",
    "summary": "This session's writeup, and what publishing its notes now would produce",
    "parameters": [
     {
      "$ref": "#/components/parameters/sid"
     }
    ],
    "responses": {
     "200": {
      "description": "JSON result",
      "content": {
       "application/json": {
        "schema": {
         "$ref": "#/components/schemas/SessionPost"
        }
       }
      }
     },
     "401": {
      "$ref": "#/components/responses/unauthorized"
     },
     "404": {
      "$ref": "#/components/responses/notFound"
     },
     "default": {
      "$ref": "#/components/responses/error"
     }
    }
   },
   "post": {
    "operationId": "publishSessionPost",
    "summary": "Publish this session's notes as a writeup (creator)",
    "description": "The notes are the writeup: the prose, its title and the references that become links all come from them, so there is nothing to submit but the link and whether the sample travels. Publishing freezes a copy of the session; publishing again updates the page and keeps the link.",
    "parameters": [
     {
      "$ref": "#/components/parameters/sid"
     }
    ],
    "requestBody": {
     "required": true,
     "content": {
      "application/json": {
       "schema": {
        "type": "object",
        "properties": {
         "slug": {
          "type": "string",
          "description": "Suggested from the notes' first heading. Fixed at the first publish; ignored afterwards."
         },
         "allowDownload": {
          "type": "boolean",
          "description": "Whether readers may take the sample and open their own copy."
         }
        }
       }
      }
     }
    },
    "responses": {
     "200": {
      "description": "JSON result",
      "content": {
       "application/json": {
        "schema": {
         "$ref": "#/components/schemas/Post"
        }
       }
      }
     },
     "400": {
      "description": "The notes are empty, or the link is malformed."
     },
     "401": {
      "$ref": "#/components/responses/unauthorized"
     },
     "403": {
      "description": "Publishing needs creator access to the session."
     },
     "404": {
      "$ref": "#/components/responses/notFound"
     },
     "409": {
      "description": "That link is taken, or you are at your writeup limit."
     },
     "default": {
      "$ref": "#/components/responses/error"
     }
    }
   }
  },
  "/api/oauth/client": {
   "get": {
    "operationId": "oauthClientInfo",
    "summary": "Name of a registered OAuth client, for the consent screen",
    "parameters": [
     {
      "name": "client_id",
      "in": "query",
      "required": true,
      "schema": {
       "type": "string"
      }
     }
    ],
    "responses": {
     "200": {
      "description": "Client display name",
      "content": {
       "application/json": {
        "schema": {
         "type": "object",
         "properties": {
          "name": {
           "type": "string"
          }
         },
         "required": [
          "name"
         ]
        }
       }
      }
     },
     "default": {
      "$ref": "#/components/responses/error"
     },
     "401": {
      "$ref": "#/components/responses/unauthorized"
     }
    }
   }
  },
  "/api/oauth/approve": {
   "post": {
    "operationId": "oauthApprove",
    "summary": "Approve or deny an OAuth authorization request",
    "description": "Validates the client and redirect_uri, mints a single-use authorization code, and returns the redirect URL the browser should follow. Set deny to redirect with error=access_denied instead.",
    "requestBody": {
     "required": true,
     "content": {
      "application/json": {
       "schema": {
        "type": "object",
        "properties": {
         "client_id": {
          "type": "string"
         },
         "redirect_uri": {
          "type": "string"
         },
         "state": {
          "type": "string"
         },
         "code_challenge": {
          "type": "string"
         },
         "code_challenge_method": {
          "type": "string",
          "enum": [
           "S256"
          ]
         },
         "response_type": {
          "type": "string",
          "enum": [
           "code"
          ]
         },
         "deny": {
          "type": "boolean"
         }
        },
        "required": [
         "client_id",
         "redirect_uri"
        ]
       }
      }
     }
    },
    "responses": {
     "200": {
      "description": "Redirect URL carrying the code, or an error parameter",
      "content": {
       "application/json": {
        "schema": {
         "type": "object",
         "properties": {
          "redirect": {
           "type": "string"
          }
         },
         "required": [
          "redirect"
         ]
        }
       }
      }
     },
     "default": {
      "$ref": "#/components/responses/error"
     },
     "401": {
      "$ref": "#/components/responses/unauthorized"
     }
    }
   }
  },
  "/api/oauth/connections": {
   "get": {
    "operationId": "oauthConnections",
    "summary": "OAuth clients holding a live token for this account",
    "responses": {
     "200": {
      "description": "Connected clients",
      "content": {
       "application/json": {
        "schema": {
         "type": "array",
         "items": {
          "type": "object",
          "properties": {
           "clientId": {
            "type": "string"
           },
           "name": {
            "type": "string"
           },
           "connectedAt": {
            "type": "integer"
           },
           "lastUsedAt": {
            "type": "integer"
           }
          },
          "required": [
           "clientId",
           "name",
           "connectedAt",
           "lastUsedAt"
          ]
         }
        }
       }
      }
     },
     "default": {
      "$ref": "#/components/responses/error"
     },
     "401": {
      "$ref": "#/components/responses/unauthorized"
     }
    }
   }
  },
  "/api/oauth/connections/{cid}": {
   "delete": {
    "operationId": "oauthRevokeConnection",
    "summary": "Revoke every token one OAuth client holds for this account",
    "parameters": [
     {
      "name": "cid",
      "in": "path",
      "required": true,
      "schema": {
       "type": "string"
      }
     }
    ],
    "responses": {
     "200": {
      "description": "JSON result",
      "content": {
       "application/json": {
        "schema": {
         "$ref": "#/components/schemas/Status"
        }
       }
      }
     },
     "default": {
      "$ref": "#/components/responses/error"
     },
     "401": {
      "$ref": "#/components/responses/unauthorized"
     }
    }
   }
  },
  "/api/s/{sid}/defineddata": {
   "get": {
    "operationId": "definedData",
    "summary": "Typed globals with their values and xref counts",
    "parameters": [
     {
      "$ref": "#/components/parameters/sid"
     }
    ],
    "responses": {
     "200": {
      "description": "JSON result",
      "content": {
       "application/json": {
        "schema": {
         "type": "array",
         "items": {
          "$ref": "#/components/schemas/DefinedDataItem"
         }
        }
       }
      }
     },
     "404": {
      "$ref": "#/components/responses/notFound"
     },
     "default": {
      "$ref": "#/components/responses/error"
     },
     "401": {
      "$ref": "#/components/responses/unauthorized"
     }
    }
   }
  },
  "/api/s/{sid}/setenum": {
   "post": {
    "operationId": "setEnum",
    "summary": "Rewrite an enum's members and storage width",
    "description": "Enums do not go through /parsetypes: C cannot express an enum's storage width, so the whole definition is posted here. The enum is rebuilt at the requested width and swapped in, keeping its category and repointing every use.",
    "parameters": [
     {
      "$ref": "#/components/parameters/sid"
     }
    ],
    "requestBody": {
     "required": true,
     "content": {
      "application/json": {
       "schema": {
        "type": "object",
        "properties": {
         "name": {
          "type": "string",
          "description": "Name of an existing enum."
         },
         "width": {
          "type": "integer",
          "enum": [
           1,
           2,
           4,
           8
          ],
          "description": "Storage width in bytes."
         },
         "members": {
          "type": "array",
          "maxItems": 512,
          "items": {
           "type": "object",
           "properties": {
            "name": {
             "type": "string"
            },
            "value": {
             "type": "integer"
            }
           },
           "required": [
            "name",
            "value"
           ],
           "additionalProperties": false
          }
         }
        },
        "required": [
         "name",
         "width",
         "members"
        ],
        "additionalProperties": false
       }
      }
     }
    },
    "responses": {
     "200": {
      "description": "The saved enum",
      "content": {
       "application/json": {
        "schema": {
         "$ref": "#/components/schemas/TypeDetail"
        }
       }
      }
     },
     "404": {
      "$ref": "#/components/responses/notFound"
     },
     "default": {
      "$ref": "#/components/responses/error"
     },
     "401": {
      "$ref": "#/components/responses/unauthorized"
     }
    }
   }
  }
 },
 "components": {
  "securitySchemes": {
   "bearerAuth": {
    "type": "http",
    "scheme": "bearer",
    "description": "Token from POST /api/auth/login"
   }
  },
  "parameters": {
   "sid": {
    "name": "sid",
    "in": "path",
    "required": true,
    "description": "Session id, from GET /api/sessions or the upload response",
    "schema": {
     "type": "string"
    }
   },
   "addr": {
    "name": "addr",
    "in": "query",
    "required": true,
    "description": "Address as a 0x-prefixed hex string, e.g. 0x401000. Function endpoints accept any address inside the function.",
    "schema": {
     "type": "string",
     "pattern": "^(0x)?[0-9a-fA-F]+$"
    }
   }
  },
  "responses": {
   "badRequest": {
    "description": "Malformed parameter or body (bad address, out-of-range number)",
    "content": {
     "application/json": {
      "schema": {
       "$ref": "#/components/schemas/Error"
      }
     }
    }
   },
   "notFound": {
    "description": "Nothing there: unknown session or token, or nothing at that address",
    "content": {
     "application/json": {
      "schema": {
       "$ref": "#/components/schemas/Error"
      }
     }
    }
   },
   "error": {
    "description": "Any other failure, same {error} shape. 409: uploaded but not analysed yet. 503: the gateway is at capacity or the session's worker is unavailable; retry later.",
    "content": {
     "application/json": {
      "schema": {
       "$ref": "#/components/schemas/Error"
      }
     }
    }
   },
   "unauthorized": {
    "description": "No token, or a revoked one; sign in again",
    "content": {
     "application/json": {
      "schema": {
       "$ref": "#/components/schemas/Error"
      }
     }
    }
   }
  },
  "schemas": {
   "Error": {
    "type": "object",
    "properties": {
     "error": {
      "type": "string",
      "description": "What went wrong, as a sentence"
     }
    },
    "additionalProperties": false,
    "required": [
     "error"
    ]
   },
   "Info": {
    "type": "object",
    "properties": {
     "core": {
      "type": "object",
      "properties": {
       "file": {
        "type": "string",
        "description": "Display name"
       },
       "format": {
        "type": "string",
        "description": "Container format, e.g. ELF or PE"
       },
       "humansz": {
        "type": "string",
        "description": "Human-readable size"
       },
       "size": {
        "type": "integer",
        "description": "Size in bytes"
       }
      },
      "additionalProperties": true
     },
     "bin": {
      "type": "object",
      "properties": {
       "arch": {
        "type": "string"
       },
       "bits": {
        "type": "integer"
       },
       "endian": {
        "type": "string",
        "enum": [
         "little",
         "big"
        ]
       },
       "baddr": {
        "type": "integer",
        "description": "Image base address"
       },
       "bintype": {
        "type": "string"
       },
       "compiler": {
        "type": "string"
       },
       "language": {
        "type": "string",
        "description": "Ghidra language id, e.g. x86:LE:64:default"
       },
       "canary": {
        "type": "boolean"
       },
       "nx": {
        "type": "boolean"
       },
       "pic": {
        "type": "boolean"
       },
       "relocs": {
        "type": "boolean"
       },
       "relro": {
        "type": "string"
       },
       "static": {
        "type": "boolean"
       },
       "stripped": {
        "type": "boolean"
       }
      },
      "additionalProperties": true
     }
    },
    "additionalProperties": false,
    "required": [
     "core",
     "bin"
    ]
   },
   "Overview": {
    "type": "object",
    "properties": {
     "functions": {
      "type": "integer"
     },
     "xrefs": {
      "type": "integer"
     },
     "calls": {
      "type": "integer"
     },
     "strings": {
      "type": "integer"
     },
     "symbols": {
      "type": "integer"
     },
     "imports": {
      "type": "integer"
     }
    },
    "additionalProperties": false
   },
   "Triage": {
    "type": "object",
    "properties": {
     "items": {
      "type": "array",
      "items": {
       "type": "object",
       "properties": {
        "addr": {
         "type": "string",
         "description": "Function entry point as a 0x-prefixed hex string (unlike list endpoints, which return decimal offsets)"
        },
        "name": {
         "type": "string"
        },
        "size": {
         "type": "integer",
         "description": "Function size in bytes"
        },
        "score": {
         "type": "integer",
         "description": "Rank score; higher means more worth reading first"
        },
        "reasons": {
         "type": "array",
         "items": {
          "type": "string"
         },
         "description": "Why it ranked, e.g. 'exported entry point', 'complex'"
        }
       },
       "additionalProperties": false
      }
     },
     "ranked": {
      "type": "integer",
      "description": "How many functions scored above zero"
     },
     "total": {
      "type": "integer",
      "description": "How many functions exist"
     }
    },
    "additionalProperties": false,
    "required": [
     "items",
     "ranked",
     "total"
    ]
   },
   "Hashes": {
    "type": "object",
    "properties": {
     "md5": {
      "type": "string"
     },
     "sha1": {
      "type": "string"
     },
     "sha256": {
      "type": "string"
     },
     "crc32": {
      "type": "string"
     },
     "entropy": {
      "type": "string",
      "description": "Whole-file Shannon entropy, 0-8 bits per byte"
     }
    },
    "additionalProperties": false
   },
   "EntropyBucket": {
    "type": "object",
    "properties": {
     "addr": {
      "type": "integer",
      "description": "Address as a decimal byte offset in the program's address space. Render as hex for display; pass back to addr parameters as a 0x-prefixed hex string."
     },
     "size": {
      "type": "integer",
      "description": "Bytes sampled in this bucket"
     },
     "section": {
      "type": "string",
      "description": "Memory block the bucket lies in; buckets never straddle blocks"
     },
     "entropy": {
      "type": "number",
      "description": "Shannon entropy of the bucket, 0-8 bits per byte"
     }
    },
    "additionalProperties": false
   },
   "Section": {
    "type": "object",
    "properties": {
     "name": {
      "type": "string"
     },
     "size": {
      "type": "integer",
      "description": "File size"
     },
     "vsize": {
      "type": "integer",
      "description": "Size in memory"
     },
     "type": {
      "type": "string"
     },
     "perm": {
      "type": "string",
      "description": "Permissions as rwx string, e.g. 'r-x'"
     },
     "flags": {
      "type": "integer"
     },
     "vaddr": {
      "type": "integer",
      "description": "Address as a decimal byte offset in the program's address space. Render as hex for display; pass back to addr parameters as a 0x-prefixed hex string."
     },
     "paddr": {
      "type": "integer",
      "description": "File offset"
     },
     "loaded": {
      "type": "boolean"
     }
    },
    "additionalProperties": false
   },
   "Function": {
    "type": "object",
    "properties": {
     "addr": {
      "type": "integer",
      "description": "Address as a decimal byte offset in the program's address space. Render as hex for display; pass back to addr parameters as a 0x-prefixed hex string."
     },
     "name": {
      "type": "string"
     },
     "size": {
      "type": "integer",
      "description": "Bytes in the function body"
     },
     "end": {
      "type": "integer",
      "description": "Last address, decimal"
     },
     "nbbs": {
      "type": "integer",
      "description": "Basic block count"
     },
     "cc": {
      "type": "integer",
      "description": "Cyclomatic complexity"
     },
     "ninstrs": {
      "type": "integer",
      "description": "Instruction count"
     },
     "indegree": {
      "type": "integer",
      "description": "How many functions call this one"
     }
    },
    "additionalProperties": false
   },
   "Op": {
    "type": "object",
    "properties": {
     "addr": {
      "type": "integer",
      "description": "Address as a decimal byte offset in the program's address space. Render as hex for display; pass back to addr parameters as a 0x-prefixed hex string."
     },
     "bytes": {
      "type": "string",
      "description": "Instruction bytes as lowercase hex"
     },
     "disasm": {
      "type": "string"
     },
     "opcode": {
      "type": "string"
     }
    },
    "additionalProperties": false
   },
   "Disasm": {
    "type": "object",
    "properties": {
     "addr": {
      "type": "integer",
      "description": "Address as a decimal byte offset in the program's address space. Render as hex for display; pass back to addr parameters as a 0x-prefixed hex string."
     },
     "name": {
      "type": "string",
      "description": "Containing function"
     },
     "size": {
      "type": "integer"
     },
     "ops": {
      "type": "array",
      "items": {
       "$ref": "#/components/schemas/Op"
      }
     }
    },
    "additionalProperties": false
   },
   "Decompile": {
    "type": "object",
    "properties": {
     "lines": {
      "type": "array",
      "items": {
       "type": "object",
       "properties": {
        "str": {
         "type": "string",
         "description": "One line of C"
        },
        "offset": {
         "type": "integer",
         "description": "Address the line maps to, decimal; absent on lines with no location"
        }
       },
       "additionalProperties": false,
       "required": [
        "str"
       ]
      }
     },
     "annotatedVars": {
      "type": "array",
      "items": {
       "type": "string"
      },
      "description": "Variable and symbol names appearing in the listing"
     }
    },
    "additionalProperties": false,
    "required": [
     "lines"
    ]
   },
   "Vars": {
    "type": "object",
    "properties": {
     "reg": {
      "type": "array",
      "items": {
       "$ref": "#/components/schemas/Var"
      },
      "description": "Register-backed variables"
     },
     "sp": {
      "type": "array",
      "items": {
       "$ref": "#/components/schemas/Var"
      },
      "description": "Stack variables"
     },
     "bp": {
      "type": "array",
      "items": {
       "$ref": "#/components/schemas/Var"
      },
      "description": "Frame-base variables"
     }
    },
    "additionalProperties": false
   },
   "Var": {
    "type": "object",
    "properties": {
     "name": {
      "type": "string"
     },
     "type": {
      "type": "string"
     },
     "kind": {
      "type": "string",
      "enum": [
       "arg",
       "var"
      ]
     },
     "ref": {
      "type": "string",
      "description": "Storage location, e.g. 'RDI:8' or a stack offset"
     }
    },
    "additionalProperties": false
   },
   "Graph": {
    "type": "object",
    "properties": {
     "name": {
      "type": "string",
      "description": "Function name"
     },
     "addr": {
      "type": "integer",
      "description": "Address as a decimal byte offset in the program's address space. Render as hex for display; pass back to addr parameters as a 0x-prefixed hex string."
     },
     "blocks": {
      "type": "array",
      "items": {
       "type": "object",
       "properties": {
        "addr": {
         "type": "integer",
         "description": "Address as a decimal byte offset in the program's address space. Render as hex for display; pass back to addr parameters as a 0x-prefixed hex string."
        },
        "size": {
         "type": "integer",
         "description": "Addresses spanned"
        },
        "jump": {
         "type": "integer",
         "description": "Branch-taken successor, decimal; absent when none"
        },
        "fail": {
         "type": "integer",
         "description": "Fall-through successor, decimal; absent when none"
        },
        "ops": {
         "type": "array",
         "items": {
          "$ref": "#/components/schemas/Op"
         }
        }
       },
       "additionalProperties": false,
       "required": [
        "addr",
        "size",
        "ops"
       ]
      }
     }
    },
    "additionalProperties": false
   },
   "Xref": {
    "type": "object",
    "properties": {
     "from": {
      "type": "integer",
      "description": "Referencing address, decimal"
     },
     "type": {
      "type": "string",
      "description": "Reference type, e.g. CALL, READ, WRITE, JUMP"
     },
     "opcode": {
      "type": "string",
      "description": "Disassembly at the referencing address"
     },
     "fcn_name": {
      "type": "string",
      "description": "Function containing the reference, when any"
     },
     "realname": {
      "type": "string"
     }
    },
    "additionalProperties": false
   },
   "CallTree": {
    "type": "object",
    "properties": {
     "incoming": {
      "type": "array",
      "items": {
       "$ref": "#/components/schemas/NamedAddr"
      },
      "description": "Functions that call this one"
     },
     "outgoing": {
      "type": "array",
      "items": {
       "$ref": "#/components/schemas/NamedAddr"
      },
      "description": "Functions this one calls"
     }
    },
    "additionalProperties": false
   },
   "CallGraphNode": {
    "type": "object",
    "properties": {
     "addr": {
      "type": "integer",
      "description": "Entry point, decimal"
     },
     "name": {
      "type": "string"
     },
     "callees": {
      "type": "array",
      "items": {
       "type": "string"
      },
      "description": "Functions this one calls, by name; empty for leaves"
     }
    },
    "additionalProperties": false
   },
   "NamedAddr": {
    "type": "object",
    "properties": {
     "addr": {
      "type": "integer",
      "description": "Address as a decimal byte offset in the program's address space. Render as hex for display; pass back to addr parameters as a 0x-prefixed hex string."
     },
     "name": {
      "type": "string"
     }
    },
    "additionalProperties": false
   },
   "Instruction": {
    "type": "object",
    "properties": {
     "addr": {
      "type": "integer",
      "description": "Address as a decimal byte offset in the program's address space. Render as hex for display; pass back to addr parameters as a 0x-prefixed hex string."
     },
     "mnemonic": {
      "type": "string"
     },
     "text": {
      "type": "string"
     },
     "length": {
      "type": "integer"
     },
     "flow": {
      "type": "string",
      "description": "Control-flow class, e.g. FALL_THROUGH, UNCONDITIONAL_CALL"
     },
     "bytes": {
      "type": "string",
      "description": "Encoding as lowercase hex"
     },
     "operands": {
      "type": "array",
      "items": {
       "type": "object",
       "properties": {
        "text": {
         "type": "string"
        },
        "type": {
         "type": "string"
        },
        "refers": {
         "type": "integer",
         "description": "Address the operand refers to, decimal; absent when none"
        }
       },
       "additionalProperties": false,
       "required": [
        "text",
        "type"
       ]
      }
     },
     "pcode": {
      "type": "array",
      "items": {
       "type": "string"
      },
      "description": "The instruction's p-code ops, one string each"
     }
    },
    "additionalProperties": false
   },
   "ResolveAddr": {
    "type": "object",
    "properties": {
     "addr": {
      "type": "integer",
      "description": "Address as a decimal byte offset in the program's address space. Render as hex for display; pass back to addr parameters as a 0x-prefixed hex string."
     },
     "name": {
      "type": "string",
      "description": "Containing function"
     },
     "size": {
      "type": "integer"
     },
     "end": {
      "type": "integer"
     }
    },
    "additionalProperties": false
   },
   "Signature": {
    "type": "object",
    "properties": {
     "addr": {
      "type": "integer",
      "description": "Address as a decimal byte offset in the program's address space. Render as hex for display; pass back to addr parameters as a 0x-prefixed hex string."
     },
     "name": {
      "type": "string"
     },
     "signature": {
      "type": "string",
      "description": "Full C prototype"
     },
     "callingConvention": {
      "type": "string"
     },
     "callingConventions": {
      "type": "array",
      "items": {
       "type": "string"
      },
      "description": "Conventions this program accepts"
     }
    },
    "additionalProperties": false
   },
   "StringItem": {
    "type": "object",
    "properties": {
     "vaddr": {
      "type": "integer",
      "description": "Address as a decimal byte offset in the program's address space. Render as hex for display; pass back to addr parameters as a 0x-prefixed hex string."
     },
     "paddr": {
      "type": "integer",
      "description": "File offset"
     },
     "size": {
      "type": "integer",
      "description": "Bytes including terminator"
     },
     "length": {
      "type": "integer",
      "description": "Characters"
     },
     "section": {
      "type": "string"
     },
     "type": {
      "type": "string",
      "description": "E.g. TerminatedCString, unicode"
     },
     "string": {
      "type": "string",
      "description": "The text itself"
     }
    },
    "additionalProperties": false
   },
   "Symbol": {
    "type": "object",
    "properties": {
     "name": {
      "type": "string"
     },
     "flagname": {
      "type": "string"
     },
     "realname": {
      "type": "string"
     },
     "ordinal": {
      "type": "integer"
     },
     "bind": {
      "type": "string"
     },
     "type": {
      "type": "string"
     },
     "size": {
      "type": "integer"
     },
     "vaddr": {
      "type": "integer",
      "description": "Address as a decimal byte offset in the program's address space. Render as hex for display; pass back to addr parameters as a 0x-prefixed hex string."
     },
     "paddr": {
      "type": "integer"
     },
     "is_imported": {
      "type": "boolean"
     }
    },
    "additionalProperties": false
   },
   "Import": {
    "type": "object",
    "properties": {
     "ordinal": {
      "type": "integer"
     },
     "bind": {
      "type": "string"
     },
     "type": {
      "type": "string"
     },
     "name": {
      "type": "string"
     },
     "plt": {
      "type": "integer",
      "description": "Thunk address, decimal"
     }
    },
    "additionalProperties": false
   },
   "Types": {
    "type": "object",
    "properties": {
     "types": {
      "type": "array",
      "items": {
       "type": "object",
       "properties": {
        "type": {
         "type": "string",
         "description": "Type name"
        },
        "size": {
         "type": "integer",
         "description": "Bytes"
        },
        "format": {
         "type": "string",
         "description": "Category path in Ghidra's type manager"
        },
        "kind": {
         "type": "string",
         "description": "struct, union, enum, typedef, funcdef, pointer, array or builtin"
        }
       },
       "additionalProperties": false
      }
     }
    },
    "additionalProperties": false
   },
   "SearchHit": {
    "type": "object",
    "properties": {
     "addr": {
      "type": "integer",
      "description": "Address as a decimal byte offset in the program's address space. Render as hex for display; pass back to addr parameters as a 0x-prefixed hex string."
     },
     "type": {
      "type": "string",
      "description": "What matched: string, bytes, or similar"
     },
     "data": {
      "type": "string",
      "description": "The matching text or bytes"
     }
    },
    "additionalProperties": false
   },
   "Comment": {
    "type": "object",
    "properties": {
     "offset": {
      "type": "integer",
      "description": "Address, decimal"
     },
     "name": {
      "type": "string",
      "description": "The comment text"
     },
     "author": {
      "type": "string",
      "description": "Username that wrote it"
     },
     "at": {
      "type": "integer",
      "description": "Unix epoch milliseconds"
     }
    },
    "additionalProperties": false
   },
   "Label": {
    "type": "object",
    "properties": {
     "addr": {
      "type": "integer",
      "description": "Address as a decimal byte offset in the program's address space. Render as hex for display; pass back to addr parameters as a 0x-prefixed hex string."
     },
     "name": {
      "type": "string"
     },
     "user": {
      "type": "boolean",
      "description": "True when a person named it rather than analysis"
     }
    },
    "additionalProperties": false
   },
   "Bookmark": {
    "type": "object",
    "properties": {
     "addr": {
      "type": "integer",
      "description": "Address as a decimal byte offset in the program's address space. Render as hex for display; pass back to addr parameters as a 0x-prefixed hex string."
     },
     "category": {
      "type": "string"
     },
     "comment": {
      "type": "string"
     }
    },
    "additionalProperties": false
   },
   "ChatMessage": {
    "type": "object",
    "properties": {
     "id": {
      "type": "string"
     },
     "role": {
      "type": "string",
      "enum": [
       "user",
       "agent",
       "system"
      ]
     },
     "author": {
      "type": "string"
     },
     "text": {
      "type": "string",
      "description": "Markdown"
     },
     "at": {
      "type": "integer",
      "description": "Unix epoch milliseconds"
     }
    },
    "additionalProperties": false
   },
   "Notes": {
    "type": "object",
    "properties": {
     "text": {
      "type": "string",
      "description": "The shared session notes, markdown"
     }
    },
    "additionalProperties": false,
    "required": [
     "text"
    ]
   },
   "ActivityEvent": {
    "type": "object",
    "properties": {
     "type": {
      "type": "string",
      "description": "Event name, e.g. functionRenamed, commentsChanged, notesChanged"
     },
     "userId": {
      "type": "string",
      "description": "Who did it"
     },
     "addr": {
      "type": "string",
      "description": "Affected address when the event has one, 0x-prefixed hex"
     },
     "command": {
      "type": "string"
     },
     "timestamp": {
      "type": "integer",
      "description": "Unix epoch milliseconds"
     }
    },
    "additionalProperties": true
   },
   "Layout": {
    "description": "The creator's saved dock layout, or null when none was saved. An opaque frontend structure; not useful outside the workspace.",
    "type": [
     "object",
     "null"
    ],
    "additionalProperties": true
   },
   "PublicUser": {
    "type": "object",
    "properties": {
     "id": {
      "type": "string"
     },
     "username": {
      "type": "string"
     },
     "role": {
      "type": "string",
      "description": "Account role on the gateway"
     }
    },
    "additionalProperties": false,
    "required": [
     "id",
     "username",
     "role"
    ]
   },
   "LoginRequest": {
    "type": "object",
    "properties": {
     "username": {
      "type": "string"
     },
     "password": {
      "type": "string"
     }
    },
    "additionalProperties": false,
    "required": [
     "username",
     "password"
    ]
   },
   "LoginResponse": {
    "type": "object",
    "properties": {
     "token": {
      "type": "string",
      "description": "Bearer token for every authenticated call"
     },
     "user": {
      "$ref": "#/components/schemas/PublicUser"
     }
    },
    "additionalProperties": false,
    "required": [
     "token",
     "user"
    ]
   },
   "SessionInfo": {
    "type": "object",
    "properties": {
     "id": {
      "type": "string",
      "description": "Session id, the {sid} in every session route"
     },
     "name": {
      "type": "string",
      "description": "The binary's display name"
     },
     "status": {
      "type": "string",
      "enum": [
       "pending",
       "queued",
       "analyzing",
       "ready",
       "errored"
      ]
     },
     "error": {
      "type": "string",
      "description": "Why the session is errored, when it is"
     },
     "yourRole": {
      "type": "string",
      "enum": [
       "viewer",
       "editor",
       "creator"
      ],
      "description": "Session role"
     },
     "ownerUserId": {
      "type": "string",
      "description": "Immutable catalog owner account id"
     },
     "storageVersion": {
      "type": "integer",
      "description": "Workspace storage layout version"
     },
     "hasSymbols": {
      "type": "boolean",
      "description": "Whether debug symbols are loaded"
     },
     "defaultBackend": {
      "type": "string",
      "description": "Decompiler backend chosen at analysis time, when one was"
     },
     "resident": {
      "type": "boolean",
      "description": "Whether a worker is held right now; false means opening waits for a slot"
     },
     "queueReason": {
      "type": "string",
      "enum": [
       "analysis",
       "capacity"
      ],
      "description": "Which queue a queued session is in"
     },
     "openError": {
      "type": "string",
      "description": "Why the last open gave up, for a reason that will pass"
     }
    },
    "additionalProperties": false,
    "required": [
     "id",
     "name",
     "status"
    ]
   },
   "GatewayCapacity": {
    "type": "object",
    "properties": {
     "resident": {
      "type": "integer",
      "description": "Worker slots held"
     },
     "maxResident": {
      "type": "integer"
     },
     "analyzing": {
      "type": "integer"
     },
     "analysisSlots": {
      "type": "integer"
     },
     "yourResident": {
      "type": "integer",
      "description": "This account's own residents; 0 when the per-account limit is off"
     },
     "yourMax": {
      "type": "integer",
      "description": "This account's allowance; 0 when off"
     }
    },
    "additionalProperties": false
   },
   "Status": {
    "type": "object",
    "properties": {
     "status": {
      "type": "string"
     }
    },
    "additionalProperties": false,
    "required": [
     "status"
    ]
   },
   "ShareResponse": {
    "type": "object",
    "properties": {
     "token": {
      "type": "string",
      "description": "The share token; empty means not shared. The link is app.reverser.space/v/{token}"
     }
    },
    "additionalProperties": false,
    "required": [
     "token"
    ]
   },
   "AccessEntry": {
    "type": "object",
    "properties": {
     "userId": {
      "type": "string"
     },
     "username": {
      "type": "string"
     },
     "role": {
      "type": "string",
      "enum": [
       "viewer",
       "editor",
       "creator"
      ],
      "description": "Session role"
     }
    },
    "additionalProperties": false
   },
   "GrantAccessRequest": {
    "type": "object",
    "properties": {
     "username": {
      "type": "string",
      "description": "Account to grant"
     },
     "role": {
      "type": "string",
      "enum": [
       "viewer",
       "editor"
      ],
      "description": "Shared access role; creator is reserved for the catalog owner"
     }
    },
    "additionalProperties": false,
    "required": [
     "username",
     "role"
    ]
   },
   "StageSymbolsResult": {
    "type": "object",
    "properties": {
     "staged": {
      "type": "boolean"
     },
     "appliedOnAnalysis": {
      "type": "boolean",
      "description": "True when the session is still pending, so analysis will use the file; false means it was stored but the session was already analysed"
     }
    },
    "additionalProperties": false
   },
   "AnalyzeRequest": {
    "type": "object",
    "properties": {
     "backend": {
      "type": "string",
      "description": "Decompiler backend the workspace should open with; absent leaves the default"
     }
    },
    "additionalProperties": false
   },
   "DeleteSessionRequest": {
    "type": "object",
    "properties": {
     "confirm": {
      "type": "string",
      "description": "The binary's display name, typed back to confirm"
     }
    },
    "additionalProperties": false,
    "required": [
     "confirm"
    ]
   },
   "PublicAgent": {
    "type": "object",
    "properties": {
     "name": {
      "type": "string"
     },
     "provider": {
      "type": "string",
      "enum": [
       "gemini",
       "openai"
      ]
     },
     "model": {
      "type": "string"
     },
     "roleCeiling": {
      "type": "string",
      "enum": [
       "viewer",
       "editor",
       "creator"
      ],
      "description": "Session role"
     }
    },
    "additionalProperties": false
   },
   "InviteAgentRequest": {
    "type": "object",
    "properties": {
     "agent": {
      "type": "string",
      "description": "Agent name from GET /api/agents"
     },
     "task": {
      "type": "string",
      "description": "What to work on; optional"
     }
    },
    "additionalProperties": false,
    "required": [
     "agent"
    ]
   },
   "AgentCred": {
    "type": "object",
    "properties": {
     "id": {
      "type": "string"
     },
     "agent": {
      "type": "string"
     },
     "grantedBy": {
      "type": "string",
      "description": "Username"
     },
     "role": {
      "type": "string",
      "enum": [
       "viewer",
       "editor",
       "creator"
      ],
      "description": "Session role"
     },
     "expiresAt": {
      "type": "integer",
      "description": "Unix epoch milliseconds"
     }
    },
    "additionalProperties": false
   },
   "ActiveRun": {
    "type": "object",
    "properties": {
     "id": {
      "type": "string"
     },
     "sessionId": {
      "type": "string"
     },
     "agent": {
      "type": "string"
     },
     "startedBy": {
      "type": "string",
      "description": "Account id whose authority the run acts under"
     },
     "startedByName": {
      "type": "string",
      "description": "Username of startedBy"
     },
     "startedAt": {
      "type": "integer",
      "description": "Unix epoch milliseconds"
     }
    },
    "additionalProperties": false
   },
   "StartedRun": {
    "type": "object",
    "properties": {
     "status": {
      "type": "string",
      "enum": [
       "started"
      ]
     },
     "runId": {
      "type": "string"
     }
    },
    "additionalProperties": false,
    "required": [
     "status",
     "runId"
    ]
   },
   "SendChatRequest": {
    "type": "object",
    "properties": {
     "agent": {
      "type": "string",
      "description": "Which agent to address, from GET /api/agents"
     },
     "text": {
      "type": "string",
      "description": "The message; markdown"
     }
    },
    "additionalProperties": false,
    "required": [
     "agent",
     "text"
    ]
   },
   "AgentPeer": {
    "type": "object",
    "properties": {
     "kind": {
      "type": "string"
     },
     "userId": {
      "type": "string"
     },
     "name": {
      "type": "string",
      "description": "Agent name"
     },
     "addr": {
      "type": "integer",
      "description": "Where it was last seen, decimal"
     },
     "pane": {
      "type": "string",
      "description": "Which panel it was in"
     },
     "agent": {
      "type": "boolean"
     },
     "idle": {
      "type": "boolean"
     }
    },
    "additionalProperties": true
   },
   "KeyStatus": {
    "type": "object",
    "properties": {
     "enabled": {
      "type": "boolean",
      "description": "Whether this gateway can store keys at all (a KEK is configured)"
     },
     "providers": {
      "type": "array",
      "items": {
       "type": "object",
       "properties": {
        "provider": {
         "type": "string",
         "enum": [
          "gemini",
          "openai"
         ]
        },
        "hasKey": {
         "type": "boolean",
         "description": "Whether this account stored a key"
        },
        "pooled": {
         "type": "boolean",
         "description": "Whether runs are operator-funded when this account stores no key"
        }
       },
       "additionalProperties": false
      }
     }
    },
    "additionalProperties": false
   },
   "SetKeyRequest": {
    "type": "object",
    "properties": {
     "provider": {
      "type": "string",
      "enum": [
       "gemini",
       "openai"
      ]
     },
     "key": {
      "type": "string",
      "description": "The provider API key; stored encrypted, never read back"
     }
    },
    "additionalProperties": false,
    "required": [
     "provider",
     "key"
    ]
   },
   "AutorunSetting": {
    "type": "object",
    "properties": {
     "enabled": {
      "type": "boolean"
     },
     "agent": {
      "type": "string",
      "description": "Which agent runs on each of this account's uploads"
     },
     "role": {
      "type": "string",
      "enum": [
       "viewer",
       "editor",
       "creator"
      ],
      "description": "Session role"
     }
    },
    "additionalProperties": false
   },
   "RenameRequest": {
    "type": "object",
    "properties": {
     "addr": {
      "type": "string",
      "description": "0x-prefixed hex"
     },
     "name": {
      "type": "string",
      "description": "New function name"
     }
    },
    "additionalProperties": false,
    "required": [
     "addr",
     "name"
    ]
   },
   "RenameVarRequest": {
    "type": "object",
    "properties": {
     "addr": {
      "type": "string",
      "description": "0x-prefixed hex, inside the function"
     },
     "oldName": {
      "type": "string"
     },
     "newName": {
      "type": "string"
     }
    },
    "additionalProperties": false,
    "required": [
     "addr",
     "oldName",
     "newName"
    ]
   },
   "RetypeVarRequest": {
    "type": "object",
    "properties": {
     "addr": {
      "type": "string",
      "description": "0x-prefixed hex, inside the function"
     },
     "name": {
      "type": "string",
      "description": "Variable name"
     },
     "type": {
      "type": "string",
      "description": "C type, e.g. 'char *'"
     }
    },
    "additionalProperties": false,
    "required": [
     "addr",
     "name",
     "type"
    ]
   },
   "CommentRequest": {
    "type": "object",
    "properties": {
     "addr": {
      "type": "string",
      "description": "0x-prefixed hex"
     },
     "text": {
      "type": "string",
      "description": "Empty deletes nothing; use DELETE /comment for that"
     }
    },
    "additionalProperties": false,
    "required": [
     "addr",
     "text"
    ]
   },
   "LabelRequest": {
    "type": "object",
    "properties": {
     "addr": {
      "type": "string",
      "description": "0x-prefixed hex"
     },
     "name": {
      "type": "string",
      "description": "Empty clears the label"
     }
    },
    "additionalProperties": false,
    "required": [
     "addr",
     "name"
    ]
   },
   "DataRequest": {
    "type": "object",
    "properties": {
     "addr": {
      "type": "string",
      "description": "0x-prefixed hex"
     },
     "type": {
      "type": "string",
      "description": "Type to define the bytes as; empty clears the definition"
     }
    },
    "additionalProperties": false,
    "required": [
     "addr",
     "type"
    ]
   },
   "BookmarkRequest": {
    "type": "object",
    "properties": {
     "addr": {
      "type": "string",
      "description": "0x-prefixed hex"
     },
     "category": {
      "type": "string"
     },
     "comment": {
      "type": "string",
      "description": "Empty removes the bookmark"
     }
    },
    "additionalProperties": false,
    "required": [
     "addr",
     "comment"
    ]
   },
   "SignatureRequest": {
    "type": "object",
    "properties": {
     "addr": {
      "type": "string",
      "description": "0x-prefixed hex"
     },
     "signature": {
      "type": "string",
      "description": "Full C prototype"
     },
     "callingConvention": {
      "type": "string"
     }
    },
    "additionalProperties": false,
    "required": [
     "addr",
     "signature"
    ]
   },
   "SetNotesRequest": {
    "type": "object",
    "properties": {
     "text": {
      "type": "string",
      "description": "The whole notes text; this replaces, not appends"
     }
    },
    "additionalProperties": false,
    "required": [
     "text"
    ]
   },
   "Post": {
    "type": "object",
    "description": "A writeup bound to a frozen copy of a session. Drafts have no slug and no snapshot; both are settled at publish.",
    "properties": {
     "id": {
      "type": "string"
     },
     "slug": {
      "type": "string",
      "description": "Its published URL is /p/{slug}. Absent while it is a draft, immutable once set."
     },
     "authorId": {
      "type": "string"
     },
     "sourceSessionId": {
      "type": "string",
      "description": "The session it was written against."
     },
     "snapshotSessionId": {
      "type": "string",
      "description": "The frozen copy readers reach. It carries no grants, so every caller -- the author included -- reads it at viewer through the share token."
     },
     "title": {
      "type": "string"
     },
     "summary": {
      "type": "string"
     },
     "allowDownload": {
      "type": "boolean",
      "description": "Whether readers may pull the sample itself, as opposed to exploring the analysis."
     },
     "meta": {
      "type": "object",
      "description": "Sample frontmatter stamped at publish: sha256, size, format, arch, bits."
     },
     "createdAt": {
      "type": "integer",
      "format": "int64"
     },
     "updatedAt": {
      "type": "integer",
      "format": "int64"
     },
     "publishedAt": {
      "type": "integer",
      "format": "int64"
     }
    }
   },
   "PublicPost": {
    "type": "object",
    "description": "A published writeup as a reader loads it: rendered prose plus everything needed to reach the frozen session it argues about.",
    "properties": {
     "slug": {
      "type": "string"
     },
     "title": {
      "type": "string"
     },
     "summary": {
      "type": "string"
     },
     "html": {
      "type": "string",
      "description": "The prose, rendered at publish. References are anchors carrying revspace-addr: / revspace-fn: hrefs."
     },
     "token": {
      "type": "string",
      "description": "The share token for the frozen session: the reader's whole capability."
     },
     "mcpUrl": {
      "type": "string",
      "description": "The post's MCP endpoint, so a reader's own agent can read the sample."
     },
     "meta": {
      "type": "object"
     },
     "allowDownload": {
      "type": "boolean"
     },
     "publishedAt": {
      "type": "integer",
      "format": "int64"
     },
     "updatedAt": {
      "type": "integer",
      "format": "int64"
     }
    }
   },
   "ForkResponse": {
    "type": "object",
    "description": "The reader's own copy of a writeup's snapshot.",
    "properties": {
     "sessionId": {
      "type": "string",
      "description": "The new session, which the caller holds creator on."
     },
     "name": {
      "type": "string"
     },
     "existing": {
      "type": "boolean",
      "description": "True when the caller already held these bytes and was handed their own existing session instead of a fresh copy, so their work on it is not overwritten."
     }
    }
   },
   "SessionPost": {
    "type": "object",
    "description": "A session's writeup, if it has one, and what publishing its notes right now would produce.",
    "properties": {
     "post": {
      "$ref": "#/components/schemas/Post"
     },
     "title": {
      "type": "string",
      "description": "Read live off the notes: their first heading, or the binary's name."
     },
     "slug": {
      "type": "string",
      "description": "The published link, or a suggestion when there is not one yet."
     },
     "notes": {
      "type": "integer",
      "description": "Characters of notes, so a caller can tell there is nothing to publish."
     },
     "canPublish": {
      "type": "boolean",
      "description": "Whether the caller holds creator on the session."
     },
     "token": {
      "type": "string",
      "description": "The published snapshot's share token, once there is one."
     }
    }
   },
   "TypeDetail": {
    "type": "object",
    "properties": {
     "name": {
      "type": "string",
      "description": "Category path of the type"
     },
     "kind": {
      "type": "string",
      "description": "struct, union, enum, typedef, funcdef, pointer, array or builtin"
     },
     "size": {
      "type": "integer",
      "description": "Bytes"
     },
     "base": {
      "type": "string",
      "description": "Underlying type; typedefs only"
     },
     "members": {
      "type": "array",
      "description": "Fields for a struct or union, values for an enum",
      "items": {
       "type": "object",
       "properties": {
        "offset": {
         "type": "integer",
         "description": "Byte offset; composites only"
        },
        "name": {
         "type": "string",
         "description": "Field or constant name"
        },
        "type": {
         "type": "string",
         "description": "Field type; composites only"
        },
        "size": {
         "type": "integer",
         "description": "Field size; composites only"
        },
        "comment": {
         "type": "string",
         "description": "Field comment; composites only"
        },
        "value": {
         "type": "integer",
         "description": "Constant value; enums only"
        }
       }
      }
     }
    }
   },
   "ParseTypesRequest": {
    "type": "object",
    "properties": {
     "source": {
      "type": "string",
      "description": "C declarations: structs, unions, enums, typedefs"
     },
     "replace": {
      "type": "boolean",
      "description": "Overwrite types that already exist; without it a clash is a 409"
     }
    },
    "additionalProperties": false,
    "required": [
     "source"
    ]
   },
   "DeleteTypeRequest": {
    "type": "object",
    "properties": {
     "name": {
      "type": "string",
      "description": "Type to remove; its uses revert to undefined"
     }
    },
    "additionalProperties": false,
    "required": [
     "name"
    ]
   },
   "TypeUses": {
    "type": "object",
    "description": "What deleting this type would revert to undefined",
    "properties": {
     "name": {
      "type": "string",
      "description": "Category path of the type"
     },
     "data": {
      "type": "integer",
      "description": "Defined data using it"
     },
     "variables": {
      "type": "integer",
      "description": "Function variables typed as it"
     },
     "types": {
      "type": "integer",
      "description": "Other types built from it"
     },
     "total": {
      "type": "integer",
      "description": "Sum of the three"
     }
    }
   },
   "Finding": {
    "type": "object",
    "description": "One structured claim a background agent run recorded. Append-only: a corrected finding is superseded by a newer one, never edited.",
    "properties": {
     "id": {
      "type": "string"
     },
     "agent": {
      "type": "string"
     },
     "userId": {
      "type": "string"
     },
     "claim": {
      "type": "string"
     },
     "addr": {
      "type": "string"
     },
     "confidence": {
      "type": "string",
      "enum": [
       "low",
       "medium",
       "high"
      ]
     },
     "createdAt": {
      "type": "integer"
     },
     "supersedes": {
      "type": "string"
     },
     "supersededBy": {
      "type": "string"
     }
    },
    "required": [
     "id",
     "claim",
     "createdAt"
    ]
   },
   "DefinedDataItem": {
    "type": "object",
    "description": "One typed global defined in the program.",
    "properties": {
     "vaddr": {
      "type": "integer",
      "description": "Virtual address (decimal); render as hex."
     },
     "paddr": {
      "type": "integer",
      "description": "File offset (decimal), or -1 if not in the file image."
     },
     "size": {
      "type": "integer",
      "description": "Size in bytes."
     },
     "type": {
      "type": "string",
      "description": "Data type display name."
     },
     "name": {
      "type": "string",
      "description": "Primary symbol/label at the address, or '' if none."
     },
     "section": {
      "type": "string",
      "description": "Containing memory block, or ''."
     },
     "value": {
      "type": "string",
      "description": "Rendered value, truncated to 256 chars."
     },
     "xrefs": {
      "type": "integer",
      "description": "Count of references into this address."
     }
    },
    "required": [
     "vaddr",
     "paddr",
     "size",
     "type",
     "name",
     "section",
     "value",
     "xrefs"
    ],
    "additionalProperties": false
   }
  }
 }
}
