Skip to main content
Glama

deploy

Applies a structured release specification to atomically update database migrations, functions, site assets, routes, secret requirements, and subdomains for a run402 project.

Instructions

Unified apply primitive. Accepts a structured ReleaseSpec — database (migrations + expose), value-free secrets.require/delete declarations, functions, site, site.public_paths, site.embedding (framing opt-in by catalog key, e.g. { frame_ancestors: ['localhost'] }; null = deny), site.sign_in_path (the app's own same-origin sign-in page for MCP authorization, e.g. '/join'; null = hosted page), site.noindex (true = X-Robots-Tag: noindex, nofollow, nosnippet on every response of the host; false or null = indexable), subdomains, and routes.replace web routes — with explicit replace vs patch semantics per resource. Migration entries use id for immutable versioned SQL or name for generated/idempotent content-tracked SQL; name compiles client-side to _<sha256(sql)[0:16]>. Use site.public_paths for clean static URLs such as /events backed by release asset events.html; explicit mode does not expose /events.html unless separately declared, while mode: 'implicit' restores filename-derived reachability and can widen access. Route entries map exact/final-wildcard browser paths like /admin and /admin/* to Node 22 Fetch Request -> Response functions, or exact GET/HEAD method-aware static aliases such as /events to { type: 'static', file: 'events.html' }; acknowledge an intentionally read-only GET/HEAD wildcard function route with allow_warning_codes: ['WILDCARD_ROUTE_EXCLUDES_MUTATION_METHODS']. Direct /functions/v1/:name remains API-key protected. Secret values are set first with r.secrets.set (a run snippet) or run402 secrets set, never placed in deploy specs. All bytes ride through CAS (no inline-body cap). Returns release_id, URLs, warnings, and a structured progress-event log. Stops before upload/commit on confirmation-required warnings unless reviewed codes are passed with allow_warning_codes or allow_warnings is true.

Input Schema

NameRequiredDescriptionDefault
baseNoDiff base. Default `{ release: 'current' }`. Use `{ release: 'empty' }` for a fresh deploy that fails if a release already exists.
i18nNoRouted-locale-context release slice. Omit to carry forward from base release; pass null to clear the slice; pass { defaultLocale, locales, detect? } to replace. Drives the negotiated locale that the gateway surfaces to routed HTTP function invocations via x-run402-locale and x-run402-default-locale request headers (omitted entirely when the active release has no i18n slice). Static-route hits do NOT receive locale negotiation.
siteNo
assetsNov1.48 unified-apply assets slice. Asset writes promote inside the same activation transaction as functions/site/secrets so a release flips atomically.
routesNoApply-v1 web routes. Omit or pass null to carry forward base routes; pass { replace: [] } to clear routes; pass { replace: [{ pattern, methods?, target: { type: 'function', name } }] } for functions or exact GET/HEAD { target: { type: 'static', file } } entries for method-aware static route aliases. Prefer site.public_paths for ordinary clean static URLs.
secretsNo
databaseNo
functionsNo
project_idYesProject ID to deploy to (from provision).
subdomainsNoAt most one subdomain per project — multi-element `set` is rejected with SUBDOMAIN_MULTI_NOT_SUPPORTED.
allow_warningsNoContinue past plan warnings that require confirmation. Default false: the tool stops before upload/commit so an agent can set missing secrets or inspect warnings.
idempotency_keyNoOptional client idempotency key. Combined with the project id and gateway-computed manifest digest to deduplicate retries.
allow_warning_codesNoContinue past specific reviewed plan warning codes. Prefer this to allow_warnings when only one known warning class is intentional.

Output Schema

NameRequiredDescriptionDefault
errorNo
eventsNo
resultNo
statusYes
warningsNo

Schema Changelog

Changes observed during successful MCP inspections.

  1. Changed3 schema fields changedv4.126.1
    • addedOutput schema / properties / error / properties / diagnostics
      Added value: +{
      +  "items": {
      +    "additionalProperties": true,
      +    "properties": {
      +      "code": {
      +        "type": "string"
      +      },
      +      "column": {
      +        "type": "integer"
      +      },
      +      "line": {
      +        "type": "integer"
      +      },
      +      "message": {
      +        "type": "string"
      +      }
      +    },
      +    "required": [
      +      "line",
      +      "column",
      +      "code",
      +      "message"
      +    ],
      +    "type": "object"
      +  },
      +  "type": "array"
      +}
    • addedOutput schema / properties / error / properties / diagnostics_ref
      Added value: +{
      +  "type": "string"
      +}
    • addedOutput schema / properties / error / properties / diagnostics_total
      Added value: +{
      +  "type": "integer"
      +}
  2. Changed1 schema field changedv4.122.0
    • changedInput schema / properties / site / anyOf
      Previous value: -[
      -  {
      -    "additionalProperties": false,
      -    "properties": {
      -      "embedding": {
      -        "anyOf": [
      -          {
      -            "additionalProperties": false,
      -            "properties": {
      -              "frame_ancestors": {
      -                "description": "Platform embedding catalog KEYS (never raw origins). `localhost` expands to http://localhost:* and http://127.0.0.1:*; the gateway rejects unknown keys with INVALID_SPEC naming the valid ones.",
      -                "items": {
      -                  "type": "string"
      -                },
      -                "minItems": 1,
      -                "type": "array"
      -              }
      -            },
      -            "required": [
      -              "frame_ancestors"
      -            ],
      -            "type": "object"
      -          },
      -          {
      -            "type": "null"
      -          }
      -        ],
      -        "description": "tenant-site-embedding: who may put the site in an iframe. The gateway then sends `Content-Security-Policy: frame-ancestors <expanded origins>` and drops X-Frame-Options on every response of the host. Omit to carry the previous release's declaration forward; null returns to the default deny."
      -      },
      -      "public_paths": {
      -        "anyOf": [
      -          {
      -            "additionalProperties": false,
      -            "properties": {
      -              "mode": {
      -                "const": "implicit",
      -                "description": "Restore filename-derived public reachability for static assets.",
      -                "type": "string"
      -              }
      -            },
      -            "required": [
      -              "mode"
      -            ],
      -            "type": "object"
      -          },
      -          {
      -            "additionalProperties": false,
      -            "properties": {
      -              "mode": {
      -                "const": "explicit",
      -                "description": "Use only the complete replace table as direct public static URLs.",
      -                "type": "string"
      -              },
      -              "replace": {
      -                "additionalProperties": {
      -                  "additionalProperties": false,
      -                  "properties": {
      -                    "asset": {
      -                      "description": "Release static asset path, such as events.html. This is not a public URL.",
      -                      "type": "string"
      -                    },
      -                    "cache_class": {
      -                      "description": "Optional static cache class, for example html, immutable_versioned, or revalidating_asset.",
      -                      "type": "string"
      -                    }
      -                  },
      -                  "required": [
      -                    "asset"
      -                  ],
      -                  "type": "object"
      -                },
      -                "description": "Complete map from public browser paths such as /events to release static asset paths such as events.html.",
      -                "type": "object"
      -              }
      -            },
      -            "required": [
      -              "mode",
      -              "replace"
      -            ],
      -            "type": "object"
      -          }
      -        ]
      -      },
      -      "replace": {
      -        "$ref": "#/properties/functions/properties/replace/additionalProperties/properties/files"
      -      },
      -      "sign_in_path": {
      -        "description": "The app's own same-origin sign-in page (e.g. \"/join\") that MCP authorization (/_run402/oauth/authorize) sends a signed-out user to, with returnTo appended, instead of the hosted /auth/sign-in. Single leading /, at most 512 chars, no query/fragment, not under /_run402/ or /auth/ (the gateway refuses with INVALID_SPEC on site.sign_in_path). Omit to carry the previous release's value forward; null returns to the hosted page.",
      -        "type": [
      -          "string",
      -          "null"
      -        ]
      -      }
      -    },
      -    "required": [
      -      "replace"
      -    ],
      -    "type": "object"
      -  },
      -  {
      -    "additionalProperties": false,
      -    "properties": {
      -      "embedding": {
      -        "$ref": "#/properties/site/anyOf/0/properties/embedding",
      -        "description": "tenant-site-embedding: who may put the site in an iframe. The gateway then sends `Content-Security-Policy: frame-ancestors <expanded origins>` and drops X-Frame-Options on every response of the host. Omit to carry the previous release's declaration forward; null returns to the default deny."
      -      },
      -      "patch": {
      -        "additionalProperties": false,
      -        "properties": {
      -          "delete": {
      -            "items": {
      -              "type": "string"
      -            },
      -            "type": "array"
      -          },
      -          "put": {
      -            "$ref": "#/properties/functions/properties/replace/additionalProperties/properties/files"
      -          }
      -        },
      -        "type": "object"
      -      },
      -      "public_paths": {
      -        "$ref": "#/properties/site/anyOf/0/properties/public_paths"
      -      },
      -      "sign_in_path": {
      -        "$ref": "#/properties/site/anyOf/0/properties/sign_in_path",
      -        "description": "The app's own same-origin sign-in page (e.g. \"/join\") that MCP authorization (/_run402/oauth/authorize) sends a signed-out user to, with returnTo appended, instead of the hosted /auth/sign-in. Single leading /, at most 512 chars, no query/fragment, not under /_run402/ or /auth/ (the gateway refuses with INVALID_SPEC on site.sign_in_path). Omit to carry the previous release's value forward; null returns to the hosted page."
      -      }
      -    },
      -    "required": [
      -      "patch"
      -    ],
      -    "type": "object"
      -  },
      -  {
      -    "additionalProperties": false,
      -    "properties": {
      -      "embedding": {
      -        "$ref": "#/properties/site/anyOf/0/properties/embedding",
      -        "description": "tenant-site-embedding: who may put the site in an iframe. The gateway then sends `Content-Security-Policy: frame-ancestors <expanded origins>` and drops X-Frame-Options on every response of the host. Omit to carry the previous release's declaration forward; null returns to the default deny."
      -      },
      -      "public_paths": {
      -        "$ref": "#/properties/site/anyOf/0/properties/public_paths"
      -      },
      -      "sign_in_path": {
      -        "$ref": "#/properties/site/anyOf/0/properties/sign_in_path",
      -        "description": "The app's own same-origin sign-in page (e.g. \"/join\") that MCP authorization (/_run402/oauth/authorize) sends a signed-out user to, with returnTo appended, instead of the hosted /auth/sign-in. Single leading /, at most 512 chars, no query/fragment, not under /_run402/ or /auth/ (the gateway refuses with INVALID_SPEC on site.sign_in_path). Omit to carry the previous release's value forward; null returns to the hosted page."
      -      }
      -    },
      -    "required": [
      -      "public_paths"
      -    ],
      -    "type": "object"
      -  },
      -  {
      -    "additionalProperties": false,
      -    "properties": {
      -      "embedding": {
      -        "$ref": "#/properties/site/anyOf/0/properties/embedding"
      -      },
      -      "sign_in_path": {
      -        "$ref": "#/properties/site/anyOf/0/properties/sign_in_path",
      -        "description": "The app's own same-origin sign-in page (e.g. \"/join\") that MCP authorization (/_run402/oauth/authorize) sends a signed-out user to, with returnTo appended, instead of the hosted /auth/sign-in. Single leading /, at most 512 chars, no query/fragment, not under /_run402/ or /auth/ (the gateway refuses with INVALID_SPEC on site.sign_in_path). Omit to carry the previous release's value forward; null returns to the hosted page."
      -      }
      -    },
      -    "required": [
      -      "embedding"
      -    ],
      -    "type": "object"
      -  },
      -  {
      -    "additionalProperties": false,
      -    "properties": {
      -      "sign_in_path": {
      -        "$ref": "#/properties/site/anyOf/0/properties/sign_in_path"
      -      }
      -    },
      -    "required": [
      -      "sign_in_path"
      -    ],
      -    "type": "object"
      -  }
      -]New value: +[
      +  {
      +    "additionalProperties": false,
      +    "properties": {
      +      "embedding": {
      +        "anyOf": [
      +          {
      +            "additionalProperties": false,
      +            "properties": {
      +              "frame_ancestors": {
      +                "description": "Platform embedding catalog KEYS (never raw origins). `localhost` expands to http://localhost:* and http://127.0.0.1:*; the gateway rejects unknown keys with INVALID_SPEC naming the valid ones.",
      +                "items": {
      +                  "type": "string"
      +                },
      +                "minItems": 1,
      +                "type": "array"
      +              }
      +            },
      +            "required": [
      +              "frame_ancestors"
      +            ],
      +            "type": "object"
      +          },
      +          {
      +            "type": "null"
      +          }
      +        ],
      +        "description": "tenant-site-embedding: who may put the site in an iframe. The gateway then sends `Content-Security-Policy: frame-ancestors <expanded origins>` and drops X-Frame-Options on every response of the host. Omit to carry the previous release's declaration forward; null returns to the default deny."
      +      },
      +      "noindex": {
      +        "description": "true adds `X-Robots-Tag: noindex, nofollow, nosnippet` to every response of the host (gateway INVALID_SPEC on site.noindex for anything but a boolean or null). Omit to carry the previous release's value forward; false or null makes the host indexable again (the default).",
      +        "type": [
      +          "boolean",
      +          "null"
      +        ]
      +      },
      +      "public_paths": {
      +        "anyOf": [
      +          {
      +            "additionalProperties": false,
      +            "properties": {
      +              "mode": {
      +                "const": "implicit",
      +                "description": "Restore filename-derived public reachability for static assets.",
      +                "type": "string"
      +              }
      +            },
      +            "required": [
      +              "mode"
      +            ],
      +            "type": "object"
      +          },
      +          {
      +            "additionalProperties": false,
      +            "properties": {
      +              "mode": {
      +                "const": "explicit",
      +                "description": "Use only the complete replace table as direct public static URLs.",
      +                "type": "string"
      +              },
      +              "replace": {
      +                "additionalProperties": {
      +                  "additionalProperties": false,
      +                  "properties": {
      +                    "asset": {
      +                      "description": "Release static asset path, such as events.html. This is not a public URL.",
      +                      "type": "string"
      +                    },
      +                    "cache_class": {
      +                      "description": "Optional static cache class, for example html, immutable_versioned, or revalidating_asset.",
      +                      "type": "string"
      +                    }
      +                  },
      +                  "required": [
      +                    "asset"
      +                  ],
      +                  "type": "object"
      +                },
      +                "description": "Complete map from public browser paths such as /events to release static asset paths such as events.html.",
      +                "type": "object"
      +              }
      +            },
      +            "required": [
      +              "mode",
      +              "replace"
      +            ],
      +            "type": "object"
      +          }
      +        ]
      +      },
      +      "replace": {
      +        "$ref": "#/properties/functions/properties/replace/additionalProperties/properties/files"
      +      },
      +      "sign_in_path": {
      +        "description": "The app's own same-origin sign-in page (e.g. \"/join\") that MCP authorization (/_run402/oauth/authorize) sends a signed-out user to, with returnTo appended, instead of the hosted /auth/sign-in. Single leading /, at most 512 chars, no query/fragment, not under /_run402/ or /auth/ (the gateway refuses with INVALID_SPEC on site.sign_in_path). Omit to carry the previous release's value forward; null returns to the hosted page.",
      +        "type": [
      +          "string",
      +          "null"
      +        ]
      +      }
      +    },
      +    "required": [
      +      "replace"
      +    ],
      +    "type": "object"
      +  },
      +  {
      +    "additionalProperties": false,
      +    "properties": {
      +      "embedding": {
      +        "$ref": "#/properties/site/anyOf/0/properties/embedding",
      +        "description": "tenant-site-embedding: who may put the site in an iframe. The gateway then sends `Content-Security-Policy: frame-ancestors <expanded origins>` and drops X-Frame-Options on every response of the host. Omit to carry the previous release's declaration forward; null returns to the default deny."
      +      },
      +      "noindex": {
      +        "$ref": "#/properties/site/anyOf/0/properties/noindex",
      +        "description": "true adds `X-Robots-Tag: noindex, nofollow, nosnippet` to every response of the host (gateway INVALID_SPEC on site.noindex for anything but a boolean or null). Omit to carry the previous release's value forward; false or null makes the host indexable again (the default)."
      +      },
      +      "patch": {
      +        "additionalProperties": false,
      +        "properties": {
      +          "delete": {
      +            "items": {
      +              "type": "string"
      +            },
      +            "type": "array"
      +          },
      +          "put": {
      +            "$ref": "#/properties/functions/properties/replace/additionalProperties/properties/files"
      +          }
      +        },
      +        "type": "object"
      +      },
      +      "public_paths": {
      +        "$ref": "#/properties/site/anyOf/0/properties/public_paths"
      +      },
      +      "sign_in_path": {
      +        "$ref": "#/properties/site/anyOf/0/properties/sign_in_path",
      +        "description": "The app's own same-origin sign-in page (e.g. \"/join\") that MCP authorization (/_run402/oauth/authorize) sends a signed-out user to, with returnTo appended, instead of the hosted /auth/sign-in. Single leading /, at most 512 chars, no query/fragment, not under /_run402/ or /auth/ (the gateway refuses with INVALID_SPEC on site.sign_in_path). Omit to carry the previous release's value forward; null returns to the hosted page."
      +      }
      +    },
      +    "required": [
      +      "patch"
      +    ],
      +    "type": "object"
      +  },
      +  {
      +    "additionalProperties": false,
      +    "properties": {
      +      "embedding": {
      +        "$ref": "#/properties/site/anyOf/0/properties/embedding",
      +        "description": "tenant-site-embedding: who may put the site in an iframe. The gateway then sends `Content-Security-Policy: frame-ancestors <expanded origins>` and drops X-Frame-Options on every response of the host. Omit to carry the previous release's declaration forward; null returns to the default deny."
      +      },
      +      "noindex": {
      +        "$ref": "#/properties/site/anyOf/0/properties/noindex",
      +        "description": "true adds `X-Robots-Tag: noindex, nofollow, nosnippet` to every response of the host (gateway INVALID_SPEC on site.noindex for anything but a boolean or null). Omit to carry the previous release's value forward; false or null makes the host indexable again (the default)."
      +      },
      +      "public_paths": {
      +        "$ref": "#/properties/site/anyOf/0/properties/public_paths"
      +      },
      +      "sign_in_path": {
      +        "$ref": "#/properties/site/anyOf/0/properties/sign_in_path",
      +        "description": "The app's own same-origin sign-in page (e.g. \"/join\") that MCP authorization (/_run402/oauth/authorize) sends a signed-out user to, with returnTo appended, instead of the hosted /auth/sign-in. Single leading /, at most 512 chars, no query/fragment, not under /_run402/ or /auth/ (the gateway refuses with INVALID_SPEC on site.sign_in_path). Omit to carry the previous release's value forward; null returns to the hosted page."
      +      }
      +    },
      +    "required": [
      +      "public_paths"
      +    ],
      +    "type": "object"
      +  },
      +  {
      +    "additionalProperties": false,
      +    "properties": {
      +      "embedding": {
      +        "$ref": "#/properties/site/anyOf/0/properties/embedding"
      +      },
      +      "noindex": {
      +        "$ref": "#/properties/site/anyOf/0/properties/noindex",
      +        "description": "true adds `X-Robots-Tag: noindex, nofollow, nosnippet` to every response of the host (gateway INVALID_SPEC on site.noindex for anything but a boolean or null). Omit to carry the previous release's value forward; false or null makes the host indexable again (the default)."
      +      },
      +      "sign_in_path": {
      +        "$ref": "#/properties/site/anyOf/0/properties/sign_in_path",
      +        "description": "The app's own same-origin sign-in page (e.g. \"/join\") that MCP authorization (/_run402/oauth/authorize) sends a signed-out user to, with returnTo appended, instead of the hosted /auth/sign-in. Single leading /, at most 512 chars, no query/fragment, not under /_run402/ or /auth/ (the gateway refuses with INVALID_SPEC on site.sign_in_path). Omit to carry the previous release's value forward; null returns to the hosted page."
      +      }
      +    },
      +    "required": [
      +      "embedding"
      +    ],
      +    "type": "object"
      +  },
      +  {
      +    "additionalProperties": false,
      +    "properties": {
      +      "noindex": {
      +        "$ref": "#/properties/site/anyOf/0/properties/noindex",
      +        "description": "true adds `X-Robots-Tag: noindex, nofollow, nosnippet` to every response of the host (gateway INVALID_SPEC on site.noindex for anything but a boolean or null). Omit to carry the previous release's value forward; false or null makes the host indexable again (the default)."
      +      },
      +      "sign_in_path": {
      +        "$ref": "#/properties/site/anyOf/0/properties/sign_in_path"
      +      }
      +    },
      +    "required": [
      +      "sign_in_path"
      +    ],
      +    "type": "object"
      +  },
      +  {
      +    "additionalProperties": false,
      +    "properties": {
      +      "noindex": {
      +        "$ref": "#/properties/site/anyOf/0/properties/noindex"
      +      }
      +    },
      +    "required": [
      +      "noindex"
      +    ],
      +    "type": "object"
      +  }
      +]
  3. Changed2 schema fields changedv2.5.7-astro
    • changedInput schema / properties / routes / anyOf
      Previous value: -[
      -  {
      -    "type": "null"
      -  },
      -  {
      -    "additionalProperties": false,
      -    "properties": {
      -      "replace": {
      -        "items": {
      -          "additionalProperties": false,
      -          "properties": {
      -            "acknowledge_readonly": {
      -              "const": true,
      -              "description": "Durable acknowledgement for intentional GET/HEAD final-wildcard function routes such as /share/*.",
      -              "type": "boolean"
      -            },
      -            "methods": {
      -              "description": "Optional method allowlist. Omit to allow all supported methods; do not pass an empty array.",
      -              "items": {
      -                "enum": [
      -                  "GET",
      -                  "HEAD",
      -                  "POST",
      -                  "PUT",
      -                  "PATCH",
      -                  "DELETE",
      -                  "OPTIONS"
      -                ],
      -                "type": "string"
      -              },
      -              "minItems": 1,
      -              "type": "array"
      -            },
      -            "pattern": {
      -              "description": "Route pattern such as /api, /api/*, or /login. Prefix wildcards only use a final /*.",
      -              "type": "string"
      -            },
      -            "target": {
      -              "anyOf": [
      -                {
      -                  "additionalProperties": false,
      -                  "properties": {
      -                    "name": {
      -                      "description": "Materialized release function name, not a file name or handler export.",
      -                      "type": "string"
      -                    },
      -                    "type": {
      -                      "const": "function",
      -                      "type": "string"
      -                    }
      -                  },
      -                  "required": [
      -                    "type",
      -                    "name"
      -                  ],
      -                  "type": "object"
      -                },
      -                {
      -                  "additionalProperties": false,
      -                  "properties": {
      -                    "file": {
      -                      "description": "Materialized static-site file path, relative to the site root. No leading slash, query, fragment, traversal, or directory shorthand.",
      -                      "type": "string"
      -                    },
      -                    "type": {
      -                      "const": "static",
      -                      "type": "string"
      -                    }
      -                  },
      -                  "required": [
      -                    "type",
      -                    "file"
      -                  ],
      -                  "type": "object"
      -                }
      -              ]
      -            }
      -          },
      -          "required": [
      -            "pattern",
      -            "target"
      -          ],
      -          "type": "object"
      -        },
      -        "type": "array"
      -      }
      -    },
      -    "required": [
      -      "replace"
      -    ],
      -    "type": "object"
      -  }
      -]New value: +[
      +  {
      +    "type": "null"
      +  },
      +  {
      +    "additionalProperties": false,
      +    "properties": {
      +      "replace": {
      +        "items": {
      +          "additionalProperties": false,
      +          "properties": {
      +            "methods": {
      +              "description": "Optional method allowlist. Omit to allow all supported methods; do not pass an empty array.",
      +              "items": {
      +                "enum": [
      +                  "GET",
      +                  "HEAD",
      +                  "POST",
      +                  "PUT",
      +                  "PATCH",
      +                  "DELETE",
      +                  "OPTIONS"
      +                ],
      +                "type": "string"
      +              },
      +              "minItems": 1,
      +              "type": "array"
      +            },
      +            "pattern": {
      +              "description": "Route pattern such as /api, /api/*, or /login. Prefix wildcards only use a final /*.",
      +              "type": "string"
      +            },
      +            "target": {
      +              "anyOf": [
      +                {
      +                  "additionalProperties": false,
      +                  "properties": {
      +                    "name": {
      +                      "description": "Materialized release function name, not a file name or handler export.",
      +                      "type": "string"
      +                    },
      +                    "type": {
      +                      "const": "function",
      +                      "type": "string"
      +                    }
      +                  },
      +                  "required": [
      +                    "type",
      +                    "name"
      +                  ],
      +                  "type": "object"
      +                },
      +                {
      +                  "additionalProperties": false,
      +                  "properties": {
      +                    "file": {
      +                      "description": "Materialized static-site file path, relative to the site root. No leading slash, query, fragment, traversal, or directory shorthand.",
      +                      "type": "string"
      +                    },
      +                    "type": {
      +                      "const": "static",
      +                      "type": "string"
      +                    }
      +                  },
      +                  "required": [
      +                    "type",
      +                    "file"
      +                  ],
      +                  "type": "object"
      +                }
      +              ]
      +            }
      +          },
      +          "required": [
      +            "pattern",
      +            "target"
      +          ],
      +          "type": "object"
      +        },
      +        "type": "array"
      +      }
      +    },
      +    "required": [
      +      "replace"
      +    ],
      +    "type": "object"
      +  }
      +]
    • changedInput schema / properties / site / anyOf
      Previous value: -[
      -  {
      -    "additionalProperties": false,
      -    "properties": {
      -      "embedding": {
      -        "anyOf": [
      -          {
      -            "additionalProperties": false,
      -            "properties": {
      -              "frame_ancestors": {
      -                "description": "Platform embedding catalog KEYS (never raw origins). `localhost` expands to http://localhost:* and http://127.0.0.1:*; the gateway rejects unknown keys with INVALID_SPEC naming the valid ones.",
      -                "items": {
      -                  "type": "string"
      -                },
      -                "minItems": 1,
      -                "type": "array"
      -              }
      -            },
      -            "required": [
      -              "frame_ancestors"
      -            ],
      -            "type": "object"
      -          },
      -          {
      -            "type": "null"
      -          }
      -        ],
      -        "description": "tenant-site-embedding: who may put the site in an iframe. The gateway then sends `Content-Security-Policy: frame-ancestors <expanded origins>` and drops X-Frame-Options on every response of the host. Omit to carry the previous release's declaration forward; null returns to the default deny."
      -      },
      -      "public_paths": {
      -        "anyOf": [
      -          {
      -            "additionalProperties": false,
      -            "properties": {
      -              "mode": {
      -                "const": "implicit",
      -                "description": "Restore filename-derived public reachability for static assets.",
      -                "type": "string"
      -              }
      -            },
      -            "required": [
      -              "mode"
      -            ],
      -            "type": "object"
      -          },
      -          {
      -            "additionalProperties": false,
      -            "properties": {
      -              "mode": {
      -                "const": "explicit",
      -                "description": "Use only the complete replace table as direct public static URLs.",
      -                "type": "string"
      -              },
      -              "replace": {
      -                "additionalProperties": {
      -                  "additionalProperties": false,
      -                  "properties": {
      -                    "asset": {
      -                      "description": "Release static asset path, such as events.html. This is not a public URL.",
      -                      "type": "string"
      -                    },
      -                    "cache_class": {
      -                      "description": "Optional static cache class, for example html, immutable_versioned, or revalidating_asset.",
      -                      "type": "string"
      -                    }
      -                  },
      -                  "required": [
      -                    "asset"
      -                  ],
      -                  "type": "object"
      -                },
      -                "description": "Complete map from public browser paths such as /events to release static asset paths such as events.html.",
      -                "type": "object"
      -              }
      -            },
      -            "required": [
      -              "mode",
      -              "replace"
      -            ],
      -            "type": "object"
      -          }
      -        ]
      -      },
      -      "replace": {
      -        "$ref": "#/properties/functions/properties/replace/additionalProperties/properties/files"
      -      }
      -    },
      -    "required": [
      -      "replace"
      -    ],
      -    "type": "object"
      -  },
      -  {
      -    "additionalProperties": false,
      -    "properties": {
      -      "embedding": {
      -        "$ref": "#/properties/site/anyOf/0/properties/embedding",
      -        "description": "tenant-site-embedding: who may put the site in an iframe. The gateway then sends `Content-Security-Policy: frame-ancestors <expanded origins>` and drops X-Frame-Options on every response of the host. Omit to carry the previous release's declaration forward; null returns to the default deny."
      -      },
      -      "patch": {
      -        "additionalProperties": false,
      -        "properties": {
      -          "delete": {
      -            "items": {
      -              "type": "string"
      -            },
      -            "type": "array"
      -          },
      -          "put": {
      -            "$ref": "#/properties/functions/properties/replace/additionalProperties/properties/files"
      -          }
      -        },
      -        "type": "object"
      -      },
      -      "public_paths": {
      -        "$ref": "#/properties/site/anyOf/0/properties/public_paths"
      -      }
      -    },
      -    "required": [
      -      "patch"
      -    ],
      -    "type": "object"
      -  },
      -  {
      -    "additionalProperties": false,
      -    "properties": {
      -      "embedding": {
      -        "$ref": "#/properties/site/anyOf/0/properties/embedding",
      -        "description": "tenant-site-embedding: who may put the site in an iframe. The gateway then sends `Content-Security-Policy: frame-ancestors <expanded origins>` and drops X-Frame-Options on every response of the host. Omit to carry the previous release's declaration forward; null returns to the default deny."
      -      },
      -      "public_paths": {
      -        "$ref": "#/properties/site/anyOf/0/properties/public_paths"
      -      }
      -    },
      -    "required": [
      -      "public_paths"
      -    ],
      -    "type": "object"
      -  },
      -  {
      -    "additionalProperties": false,
      -    "properties": {
      -      "embedding": {
      -        "$ref": "#/properties/site/anyOf/0/properties/embedding"
      -      }
      -    },
      -    "required": [
      -      "embedding"
      -    ],
      -    "type": "object"
      -  }
      -]New value: +[
      +  {
      +    "additionalProperties": false,
      +    "properties": {
      +      "embedding": {
      +        "anyOf": [
      +          {
      +            "additionalProperties": false,
      +            "properties": {
      +              "frame_ancestors": {
      +                "description": "Platform embedding catalog KEYS (never raw origins). `localhost` expands to http://localhost:* and http://127.0.0.1:*; the gateway rejects unknown keys with INVALID_SPEC naming the valid ones.",
      +                "items": {
      +                  "type": "string"
      +                },
      +                "minItems": 1,
      +                "type": "array"
      +              }
      +            },
      +            "required": [
      +              "frame_ancestors"
      +            ],
      +            "type": "object"
      +          },
      +          {
      +            "type": "null"
      +          }
      +        ],
      +        "description": "tenant-site-embedding: who may put the site in an iframe. The gateway then sends `Content-Security-Policy: frame-ancestors <expanded origins>` and drops X-Frame-Options on every response of the host. Omit to carry the previous release's declaration forward; null returns to the default deny."
      +      },
      +      "public_paths": {
      +        "anyOf": [
      +          {
      +            "additionalProperties": false,
      +            "properties": {
      +              "mode": {
      +                "const": "implicit",
      +                "description": "Restore filename-derived public reachability for static assets.",
      +                "type": "string"
      +              }
      +            },
      +            "required": [
      +              "mode"
      +            ],
      +            "type": "object"
      +          },
      +          {
      +            "additionalProperties": false,
      +            "properties": {
      +              "mode": {
      +                "const": "explicit",
      +                "description": "Use only the complete replace table as direct public static URLs.",
      +                "type": "string"
      +              },
      +              "replace": {
      +                "additionalProperties": {
      +                  "additionalProperties": false,
      +                  "properties": {
      +                    "asset": {
      +                      "description": "Release static asset path, such as events.html. This is not a public URL.",
      +                      "type": "string"
      +                    },
      +                    "cache_class": {
      +                      "description": "Optional static cache class, for example html, immutable_versioned, or revalidating_asset.",
      +                      "type": "string"
      +                    }
      +                  },
      +                  "required": [
      +                    "asset"
      +                  ],
      +                  "type": "object"
      +                },
      +                "description": "Complete map from public browser paths such as /events to release static asset paths such as events.html.",
      +                "type": "object"
      +              }
      +            },
      +            "required": [
      +              "mode",
      +              "replace"
      +            ],
      +            "type": "object"
      +          }
      +        ]
      +      },
      +      "replace": {
      +        "$ref": "#/properties/functions/properties/replace/additionalProperties/properties/files"
      +      },
      +      "sign_in_path": {
      +        "description": "The app's own same-origin sign-in page (e.g. \"/join\") that MCP authorization (/_run402/oauth/authorize) sends a signed-out user to, with returnTo appended, instead of the hosted /auth/sign-in. Single leading /, at most 512 chars, no query/fragment, not under /_run402/ or /auth/ (the gateway refuses with INVALID_SPEC on site.sign_in_path). Omit to carry the previous release's value forward; null returns to the hosted page.",
      +        "type": [
      +          "string",
      +          "null"
      +        ]
      +      }
      +    },
      +    "required": [
      +      "replace"
      +    ],
      +    "type": "object"
      +  },
      +  {
      +    "additionalProperties": false,
      +    "properties": {
      +      "embedding": {
      +        "$ref": "#/properties/site/anyOf/0/properties/embedding",
      +        "description": "tenant-site-embedding: who may put the site in an iframe. The gateway then sends `Content-Security-Policy: frame-ancestors <expanded origins>` and drops X-Frame-Options on every response of the host. Omit to carry the previous release's declaration forward; null returns to the default deny."
      +      },
      +      "patch": {
      +        "additionalProperties": false,
      +        "properties": {
      +          "delete": {
      +            "items": {
      +              "type": "string"
      +            },
      +            "type": "array"
      +          },
      +          "put": {
      +            "$ref": "#/properties/functions/properties/replace/additionalProperties/properties/files"
      +          }
      +        },
      +        "type": "object"
      +      },
      +      "public_paths": {
      +        "$ref": "#/properties/site/anyOf/0/properties/public_paths"
      +      },
      +      "sign_in_path": {
      +        "$ref": "#/properties/site/anyOf/0/properties/sign_in_path",
      +        "description": "The app's own same-origin sign-in page (e.g. \"/join\") that MCP authorization (/_run402/oauth/authorize) sends a signed-out user to, with returnTo appended, instead of the hosted /auth/sign-in. Single leading /, at most 512 chars, no query/fragment, not under /_run402/ or /auth/ (the gateway refuses with INVALID_SPEC on site.sign_in_path). Omit to carry the previous release's value forward; null returns to the hosted page."
      +      }
      +    },
      +    "required": [
      +      "patch"
      +    ],
      +    "type": "object"
      +  },
      +  {
      +    "additionalProperties": false,
      +    "properties": {
      +      "embedding": {
      +        "$ref": "#/properties/site/anyOf/0/properties/embedding",
      +        "description": "tenant-site-embedding: who may put the site in an iframe. The gateway then sends `Content-Security-Policy: frame-ancestors <expanded origins>` and drops X-Frame-Options on every response of the host. Omit to carry the previous release's declaration forward; null returns to the default deny."
      +      },
      +      "public_paths": {
      +        "$ref": "#/properties/site/anyOf/0/properties/public_paths"
      +      },
      +      "sign_in_path": {
      +        "$ref": "#/properties/site/anyOf/0/properties/sign_in_path",
      +        "description": "The app's own same-origin sign-in page (e.g. \"/join\") that MCP authorization (/_run402/oauth/authorize) sends a signed-out user to, with returnTo appended, instead of the hosted /auth/sign-in. Single leading /, at most 512 chars, no query/fragment, not under /_run402/ or /auth/ (the gateway refuses with INVALID_SPEC on site.sign_in_path). Omit to carry the previous release's value forward; null returns to the hosted page."
      +      }
      +    },
      +    "required": [
      +      "public_paths"
      +    ],
      +    "type": "object"
      +  },
      +  {
      +    "additionalProperties": false,
      +    "properties": {
      +      "embedding": {
      +        "$ref": "#/properties/site/anyOf/0/properties/embedding"
      +      },
      +      "sign_in_path": {
      +        "$ref": "#/properties/site/anyOf/0/properties/sign_in_path",
      +        "description": "The app's own same-origin sign-in page (e.g. \"/join\") that MCP authorization (/_run402/oauth/authorize) sends a signed-out user to, with returnTo appended, instead of the hosted /auth/sign-in. Single leading /, at most 512 chars, no query/fragment, not under /_run402/ or /auth/ (the gateway refuses with INVALID_SPEC on site.sign_in_path). Omit to carry the previous release's value forward; null returns to the hosted page."
      +      }
      +    },
      +    "required": [
      +      "embedding"
      +    ],
      +    "type": "object"
      +  },
      +  {
      +    "additionalProperties": false,
      +    "properties": {
      +      "sign_in_path": {
      +        "$ref": "#/properties/site/anyOf/0/properties/sign_in_path"
      +      }
      +    },
      +    "required": [
      +      "sign_in_path"
      +    ],
      +    "type": "object"
      +  }
      +]
  4. Changed5 schema fields changed
    • removedInput schema / properties / database / properties / migrations / items / properties / sql_ref / properties / contentType
      Removed value: -{
      -  "type": "string"
      -}
    • addedInput schema / properties / database / properties / migrations / items / properties / sql_ref / properties / content_type
      Added value: +{
      +  "type": "string"
      +}
    • changedInput schema / properties / functions / properties / replace / additionalProperties / properties / source / anyOf
      Previous value: -[
      -  {
      -    "type": "string"
      -  },
      -  {
      -    "additionalProperties": false,
      -    "properties": {
      -      "contentType": {
      -        "description": "MIME type override. Auto-detected from the path's extension when omitted.",
      -        "type": "string"
      -      },
      -      "data": {
      -        "type": "string"
      -      },
      -      "encoding": {
      -        "enum": [
      -          "utf-8",
      -          "base64"
      -        ],
      -        "type": "string"
      -      }
      -    },
      -    "required": [
      -      "data"
      -    ],
      -    "type": "object"
      -  }
      -]New value: +[
      +  {
      +    "type": "string"
      +  },
      +  {
      +    "additionalProperties": false,
      +    "properties": {
      +      "content_type": {
      +        "description": "MIME type override (snake_case, like every wire field). Auto-detected from the path's extension when omitted.",
      +        "type": "string"
      +      },
      +      "data": {
      +        "type": "string"
      +      },
      +      "encoding": {
      +        "enum": [
      +          "utf-8",
      +          "base64"
      +        ],
      +        "type": "string"
      +      }
      +    },
      +    "required": [
      +      "data"
      +    ],
      +    "type": "object"
      +  }
      +]
    • changedInput schema / properties / site / anyOf
      Previous value: -[
      -  {
      -    "additionalProperties": false,
      -    "properties": {
      -      "public_paths": {
      -        "anyOf": [
      -          {
      -            "additionalProperties": false,
      -            "properties": {
      -              "mode": {
      -                "const": "implicit",
      -                "description": "Restore filename-derived public reachability for static assets.",
      -                "type": "string"
      -              }
      -            },
      -            "required": [
      -              "mode"
      -            ],
      -            "type": "object"
      -          },
      -          {
      -            "additionalProperties": false,
      -            "properties": {
      -              "mode": {
      -                "const": "explicit",
      -                "description": "Use only the complete replace table as direct public static URLs.",
      -                "type": "string"
      -              },
      -              "replace": {
      -                "additionalProperties": {
      -                  "additionalProperties": false,
      -                  "properties": {
      -                    "asset": {
      -                      "description": "Release static asset path, such as events.html. This is not a public URL.",
      -                      "type": "string"
      -                    },
      -                    "cache_class": {
      -                      "description": "Optional static cache class, for example html, immutable_versioned, or revalidating_asset.",
      -                      "type": "string"
      -                    }
      -                  },
      -                  "required": [
      -                    "asset"
      -                  ],
      -                  "type": "object"
      -                },
      -                "description": "Complete map from public browser paths such as /events to release static asset paths such as events.html.",
      -                "type": "object"
      -              }
      -            },
      -            "required": [
      -              "mode",
      -              "replace"
      -            ],
      -            "type": "object"
      -          }
      -        ]
      -      },
      -      "replace": {
      -        "$ref": "#/properties/functions/properties/replace/additionalProperties/properties/files"
      -      }
      -    },
      -    "required": [
      -      "replace"
      -    ],
      -    "type": "object"
      -  },
      -  {
      -    "additionalProperties": false,
      -    "properties": {
      -      "patch": {
      -        "additionalProperties": false,
      -        "properties": {
      -          "delete": {
      -            "items": {
      -              "type": "string"
      -            },
      -            "type": "array"
      -          },
      -          "put": {
      -            "$ref": "#/properties/functions/properties/replace/additionalProperties/properties/files"
      -          }
      -        },
      -        "type": "object"
      -      },
      -      "public_paths": {
      -        "$ref": "#/properties/site/anyOf/0/properties/public_paths"
      -      }
      -    },
      -    "required": [
      -      "patch"
      -    ],
      -    "type": "object"
      -  },
      -  {
      -    "additionalProperties": false,
      -    "properties": {
      -      "public_paths": {
      -        "$ref": "#/properties/site/anyOf/0/properties/public_paths"
      -      }
      -    },
      -    "required": [
      -      "public_paths"
      -    ],
      -    "type": "object"
      -  }
      -]New value: +[
      +  {
      +    "additionalProperties": false,
      +    "properties": {
      +      "embedding": {
      +        "anyOf": [
      +          {
      +            "additionalProperties": false,
      +            "properties": {
      +              "frame_ancestors": {
      +                "description": "Platform embedding catalog KEYS (never raw origins). `localhost` expands to http://localhost:* and http://127.0.0.1:*; the gateway rejects unknown keys with INVALID_SPEC naming the valid ones.",
      +                "items": {
      +                  "type": "string"
      +                },
      +                "minItems": 1,
      +                "type": "array"
      +              }
      +            },
      +            "required": [
      +              "frame_ancestors"
      +            ],
      +            "type": "object"
      +          },
      +          {
      +            "type": "null"
      +          }
      +        ],
      +        "description": "tenant-site-embedding: who may put the site in an iframe. The gateway then sends `Content-Security-Policy: frame-ancestors <expanded origins>` and drops X-Frame-Options on every response of the host. Omit to carry the previous release's declaration forward; null returns to the default deny."
      +      },
      +      "public_paths": {
      +        "anyOf": [
      +          {
      +            "additionalProperties": false,
      +            "properties": {
      +              "mode": {
      +                "const": "implicit",
      +                "description": "Restore filename-derived public reachability for static assets.",
      +                "type": "string"
      +              }
      +            },
      +            "required": [
      +              "mode"
      +            ],
      +            "type": "object"
      +          },
      +          {
      +            "additionalProperties": false,
      +            "properties": {
      +              "mode": {
      +                "const": "explicit",
      +                "description": "Use only the complete replace table as direct public static URLs.",
      +                "type": "string"
      +              },
      +              "replace": {
      +                "additionalProperties": {
      +                  "additionalProperties": false,
      +                  "properties": {
      +                    "asset": {
      +                      "description": "Release static asset path, such as events.html. This is not a public URL.",
      +                      "type": "string"
      +                    },
      +                    "cache_class": {
      +                      "description": "Optional static cache class, for example html, immutable_versioned, or revalidating_asset.",
      +                      "type": "string"
      +                    }
      +                  },
      +                  "required": [
      +                    "asset"
      +                  ],
      +                  "type": "object"
      +                },
      +                "description": "Complete map from public browser paths such as /events to release static asset paths such as events.html.",
      +                "type": "object"
      +              }
      +            },
      +            "required": [
      +              "mode",
      +              "replace"
      +            ],
      +            "type": "object"
      +          }
      +        ]
      +      },
      +      "replace": {
      +        "$ref": "#/properties/functions/properties/replace/additionalProperties/properties/files"
      +      }
      +    },
      +    "required": [
      +      "replace"
      +    ],
      +    "type": "object"
      +  },
      +  {
      +    "additionalProperties": false,
      +    "properties": {
      +      "embedding": {
      +        "$ref": "#/properties/site/anyOf/0/properties/embedding",
      +        "description": "tenant-site-embedding: who may put the site in an iframe. The gateway then sends `Content-Security-Policy: frame-ancestors <expanded origins>` and drops X-Frame-Options on every response of the host. Omit to carry the previous release's declaration forward; null returns to the default deny."
      +      },
      +      "patch": {
      +        "additionalProperties": false,
      +        "properties": {
      +          "delete": {
      +            "items": {
      +              "type": "string"
      +            },
      +            "type": "array"
      +          },
      +          "put": {
      +            "$ref": "#/properties/functions/properties/replace/additionalProperties/properties/files"
      +          }
      +        },
      +        "type": "object"
      +      },
      +      "public_paths": {
      +        "$ref": "#/properties/site/anyOf/0/properties/public_paths"
      +      }
      +    },
      +    "required": [
      +      "patch"
      +    ],
      +    "type": "object"
      +  },
      +  {
      +    "additionalProperties": false,
      +    "properties": {
      +      "embedding": {
      +        "$ref": "#/properties/site/anyOf/0/properties/embedding",
      +        "description": "tenant-site-embedding: who may put the site in an iframe. The gateway then sends `Content-Security-Policy: frame-ancestors <expanded origins>` and drops X-Frame-Options on every response of the host. Omit to carry the previous release's declaration forward; null returns to the default deny."
      +      },
      +      "public_paths": {
      +        "$ref": "#/properties/site/anyOf/0/properties/public_paths"
      +      }
      +    },
      +    "required": [
      +      "public_paths"
      +    ],
      +    "type": "object"
      +  },
      +  {
      +    "additionalProperties": false,
      +    "properties": {
      +      "embedding": {
      +        "$ref": "#/properties/site/anyOf/0/properties/embedding"
      +      }
      +    },
      +    "required": [
      +      "embedding"
      +    ],
      +    "type": "object"
      +  }
      +]
    • changedOutput schema / (root)
      Previous value: -nullNew value: +{
      +  "$schema": "http://json-schema.org/draft-07/schema#",
      +  "additionalProperties": true,
      +  "properties": {
      +    "error": {
      +      "additionalProperties": true,
      +      "properties": {
      +        "category": {
      +          "type": "string"
      +        },
      +        "code": {
      +          "type": "string"
      +        },
      +        "column": {
      +          "type": "integer"
      +        },
      +        "details": {},
      +        "fix": {},
      +        "http_status": {
      +          "type": "integer"
      +        },
      +        "line": {
      +          "type": "integer"
      +        },
      +        "logs": {
      +          "items": {
      +            "type": "string"
      +          },
      +          "type": "array"
      +        },
      +        "message": {
      +          "type": "string"
      +        },
      +        "mutation_state": {
      +          "type": "string"
      +        },
      +        "next_actions": {
      +          "items": {
      +            "additionalProperties": true,
      +            "properties": {
      +              "type": {
      +                "type": "string"
      +              }
      +            },
      +            "type": "object"
      +          },
      +          "type": "array"
      +        },
      +        "operation_id": {
      +          "type": "string"
      +        },
      +        "phase": {
      +          "type": "string"
      +        },
      +        "plan_id": {
      +          "type": "string"
      +        },
      +        "resource": {
      +          "type": "string"
      +        },
      +        "retryable": {
      +          "type": "boolean"
      +        },
      +        "safe_to_retry": {
      +          "type": "boolean"
      +        },
      +        "trace_id": {
      +          "type": "string"
      +        }
      +      },
      +      "required": [
      +        "code",
      +        "message",
      +        "next_actions"
      +      ],
      +      "type": "object"
      +    },
      +    "events": {
      +      "items": {
      +        "additionalProperties": true,
      +        "properties": {
      +          "type": {
      +            "type": "string"
      +          }
      +        },
      +        "type": "object"
      +      },
      +      "type": "array"
      +    },
      +    "result": {
      +      "additionalProperties": true,
      +      "properties": {
      +        "next_actions": {
      +          "items": {
      +            "$ref": "#/properties/error/properties/next_actions/items"
      +          },
      +          "type": "array"
      +        },
      +        "operation_id": {
      +          "type": "string"
      +        },
      +        "release_id": {
      +          "type": "string"
      +        },
      +        "urls": {
      +          "additionalProperties": {},
      +          "type": "object"
      +        },
      +        "warnings": {
      +          "items": {
      +            "additionalProperties": true,
      +            "properties": {
      +              "code": {
      +                "type": "string"
      +              }
      +            },
      +            "type": "object"
      +          },
      +          "type": "array"
      +        }
      +      },
      +      "required": [
      +        "release_id",
      +        "operation_id",
      +        "urls"
      +      ],
      +      "type": "object"
      +    },
      +    "status": {
      +      "enum": [
      +        "ok",
      +        "error"
      +      ],
      +      "type": "string"
      +    },
      +    "warnings": {
      +      "items": {
      +        "$ref": "#/properties/result/properties/warnings/items"
      +      },
      +      "type": "array"
      +    }
      +  },
      +  "required": [
      +    "status"
      +  ],
      +  "type": "object"
      +}
  5. Changed3 schema fields changedv4.0.2
    • changedInput schema / properties / database / properties / migrations / items / properties / id / description
      Previous value: -"Stable migration id (e.g. '001_init'). Same id+checksum across re-deploys is a registry noop; same id+different checksum is a hard error."New value: +"Stable versioned migration id (e.g. '001_init'). Same id+checksum across re-deploys is a registry noop; same id+different checksum is a hard error. Use name instead for generated/idempotent SQL."
    • addedInput schema / properties / database / properties / migrations / items / properties / name
      Added value: +{
      +  "description": "Content-tracked migration name for generated/idempotent SQL. The SDK compiles this to <name>_<sha256(sql)[0:16]>; changed content applies once under a new id and identical re-deploys noop. SQL declared with name MUST be idempotent.",
      +  "pattern": "^[a-zA-Z0-9][a-zA-Z0-9_-]{0,63}$",
      +  "type": "string"
      +}
    • removedInput schema / properties / database / properties / migrations / items / required
      Removed value: -[
      -  "id"
      -]
  6. First observedv3.6.0

TDQS

A4.1/5.0
Behavior5/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

With no annotations, the description carries the full burden and does so well: it discloses atomic activation ('All bytes ride through CAS'), the confirmation gate ('Stops before upload/commit on confirmation-required warnings unless ... allow_warning_codes ... or allow_warnings'), the read-only GET/HEAD wildcard warning code, and the API-key protection on /functions/v1/:name. Return values (release_id, URLs, warnings, progress-event log) are also stated.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness3/5

Is the description appropriately sized, front-loaded, and free of redundancy?

It is front-loaded with 'Unified apply primitive', but the body is a dense, comma-chained wall of text mixing schema semantics, security notes, and warning behavior in single long sentences. Nearly every clause earns its place, yet scannability suffers and the key operational constraint (secrets must be set first) is buried mid-paragraph.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness4/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

For a 13-parameter, deeply nested, high-blast-radius mutation, the description is unusually complete and an output schema covers the return shape. It omits only authentication/authorization requirements and any guidance on base/release-id selection, so it is strong but not exhaustive.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters5/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Well beyond the 69% schema coverage, it explains replace vs patch semantics per resource, how `name` compiles to <name>_<sha256(sql)[0:16]> vs immutable `id`, embedding catalog keys (with localhost expansion and unknown-key rejection), sign_in_path constraints, and the explicit-vs-implicit widening risk of public_paths. These are semantic rules the schema alone does not convey.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose4/5

Does the description clearly state what the tool does and how it differs from similar tools?

The description names a specific verb and resource ('Unified apply primitive', accepting a ReleaseSpec) and enumerates exactly which slices it covers: database migrations, secrets declarations, functions, site, subdomains, routes. It never names or contrasts itself with the sibling tool 'up', which is the most likely confusion point, so it stops short of a 5.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines3/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

It gives useful operational sequencing ('Secret values are set first with r.secrets.set ... never placed in deploy specs') and points to site.public_paths for the common case. But it never states when to deploy vs. use `up`, `run`, or a patch-only call, and it offers no explicit exclusions, so usage is implied rather than guided.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

Deploy Server

Other Tools