Skip to content

chore: production deploy - #6416

Open
supabase-cli-releaser[bot] wants to merge 38 commits into
mainfrom
develop
Open

chore: production deploy#6416
supabase-cli-releaser[bot] wants to merge 38 commits into
mainfrom
develop

Conversation

@supabase-cli-releaser

Copy link
Copy Markdown
Contributor

johnstonmatt and others added 30 commits August 26, 2026 20:17
## Summary

Adds `supabase workers new`, plus the project layout and `config.toml`
editing the
whole command family builds on:

- `shared/workers/` — worker path resolution, `config.toml` section
reading and
patching (`toml-section.ts` preserves surrounding formatting), the
runtime/size
  envelope, and the starter files.
- Starter files live as ordinary files under
`shared/workers/stacks/<runtime>/`
rather than string literals, and are embedded into the compiled binary
through a
  Bun macro — the directory is expanded at transpile time and inlined.
A completeness check inside the macro fails the build if
`WORKER_RUNTIMES` and
  the directory drift apart.

**Stack 2 of 4**, on top of the config schema (#6260).

Reviewer note: the third commit is where the embedding mechanism is
explained; the
starters are deliberately kept out of the type program (a `deno` starter
is not
valid under this workspace's Bun types), which is why `tsconfig.json`
excludes the
directory and nothing imports the files.

## Linked issue

FUNC-753 (Linear). Supabase maintainer, exempt from the
`open-for-contribution` flow.

## Checklist

- [x] The PR title follows [Conventional
Commits](https://www.conventionalcommits.org/)

---------

Co-authored-by: Kanad Gupta <git@kanad.dev>
## Summary

Adds `supabase workers push` (aliased `deploy`) and the machinery it
needs:

- `workers-api.ts` — the typed Workers Management API client.
- `tar.ts` / `worker-package.ts` — packaging a worker directory into the
build
  context that gets uploaded.
- `worker-classify.ts` — best-effort runtime detection from marker
files, so a
directory with no `[workers.<name>] runtime` can still deploy. The guess
is
  always reported with a nudge to pin it down, never applied silently.

**Stack 3 of 4**, on top of `workers new` (#6261).

## Linked issue

FUNC-753 (Linear). Supabase maintainer, exempt from the
`open-for-contribution` flow.

## Checklist

- [x] The PR title follows [Conventional
Commits](https://www.conventionalcommits.org/)
…te (#6350)

Bumps the go-minor group with 1 update in the /apps/cli-go directory:
[google.golang.org/grpc](https://github.com/grpc/grpc-go).
Bumps the go-minor group with 1 update in the /apps/cli-go/pkg
directory: [google.golang.org/grpc](https://github.com/grpc/grpc-go).

Updates `google.golang.org/grpc` from 1.83.0 to 1.83.1
<details>
<summary>Release notes</summary>
<p><em>Sourced from <a
href="https://github.com/grpc/grpc-go/releases">google.golang.org/grpc's
releases</a>.</em></p>
<blockquote>
<h2>Release 1.83.1</h2>
<h1>Security</h1>
<ul>
<li>xds/rbac: Fix a bug where nested <code>Principal</code> or
<code>Permission</code> rules with <code>:scheme</code> or
<code>grpc-</code> prefixed header matchers were not rejected, which
could cause DENY rules to fail open. (<a
href="https://redirect.github.com/grpc/grpc-go/issues/9258">#9258</a>)
<ul>
<li>Special Thanks: <a
href="https://github.com/nvxbug"><code>@​nvxbug</code></a></li>
</ul>
</li>
<li>xds/rbac: Fix a bug where the <code>host</code> header matcher was
not being replaced with <code>:authority</code> in nested
<code>Principal</code> or <code>Permission</code> rules. (<a
href="https://redirect.github.com/grpc/grpc-go/issues/9258">#9258</a>)
<ul>
<li>Special Thanks: <a
href="https://github.com/nvxbug"><code>@​nvxbug</code></a></li>
</ul>
</li>
<li>xds/rbac: Fix a bug where a header matcher whose name was not
lowercase, such as <code>X-Role</code>, matched no header, which could
cause DENY rules to fail open. (<a
href="https://redirect.github.com/grpc/grpc-go/issues/9332">#9332</a>)
<ul>
<li>Special Thanks: <a
href="https://github.com/alimony"><code>@​alimony</code></a></li>
</ul>
</li>
<li>xds/rbac: Fix a bug where a <code>:scheme</code> or
<code>grpc-</code> prefixed header matcher was accepted when its name
was not lowercase. (<a
href="https://redirect.github.com/grpc/grpc-go/issues/9332">#9332</a>)
<ul>
<li>Special Thanks: <a
href="https://github.com/alimony"><code>@​alimony</code></a></li>
</ul>
</li>
<li>xds/rbac: Fix a bug where a <code>Host</code> header matcher was not
replaced with <code>:authority</code>. (<a
href="https://redirect.github.com/grpc/grpc-go/issues/9332">#9332</a>)
<ul>
<li>Special Thanks: <a
href="https://github.com/alimony"><code>@​alimony</code></a></li>
</ul>
</li>
</ul>
<h1>Performance</h1>
<ul>
<li>transport: Restrict memory overhead of buffering small data frames.
(<a
href="https://redirect.github.com/grpc/grpc-go/issues/9331">#9331</a>)</li>
</ul>
</blockquote>
</details>
<details>
<summary>Commits</summary>
<ul>
<li><a
href="https://github.com/grpc/grpc-go/commit/1550d9e0cddb30ce99e61a2102e8294a49461e5e"><code>1550d9e</code></a>
Change version to 1.83.1 (<a
href="https://redirect.github.com/grpc/grpc-go/issues/9336">#9336</a>)</li>
<li><a
href="https://github.com/grpc/grpc-go/commit/ebba6f3f1b206e2b4dc4d1d5a96d18430302c2fe"><code>ebba6f3</code></a>
Cherry-pick <a
href="https://redirect.github.com/grpc/grpc-go/issues/9258">#9258</a>
and <a
href="https://redirect.github.com/grpc/grpc-go/issues/9332">#9332</a>
into v1.83.x (<a
href="https://redirect.github.com/grpc/grpc-go/issues/9335">#9335</a>)</li>
<li><a
href="https://github.com/grpc/grpc-go/commit/8cfeca0e1ee5ea0980dcc320e20240fa1079ec77"><code>8cfeca0</code></a>
Cherry-pick <a
href="https://redirect.github.com/grpc/grpc-go/issues/9331">#9331</a> to
v1.83.x (<a
href="https://redirect.github.com/grpc/grpc-go/issues/9333">#9333</a>)</li>
<li><a
href="https://github.com/grpc/grpc-go/commit/dec6951305e88906696f1d0a00dd2439363bc708"><code>dec6951</code></a>
Change version to 1.83.1-dev (<a
href="https://redirect.github.com/grpc/grpc-go/issues/9229">#9229</a>)</li>
<li>See full diff in <a
href="https://github.com/grpc/grpc-go/compare/v1.83.0...v1.83.1">compare
view</a></li>
</ul>
</details>
<br />

Updates `google.golang.org/grpc` from 1.83.0 to 1.83.1
<details>
<summary>Release notes</summary>
<p><em>Sourced from <a
href="https://github.com/grpc/grpc-go/releases">google.golang.org/grpc's
releases</a>.</em></p>
<blockquote>
<h2>Release 1.83.1</h2>
<h1>Security</h1>
<ul>
<li>xds/rbac: Fix a bug where nested <code>Principal</code> or
<code>Permission</code> rules with <code>:scheme</code> or
<code>grpc-</code> prefixed header matchers were not rejected, which
could cause DENY rules to fail open. (<a
href="https://redirect.github.com/grpc/grpc-go/issues/9258">#9258</a>)
<ul>
<li>Special Thanks: <a
href="https://github.com/nvxbug"><code>@​nvxbug</code></a></li>
</ul>
</li>
<li>xds/rbac: Fix a bug where the <code>host</code> header matcher was
not being replaced with <code>:authority</code> in nested
<code>Principal</code> or <code>Permission</code> rules. (<a
href="https://redirect.github.com/grpc/grpc-go/issues/9258">#9258</a>)
<ul>
<li>Special Thanks: <a
href="https://github.com/nvxbug"><code>@​nvxbug</code></a></li>
</ul>
</li>
<li>xds/rbac: Fix a bug where a header matcher whose name was not
lowercase, such as <code>X-Role</code>, matched no header, which could
cause DENY rules to fail open. (<a
href="https://redirect.github.com/grpc/grpc-go/issues/9332">#9332</a>)
<ul>
<li>Special Thanks: <a
href="https://github.com/alimony"><code>@​alimony</code></a></li>
</ul>
</li>
<li>xds/rbac: Fix a bug where a <code>:scheme</code> or
<code>grpc-</code> prefixed header matcher was accepted when its name
was not lowercase. (<a
href="https://redirect.github.com/grpc/grpc-go/issues/9332">#9332</a>)
<ul>
<li>Special Thanks: <a
href="https://github.com/alimony"><code>@​alimony</code></a></li>
</ul>
</li>
<li>xds/rbac: Fix a bug where a <code>Host</code> header matcher was not
replaced with <code>:authority</code>. (<a
href="https://redirect.github.com/grpc/grpc-go/issues/9332">#9332</a>)
<ul>
<li>Special Thanks: <a
href="https://github.com/alimony"><code>@​alimony</code></a></li>
</ul>
</li>
</ul>
<h1>Performance</h1>
<ul>
<li>transport: Restrict memory overhead of buffering small data frames.
(<a
href="https://redirect.github.com/grpc/grpc-go/issues/9331">#9331</a>)</li>
</ul>
</blockquote>
</details>
<details>
<summary>Commits</summary>
<ul>
<li><a
href="https://github.com/grpc/grpc-go/commit/1550d9e0cddb30ce99e61a2102e8294a49461e5e"><code>1550d9e</code></a>
Change version to 1.83.1 (<a
href="https://redirect.github.com/grpc/grpc-go/issues/9336">#9336</a>)</li>
<li><a
href="https://github.com/grpc/grpc-go/commit/ebba6f3f1b206e2b4dc4d1d5a96d18430302c2fe"><code>ebba6f3</code></a>
Cherry-pick <a
href="https://redirect.github.com/grpc/grpc-go/issues/9258">#9258</a>
and <a
href="https://redirect.github.com/grpc/grpc-go/issues/9332">#9332</a>
into v1.83.x (<a
href="https://redirect.github.com/grpc/grpc-go/issues/9335">#9335</a>)</li>
<li><a
href="https://github.com/grpc/grpc-go/commit/8cfeca0e1ee5ea0980dcc320e20240fa1079ec77"><code>8cfeca0</code></a>
Cherry-pick <a
href="https://redirect.github.com/grpc/grpc-go/issues/9331">#9331</a> to
v1.83.x (<a
href="https://redirect.github.com/grpc/grpc-go/issues/9333">#9333</a>)</li>
<li><a
href="https://github.com/grpc/grpc-go/commit/dec6951305e88906696f1d0a00dd2439363bc708"><code>dec6951</code></a>
Change version to 1.83.1-dev (<a
href="https://redirect.github.com/grpc/grpc-go/issues/9229">#9229</a>)</li>
<li>See full diff in <a
href="https://github.com/grpc/grpc-go/compare/v1.83.0...v1.83.1">compare
view</a></li>
</ul>
</details>
<br />


Dependabot will resolve any conflicts with this PR as long as you don't
alter it yourself. You can also trigger a rebase manually by commenting
`@dependabot rebase`.

[//]: # (dependabot-automerge-start)
[//]: # (dependabot-automerge-end)

---

<details>
<summary>Dependabot commands and options</summary>
<br />

You can trigger Dependabot actions by commenting on this PR:
- `@dependabot rebase` will rebase this PR
- `@dependabot recreate` will recreate this PR, overwriting any edits
that have been made to it
- `@dependabot show <dependency name> ignore conditions` will show all
of the ignore conditions of the specified dependency
- `@dependabot ignore <dependency name> major version` will close this
group update PR and stop Dependabot creating any more for the specific
dependency's major version (unless you unignore this specific
dependency's major version or upgrade to it yourself)
- `@dependabot ignore <dependency name> minor version` will close this
group update PR and stop Dependabot creating any more for the specific
dependency's minor version (unless you unignore this specific
dependency's minor version or upgrade to it yourself)
- `@dependabot ignore <dependency name>` will close this group update PR
and stop Dependabot creating any more for the specific dependency
(unless you unignore this specific dependency or upgrade to it yourself)
- `@dependabot unignore <dependency name>` will remove all of the ignore
conditions of the specified dependency
- `@dependabot unignore <dependency name> <ignore condition>` will
remove the ignore condition of the specified dependency and ignore
conditions


</details>

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
This PR was automatically created to sync API types from the
infrastructure repository.

Changes were detected in the generated API code after syncing with the
latest spec from infrastructure.

Co-authored-by: supabase-cli-releaser[bot] <246109035+supabase-cli-releaser[bot]@users.noreply.github.com>
## Summary

- Replace the runtime REST and SSE daemon protocol with a static control
plane exposing owner discovery, session-fenced shutdown, and
same-version Effect RPC over HTTP and NDJSON.
- Use the immutable, unique CLI version as the sole runtime
compatibility identity; source execution uses the explicit 0.0.0-dev
development sentinel.
- Make an incompatible CLI version an explicit parent-owned full stack
stop/start authorized only by supabase start; connect-only and ordinary
child paths report the typed upgrade requirement without restarting the
live owner.
- Preserve managed data, document and launch metadata, runtime
selection, pinned service versions, raw exclusions, and sticky ports
across the upgrade restart.
- Serialize startup, runtime scope ownership, terminal persistence, and
shutdown through one Effect Queue-backed SupervisorSession actor,
releasing the control listener last across Node, Bun, and compiled Bun
runtimes.
- Update CLI consumers, error reporting, integration helpers, targeted
process coverage, and durable architecture documentation for the
single-protocol cutover.

## Linked issue

None.

## Reviewer context

This intentionally has no legacy protocol window, compatibility adapter,
adoption path, or in-place supervisor swap. Runtime RPC is a
same-version boundary; owner discovery and session-fenced shutdown
remain the stable cross-build protocol. Upgrading through supabase start
restarts the complete stack, so active application connections and
tooling streams disconnect briefly while durable state and launch
selections remain intact.
## Summary

- remove the remaining Nx configuration, package metadata, inference
plugin workspace, dependencies, cache ignores, and lockfile graph
- update current contributor guidance to use package scripts and
root-owned Turbo tasks for execution and dependency inspection
- preserve the build, generation, quality, live, auxiliary, and test
graphs established by the preceding Turborepo migrations

## Context

PR #6343 merged while this change was in progress, so this branch was
rebased onto the updated `develop` branch containing its final live and
auxiliary task migration. Task execution is now owned entirely by
package scripts and Turbo.

Affected execution, persistent cache storage, and remote caching remain
separate follow-up optimizations.
This PR was automatically created to sync the generated `@supabase/api`
package with the latest Management API OpenAPI document.

Changes were detected in the upstream OpenAPI documents exposed by
`https://api.supabase.com/api/v1-json` and
`https://api.supabase.com/api/v2-json`.

Co-authored-by: jgoux <1443499+jgoux@users.noreply.github.com>
…dates (#6320)

Bumps the docker-minor group with 5 updates in the
/apps/cli-go/pkg/config/templates directory:

| Package | From | To |
| --- | --- | --- |
| postgrest/postgrest | `v16.1` | `v16.2` |
| supabase/studio | `2026.08.17-sha-0c1da8f` | `2026.08.24-sha-8ec45b2`
|
| supabase/realtime | `v2.129.3` | `v2.129.9` |
| supabase/storage-api | `v1.70.3` | `v1.71.0` |
| supabase/logflare | `1.50.4` | `1.50.6` |


Updates `postgrest/postgrest` from v16.1 to v16.2

Updates `supabase/studio` from 2026.08.17-sha-0c1da8f to
2026.08.24-sha-8ec45b2

Updates `supabase/realtime` from v2.129.3 to v2.129.9

Updates `supabase/storage-api` from v1.70.3 to v1.71.0

Updates `supabase/logflare` from 1.50.4 to 1.50.6


Dependabot will resolve any conflicts with this PR as long as you don't
alter it yourself. You can also trigger a rebase manually by commenting
`@dependabot rebase`.

[//]: # (dependabot-automerge-start)
[//]: # (dependabot-automerge-end)

---

<details>
<summary>Dependabot commands and options</summary>
<br />

You can trigger Dependabot actions by commenting on this PR:
- `@dependabot rebase` will rebase this PR
- `@dependabot recreate` will recreate this PR, overwriting any edits
that have been made to it
- `@dependabot show <dependency name> ignore conditions` will show all
of the ignore conditions of the specified dependency
- `@dependabot ignore <dependency name> major version` will close this
group update PR and stop Dependabot creating any more for the specific
dependency's major version (unless you unignore this specific
dependency's major version or upgrade to it yourself)
- `@dependabot ignore <dependency name> minor version` will close this
group update PR and stop Dependabot creating any more for the specific
dependency's minor version (unless you unignore this specific
dependency's minor version or upgrade to it yourself)
- `@dependabot ignore <dependency name>` will close this group update PR
and stop Dependabot creating any more for the specific dependency
(unless you unignore this specific dependency or upgrade to it yourself)
- `@dependabot unignore <dependency name>` will remove all of the ignore
conditions of the specified dependency
- `@dependabot unignore <dependency name> <ignore condition>` will
remove the ignore condition of the specified dependency and ignore
conditions


</details>

---------

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>
Co-authored-by: Julien Goux <hi@jgoux.dev>
This PR was automatically created to sync the generated `@supabase/api`
package with the latest Management API OpenAPI document.

Changes were detected in the upstream OpenAPI documents exposed by
`https://api.supabase.com/api/v1-json` and
`https://api.supabase.com/api/v2-json`.

Co-authored-by: jgoux <1443499+jgoux@users.noreply.github.com>
This PR was automatically created to sync API types from the
infrastructure repository.

Changes were detected in the generated API code after syncing with the
latest spec from infrastructure.

Co-authored-by: supabase-cli-releaser[bot] <246109035+supabase-cli-releaser[bot]@users.noreply.github.com>
## Summary

Defense-in-depth hardening for the automated release-notes generator
(`propose-release-notes.yml` →
`apps/cli/scripts/propose-release-notes.ts`), which runs the Claude
Agent SDK with `Bash` + `WebFetch`/`WebSearch` and feeds it the
semantic-release changelog block (built from contributor commit subjects
/ PR titles) plus PR bodies and linked issues it fetches at runtime —
all attacker-influenceable content, previously with no injection guard.

This PR adds an explicit **trust boundary** to
`tools/release/release-notes-prompt.md`:

- A top-of-file section establishing that the changelog block and all
fetched PR/issue/web content are **untrusted data to be summarized,
never instructions to obey**.
- Rules that override embedded instructions: don't act on injected
commands; never disclose env vars / secrets / tokens; restrict `Bash` to
read-only `gh` GETs on `supabase/cli`; restrict `WebFetch`/`WebSearch`
to `github.com/supabase/cli`; produce only the release-notes markdown.
- Inline reminders at the two points where untrusted content enters (the
changelog block and the PR-investigation step).

The `{{PASTE_SEMANTIC_RELEASE_BLOCK_HERE}}` placeholder is unchanged, so
the generator's template check and output contract are unaffected.

## Scope / follow-up

This is **defense-in-depth only** — prompt guards are best-effort
against a determined injection. The stronger, structural containment is
deliberately **left for a follow-up**:

1. Separate the write-capable GitHub App token (`GH_TOKEN`,
`contents`/`pull-requests: write` on the protected default branch) from
the agent's process — generate notes in an agent-only step with no GH
token, then push/open the PR in a separate step that runs no model.
2. Drop `Bash` (and ideally `WebFetch`) from the agent's `allowedTools`,
pre-fetching the PR/issue data with trusted code instead — removing the
shell/network exfiltration primitive.

Context: surfaced during the security review of the AI-review pipeline
(#6358); the release-notes workflow shares the "untrusted content +
secrets in an agentic CI job" class of exposure, gated behind a
maintainer-cut stable release rather than per-PR.
… (CLI-2230) (#6339)

## What changed

Implements
[CLI-2230](https://linear.app/supabase/issue/CLI-2230/create-a-toprojectconfig-function-that-is-exported-from-the-config):
the hosted-project subset type `ProjectConfig` and its normalizers,
exported from `@supabase/config`'s pure (browser-safe) entrypoint so the
CLI and Studio share one mapper.

- **`fromConfigDocument(config)`** — projection of a `CliConfig`
document (or any `EffectiveConfig`) down to the hosted sections (`api`,
`auth`, `db`, `realtime`, `storage`, `workers`, `experimental`).
- **`fromApiProjectConfig(input)`** — translation of a Management API v2
project-config response (full envelope, `data` object, or bare
`data.attributes`). Registry-driven: 233 mapping rows mined from the
legacy `config push` sync mappers (`config-sync/*.sync.ts`), covering
renames (`rate_limit_otp` → `sign_in_sign_ups`), boolean inversions
(`disable_signup`, `mailer_autoconfirm`), unit conversions
(seconds/hours → Go duration strings, int64 bytes → BytesSize), the
GoTrue key table (19 OAuth providers, 6 hooks, 5 SMS providers), and
`x-secret` omission (the API only reports HMAC digests). Decode is
lenient per ADR 0019 — unknown/API-ahead keys never fail; the raw
attributes ride along as a **non-enumerable `_apiResponse`** (invisible
to encodes, spreads, and structural walks; never persisted), with a
registry-derived `unmappedApiFields()` reader.
- **`toProjectConfig(source)`** — thin dispatcher over both (`{
cliConfig }` / `{ apiResponse }`).

### Operand widening (ruling on CLI-2230)

`ProjectConfig` is deliberately **sparse** — an API response never
mentions sections it doesn't manage, and flooding in schema defaults
would fabricate drift. To make it a first-class operand of the
comparison core, `BaseCliConfig` is replaced by the family-neutral
`EffectiveConfig = DeepPartial<Omit<CliConfig, "remotes">>` on
`subtractCliConfig`/`omitDefaultValues`. No runtime change — the
subtraction walk already had the right absence semantics. Recorded in
ADR 0018's 2026-08-26 addendum; the naming-rule generalization lands
separately with CLI-2238 (#6335).

### apps/cli

- A type-drift guard (`project-config-api-drift.unit.test.ts`) pins the
generated `V2GetProjectConfigOutput` attributes against the package's
lenient input schema: assignability (catches type widening) plus
per-section key-set assertions (catch added/removed/renamed fields) — so
OpenAPI drift fails compile before it can silently break the mapping. No
runtime dependency on `packages/api` was added.
- `ProjectConfigParseError` registered in the error-actionability table
as `apiStatus` (a malformed platform response, not a user config
mistake).

### Reviewer notes

- Deliberate divergences from the legacy apply semantics are documented
inline where they occur: API `null` → omit (sparse output has no local
document to fall back to), `uri_allow_list` trimming, `smtp_host: ""`
treated as disabled, `sms_autoconfirm` **not** inverted (matches
`auth.sync.ts:1677/:2485` — only the mailer counterpart inverts).
- An explicit `db_schema: ""` maps to `{ api: { enabled: false } }`
only, mirroring `applyRemoteApiConfig`'s early return; an *absent*
`db_schema` doesn't gate the sibling fields.
- Follow-up candidate deliberately not in this PR: a parity test pinning
the replicated legacy helpers
(duration/BytesSize/parseUint16/envToMap/password charsets) against
their `apps/cli` originals. (ADR 0019's attach helper *did* land in the
second round below, as `attachApiResponse`.)

### Second review round (commit 93b4679) — adjudication record

A two-set review (architect/engineer/security/DX + adversarial
execution) ran against bdd607f. The registry mapping itself survived
three independent verification passes with zero defects; every accepted
finding about the surrounding surface is fixed in 93b4679:

- **Secrets**: `fromConfigDocument` now deep-copies and omits every
`x-secret` leaf (schema-derived, `lib/secret-paths.ts`) — decoded
documents hold plaintext credentials, and the subtract composition
rendered them as drift.
- **Spelling convergence**: new registry `normalizeDocument` column
canonicalizes document-side duration and byte-size spellings so both
normalizers emit one form for one logical value.
- **Leniency**: the mirror schema types every never-mapped field
`Schema.Unknown`, so a platform type change on a field nothing reads can
no longer fail every decode.
- **Errors**: `ProjectConfigParseError` gained
`message`/`detail`/`suggestion` (upgrade-then-report), schema-issue
paths lift into `apiPath`, telemetry adds `fingerprint_suffix:
"api_response"` + `has_suggestion`.
- **Type-mismatch unification**: string rows, `smtp_host`/`smtp_port`,
and CIDR entries now throw typed errors instead of fabricating values
(`enabled: false`), vanishing silently, or partially filtering a
security allowlist; `expectNumber` rejects non-finite.
- **`_apiResponse`**: cloned + deep-frozen at attach (no caller
aliasing); `attachApiResponse` export restores it across spread/clone
round-trips; invisibility claim narrowed (serializers and walks — debug
inspectors like Bun's `console.log` still print it; never log an
API-sourced config).
- **`unmappedApiFields`**: recursion depth cap; `unmappedSecretApiPaths`
deny list (`external_figma_secret` — the one genuine orphan digest; the
review's other two candidates don't exist in the legacy source).
- **New guards/exports**: `registry-integrity.unit.test.ts` (all 233
rows' paths resolve against the schema ASTs, 470 generated cases);
drift-guard key-set levels completed;
`comparableProjectConfigPaths`/`isComparableProjectConfigPath` so diff
consumers never hand-maintain field lists; `inverse` implementations
dropped until the push mapper derives them.

**Explicit rejections** (reviewed, not silently deferred):
1. *`alsoConsumes` static consumed-set*: "consumed" means
known-to-this-registry-version, not mapped-on-this-run — an
`alsoConsumes` sibling whose anchor didn't run stays suppressed by
design and remains in `_apiResponse`. Documented in `walkUnmapped`.
2. *WeakMap sidecar for `_apiResponse`*: deferred — clone+freeze
resolves the aliasing hazard and the narrowed docstring is honest;
revisit if CLI-2156 consumption shows inspectors bite (ADR 0019 records
the alternative).
3. *`fromCliConfig`/`fromApiResponse` renaming*: the shipped names are
already recorded in ADR 0020 (#6335), Linear, and coordinated docs —
symmetry isn't worth re-coordinating three artifacts.
4. *Branding `EffectiveConfig`*: took the ADR 0018 consequence note
instead (widening removes the static every-section guarantee; callers
own operand completeness).
5. *`ProjectConfigApiAttributes` placement* and *`"sideEffects":
false`*: deferred to their owning issues with notes filed — CLI-2234
(export-surface audit) and CLI-2232 (verify the bundler claim against a
built artifact).

### Verification round (commits 5f389c9 + 0424ac7)

An executed verification pass over 93b4679 re-ran all prior attacks
(10/10 now pass) and surfaced residuals, fixed in 0424ac7:

- **Orphan digests were 3, not 1** — the generated
`V1GetAuthServiceConfigOutput` contract (not the legacy interface) is
the authority; `external_slack_secret`,
`hook_after_user_created_secrets`, and `nimbus_oauth_client_secret` join
the deny list, and a new apps/cli **contract-guard test** cross-checks
every auth apiPath + secret-suffixed contract key against the registry
(also closing the open-Record vacuity in the integrity test's auth
checks). Registry rows are now exported from the package root to serve
it.
- **Clone/freeze regression fixed**: deep/cyclic/non-cloneable payloads
now throw `ProjectConfigParseError` instead of raw
`RangeError`/`DOMException` (depth-capped pre-walk, wrapped clone,
cycle-guarded `deepFreeze`).
- **README example rewritten and executed** (the previous snippet
self-subtracted and filtered section names — always empty);
secret-stripped projections prune emptied containers; a real
phantom-drift pin replaces an agreeing-case test;
`comparableProjectConfigPaths`' docstring narrowed to the section-level
claim it delivers; ADR 0019 gained a dated addendum (attach helper,
structural "verbatim", debug-inspector caveat).
- **Documented-not-changed**: byte-size canonicalization quantizes at 4
significant digits symmetrically on both arms — sub-0.1% differences
comparing equal is a deliberate property (user-authored spellings are
exact).

The merge commit resolves the pre-agreed README conflict with #6335
(their `## Naming` section wins, its "in flight" sentence flipped) and
de-stales ADR 0020's phrasing, per the coordinated rebase checklist.
Known external: root `check:all` fails on `@supabase/cli-go#lint:check`
(5 gosec findings in Go files byte-identical to develop —
develop-side/toolchain, not this PR).

### Drift-audit round (commit 492ee25)

A 2026-08-27 audit compared the post-codex state against CLI-2230's
design intent. All eight structural commitments verified intact (pure
entrypoint, no `packages/api` dependency, sparse output +
`EffectiveConfig`, ADR 0019 guardrails, registry-driven with `inverse`
unimplemented, purity graph, naming, secret stripping). Three executed
repros surfaced semantic drift introduced by the codex rounds; fixed
here:

- **Leniency**: `JSON.parse('{"x":1e400}')` yields `Infinity`, so the
round-12 non-finite pre-decode rejection hard-failed a real JSON payload
on an *unknown* field (mis-bucketed as `caller_misuse`). The walk now
rejects only bigint/`undefined`/`NaN` (values `JSON.parse` cannot
produce); non-finite values decode and surface as `null` from
`unmappedApiFields` (scalars and inside array leaves, identity preserved
for all-finite arrays). ADR 0019 gains a dated leniency-boundary
addendum.
- **SMTP absence semantics**: an absent `smtp_host` previously counted
as the disabled sentinel, silently dropping
`smtp_user`/`smtp_admin_email`/`rate_limit.email_sent` from both the
output and `unmappedApiFields` — contradicting the SMS
absent-vs-sentinel rule beside it. Absence now says nothing; only the
explicit `""`/`null` legacy sentinel disables (three-state, extended to
the `email_sent` cross-section rule).
- **Convergence-predictor ruling (ADR 0021)**: the codex rounds had
incrementally turned both normalizers into *post-push convergence
predictors* (SMS provider precedence flips extra enabled providers,
disabled-sentinel pruning, `null`-gated booleans, CSV/uint/duration
canonicalization) — defensible (it kills phantom drift for CLI-2156) but
never adjudicated or documented. Ruling: **accepted**, now recorded in
ADR 0021, the
`ProjectConfig`/`fromConfigDocument`/`fromApiProjectConfig` docstrings,
and the README ("not a verbatim representation" caveat).
- **Guards**: the three hand-written sentinel/precedence tables
(`DISABLED_SENTINEL_PRUNES`, `DISABLED_SENTINEL_ENTRY_SWEEPS`,
`SMS_PROVIDER_PUSH_PRECEDENCE`) now resolve every path/key against the
schema ASTs in `registry-integrity` — previously a schema rename
silently no-opped them — and the SMS precedence order is pinned against
the legacy push switch (`auth.sync.ts:2498-2539`).
- Residual cleanups: the stale `Math.trunc` comment above the fraction
arithmetic (round-11/14 artifact the round-20 revert missed),
`ReadonlyJsonValue` exported (it appears in public types),
`smtpExplicitlyDisabledInAttributes` simplified to mirror
`smsProviderExplicitlyUnset`, ADR index gains 0020/0021.

An engineer-review pass over the fix diff verified every change; its
findings (the `email_sent` asymmetry, stale ADR citations, formatter
gate, doc phrasing) are folded in. 984/984 package tests, 461/461
apps/cli guard tests, typechecks clean both packages.

Follow-ups filed so they survive CLI-2230 closing:
[CLI-2266](https://linear.app/supabase/issue/CLI-2266/derive-the-config-push-mapper-from-the-projectconfig-mapping-registry)
(registry-derived push mapper — carries the three requirements
previously parked as CLI-2230 comments) and
[CLI-2267](https://linear.app/supabase/issue/CLI-2267/pin-supabaseconfigs-replicated-legacy-parsers-with-parity-fixtures-in)
(parity fixtures pinning the replicated legacy parsers against
`config-sync/*`).

Fixes CLI-2230

🤖 Generated with [Claude Code](https://claude.com/claude-code)
## Summary

Replaces the Codex GitHub App's per-push auto-review churn (often 30–40
short rounds per PR) with an in-repo pipeline that reviews each PR
**exactly once**, unless a maintainer explicitly re-runs it.

**Pipeline** (`.github/workflows/ai-review.yml`; full design + security
model in `.github/ai-review/README.md`):

1. **resolve** — decides whether to run: once-per-PR dedup (bot-authored
marker), draft/bot/fork skips for auto triggers, `/ai-review`
authorization (requires repo **write/admin** via effective-permission
lookup), diff-size guard. Runs only trusted default-branch code.
2. **claude-review** — Claude Code headless (`claude-fable-5`), one
exhaustive pass, read-only tools, JSON validated against
`findings.schema.json`.
3. **codex-review** — `openai/codex-action` (`gpt-5.6-sol`, drop-sudo +
read-only sandbox): independent review **plus** adjudication of every
Claude finding (confirmed / refuted-with-evidence / uncertain), merged
into `merged-review.schema.json`.
4. **post-review** — deterministic Bun script posts **one** consolidated
PR review (`COMMENT`, advisory only): inline comments for anchorable
findings, refuted findings preserved in a collapsed section (never
silently dropped), verdict counts computed locally (not trusted from the
model). Re-runs supersede the prior review.

**Once-per-PR**: no `synchronize` trigger, bot-authored marker dedup,
per-PR concurrency (non-command comments can't cancel an in-flight run).
Re-run only via `/ai-review` (maintainers) or `workflow_dispatch`.

## Security model

This ran through security + engineering review (twice). A critical
secret-exfiltration path was found and closed; the design now enforces:

- **Model jobs never execute PR-authored code.** The PR head is checked
out only as read-only review subject matter (`claude` reads it with
Read/Grep/Glob under `--bare`/`--strict-mcp-config`); every executed
file — prompts, schemas, the validator script — comes from a separate
trusted default-branch checkout, and no `bun` process ever runs with a
cwd inside the PR checkout (so a PR-authored `bunfig.toml`/`.env` can't
preload code). npm installs are config-isolated and version-pinned;
Codex reviews from `/tmp` with no PR checkout at all.
- **Least privilege**: top-level `permissions: {}`; model jobs hold no
write scope; the only write-capable job (`post-review`) runs base-branch
code exclusively. All actions SHA-pinned.
- **Output is scrubbed**: model-provided text is sanitized
(mentions/refs/HTML neutralized, `file` field guarded against markdown
breakout) and secret-pattern-redacted before it's posted or uploaded as
an artifact (defense-in-depth; a dedicated rotatable key is the real
containment — see README).
- Advisory-only (`COMMENT`), never a required check, never runs in the
merge queue.

## Rollout (shadow mode)

The `pull_request` trigger ships **commented out**. Plan: add a
dedicated `OPENAI_API_KEY` secret (and ideally a dedicated
`ANTHROPIC_API_KEY` rather than the shared release-notes key), tune
prompts against real PRs via `workflow_dispatch`, then enable the
trigger and switch the Codex app to manual-only simultaneously. Steps +
caveats in the README.

## Notes for reviewers

- New `.github/workflows/github-scripts-ci.yml` finally runs the
`.github/scripts` test suites + type-check in CI (they ran nowhere
before — this also covers the pre-existing `contribution-gate` tests).
- Requires a new `OPENAI_API_KEY` repo secret; `ANTHROPIC_API_KEY`
already exists.
Two CI fixes for the AI-review pipeline (#6358), both surfaced
immediately after merge.

## 1. `Claude review` job fails at "Fetch PR diff and metadata"

The first live `/ai-review` run failed with `fatal: not a git
repository`. The `claude-review` job checks out into **subdirectories**
(`pr/` for the PR head, `trusted/` for the base), so `$GITHUB_WORKSPACE`
itself isn't a git repo — and `gh pr diff`/`gh pr view` infer the repo
from the current directory's git remote. Fix: pass `--repo
"$GITHUB_REPOSITORY"` explicitly at both `gh` call sites (claude-review
and, defensively, codex-review) so `gh` never depends on cwd.

## 2. `Test and type-check` (github-scripts-ci) times out

The shared `./.github/actions/setup` installs the full workspace + Go
toolchain via mise (~9–10 min), which raced the job's `timeout-minutes:
10` and got cancelled on a cold cache (the setup step never finished;
tests/type-check never ran). Raised to 20 min. Noted inline that the
check is heavier than it needs to be for two scripts — slimming the
setup is a possible follow-up.
## Summary

Completes the command family with the three remaining subcommands:

- `workers list` — this project's workers.
- `workers status` — one worker in detail.
- `workers delete` — remove a worker, with confirmation.

All three reuse the API client and output helpers introduced in #6262,
so this is
the smallest layer of the stack.

**Stack 4 of 4**, on top of `workers push` (#6262).

## Linked issue

FUNC-753 (Linear). Supabase maintainer, exempt from the
`open-for-contribution` flow.

## Checklist

- [x] The PR title follows [Conventional
Commits](https://www.conventionalcommits.org/)
## Summary

Set up Effect-aware Oxlint for `packages/stack` and
`packages/process-compose` using the Effect-recommended Oxlint preset
and TypeScript plugin. The scoped check is wired into the monorepo task
graph and denies warnings, matching the global Oxlint policy. The
generic pass excludes these two packages while the scoped config extends
the generic ruleset, so generic and Effect rules each run exactly once
without bringing Effect lint into `apps/cli`.

Remediate the existing scoped diagnostics in reviewable waves: typed
Effect failures and schema decoding, reusable Effect and Stream service
values, lifecycle-safe transport cleanup, and focused test-boundary
cleanup. Persisted managed-stack documents and identity markers now
encode through the same schemas used to read them. The merged #6303
transport architecture remains authoritative. Exact `apps/cli` callsites
were updated where the stack Effect service API changed, but CLI code is
intentionally not an Effect-lint target yet.

Native Node, Bun, Deno, and Promise boundaries retain narrow documented
suppressions where replacing the host API or dependency-ordered layer
provisioning would worsen lifecycle semantics.

Supersedes #6304
This PR was automatically created to sync API types from the
infrastructure repository.

Changes were detected in the generated API code after syncing with the
latest spec from infrastructure.

Co-authored-by: supabase-cli-releaser[bot] <246109035+supabase-cli-releaser[bot]@users.noreply.github.com>
… cap (#6365)

Refines the AI review pipeline (built in #6358) into its intended shape,
and removes the size limit. Validated end-to-end via a temporary
self-test trigger during development (now removed — the pipeline ships
in shadow mode).

## What changed

- **Parallel independent reviews + a dedicated adjudicator.**
`claude-review` and `codex-review` now run **in parallel** (Codex no
longer depends on Claude); a new **`adjudicate`** job then reconciles
both finding sets, verifying each finding by **reading the real code**
(PR head checked out read-only), and `post-review` posts the merged
result. This replaces the old single Codex job that did both an
independent pass and adjudication sequentially — cutting the critical
path and giving each job its own timeout.
- **No size cap.** Removed the preemptive "too large" guard. The models
review agentically (reading the diff and files via their own tools over
many turns, like the local CLI), so PRs of any size are reviewed — very
large diffs best-effort within the model's context/turn budget.
- **Runtime fixes** surfaced by real runs: `gh pr diff --repo` (subdir
checkouts), npm config isolation for the Claude CLI install, `set +e` so
the Claude retry loop isn't killed by `bash -e`, and the reviewer model
set to `claude-opus-5` (the account's API key returns 404 for
`claude-fable-5`).

Workflow + prompts only for the split (no TS/schema changes — Codex's
independent findings reuse `findings.schema.json`; the adjudicator still
emits `merged-review.json`). Ships in **shadow mode**: no `pull_request`
trigger, only `workflow_dispatch` / maintainer `/ai-review`.

## Notes for reviewers

- Two first-run unknowns for the adjudicator (can't verify offline):
whether Codex's read-only sandbox can read the `pr/` subtree, and
whether it picks up a nested `pr/AGENTS.md` (guarded in the prompt;
blast radius bounded — read-only + no network + key-proxied +
output-redacted).
- Requires the org's Anthropic/OpenAI spend limit to be sufficient, or
the model jobs 429.

---------

Co-authored-by: Julien Goux <hi@jgoux.dev>
…e on >=1 review (#6380)

Follow-up to the AI-review pipeline. Two changes.

## 1. Downgrade `codex-action` v1.12 → v1.11

On the large PR (#6366, ~130k-token diff) the `codex-review` step ran to
completion — Codex finished the turn, wrote its output file, printed its
final message and token count — then **sat idle until the 45-minute job
timeout**, discarding a completed review. That is a confirmed v1.12
regression: **openai/codex-action#150** ("v1.12: Linux run never returns
after the turn completes; job dies on timeout with the output file
already written"). The reporter confirms **v1.11 handles the same heavy
workload cleanly**, and there is no released fix above v1.12.

v1.11 (`52fe01ec…`) supports every input we use (`safety-strategy`,
`sandbox`, `output-schema-file`, `output-file`, `codex-version`,
`working-directory`, `effort`), so this is a drop-in pin change in both
Codex jobs.

## 2. Adjudicate on ≥1 independent review (graceful degradation)

Previously `adjudicate` required BOTH `claude-review` and `codex-review`
to succeed, so one flaky model job sank the whole review. Now it runs
when **at least one** independent pass succeeded: each findings download
is guarded by its job's result, and the stage step substitutes an empty
findings set for any review that didn't complete, so the adjudicator
reconciles one or two. The prompt notes the one-review case and records
it in its summary.

Together: a Codex hiccup no longer wastes a 45-minute run or blocks
Claude's (working) review from being posted.
## Summary

- prepare `/run/postgresql` for the Linux host UID/GID before the Docker
stack drops privileges
- preserve the existing root and non-Linux startup paths
- cover the privilege-drop ordering with a Linux-specific regression
test

## Context

The refreshed slim Postgres image listens on a Unix socket under
`/run/postgresql`. The stack wrapper bypassed the image root setup when
switching to the host user on Linux, so Postgres restarted with a socket
lock-file permission error. That readiness failure cascaded into the
three e2e startup timeouts visible on #6400.
This PR was automatically created to sync API types from the
infrastructure repository.

Changes were detected in the generated API code after syncing with the
latest spec from infrastructure.

Co-authored-by: supabase-cli-releaser[bot] <246109035+supabase-cli-releaser[bot]@users.noreply.github.com>
Co-authored-by: Andrew Valleteau <avallete@users.noreply.github.com>
## Summary

- consolidate fragmented Docker coverage into one public 13-service
stack journey
- verify canonical slim images, representative product behavior, and
restart persistence
- prove two automatically allocated sibling stacks keep ports, data,
ownership, and cleanup isolated

## Context

This is a test-only qualification change for CLI-2113. The existing
stack implementation already satisfied the complete Docker graph and
sibling-isolation contracts; the new journey makes those
release-critical guarantees observable through the public package
surface.
## TL;DR

fixes the CLI rejecting dashboard issued `sbp_v0_` access tokens with
`LegacyInvalidAccessTokenError` which was caused by the access token
regex pattern only

matching the `sbp_` and `sbp_oauth_` prefixes and 
is now fixed by widening the legacy validator to also accept the
`sbp_v0_` prefix...

## ref:
- closes: #6348

---------

Co-authored-by: Andrew Valleteau <avallete@users.noreply.github.com>
## Summary

Qualifies the first Dockerless native vertical slice through the public
`@supabase/stack` surface: isolated native prefetch, lazy and eager
activation, real Auth and PostgREST flows, PostgreSQL extensions,
restart preservation, retryable typed preparation failure, and exact
resource cleanup.

Adds a consumer-selected cache root to Promise-based prefetch, exposes
the public stack error type, and preserves lazy proxy activation across
a whole-stack restart without weakening explicit per-service stops.
## TL;DR

fixes `db reset, db lint, db diff`, and `migration down` silently
skipping a user schema when its oid also appears in another catalog
which was caused by joining `pg_depend` on objid without the `classid`
that scopes `oids` to a single catalog

now fixed by constraining the join to `pg_catalog.pg_namespace` rows in
every copy of the query.
Resets now drop schemas that earlier versions silently skipped....

## ref:
- closes: #6375
Adds one sentence to the Pull Requests section of `AGENTS.md`: this repo
is public, so PR descriptions, issues, and code comments keep internal
content out: absolute production metrics (percentages, ratios, or
relative change instead), internal decision detail (vendor, legal,
pricing, or strategy discussions), and competitor names (protocol
identifiers such as user-agent strings are fine). That context goes in
the linked Linear issue. Same rule as the supabase monorepo's agent
instructions (supabase/supabase#49750); an agent-authored PR there had
quoted absolute internal event volumes in its description.
## TL;DR

adds live e2e coverage for the `services` command and `storage mv`

## whats introduced?

- `services`: links the project and proves the postgres remote version
lands in the json output
proves the table renders that value in the LINKED cell, where a plain
substring match would pass vacuously
- `storage mv`: uploads an object, moves it through the real move
endpoint, and proves via the listing that the destination exists and the
source is gone
closes the storage family, since ls, cp and rm already have coverage
- `db pull`: deflakes the shipped live test, pull exits nonzero when
nothing changed by design, so the test now seeds remote-only schema
through db query and proves the initial pull writes it back as a
migration

## ref:
- closes: CLI-2263 CLI-2264 CLI-2278
## TL;DR

adds live e2e coverage for `migration up` and `migration repair`,
closing the migration family...

## whats introduced?

- `migration up`: applies a test written migration to the remote
database, proven by the apply banner and the history row migration list
reads back
- `migration repair`: inserts a history row with status applied, proves
it through migration list, then removes it with status reverted and
proves the absence

## ref:
- closes: CLI-2269
This PR was automatically created to sync API types from the
infrastructure repository.

Changes were detected in the generated API code after syncing with the
latest spec from infrastructure.

Co-authored-by: supabase-cli-releaser[bot] <246109035+supabase-cli-releaser[bot]@users.noreply.github.com>
)

## Summary

Adds an opt-in ambient env flag `SUPABASE_USE_SLIM_IMAGES` (`true` or
`1`) that rewrites local-stack Docker image names from the embedded
Dockerfile pins to the slim `ghcr.io/supabase/cli/` builds.

Published slim postgres/storage/auth/edge-runtime images now match the
docker.io contracts (root start, `sh`/`wget`), so the flag is an
image-name rewrite rather than a second runtime. Spec builders still
branch for services that remain distroless (auth/studio/pg-meta
healthchecks, pooler/realtime/analytics busybox wget, Vector
`secretFiles`). Kong, the `differ`/`migra`/`pgprove` job images, PG14,
OrioleDB, historical 15.x pins, and `deno_version = 1` stay on
docker.io. Slim refs skip `SUPABASE_INTERNAL_IMAGE_REGISTRY`. With the
flag unset, image *names* stay on docker.io.

This PR also bumps the shared Dockerfile pins (flag-off and flag-on use
the same versions) and syncs stack `DEFAULT_VERSIONS`:

- postgres `17.6.1.165` → `17.6.1.167`
- postgres 15 fallback `15.8.1.085` → `15.14.1.167` (slim-services
[#290](supabase/slim-services#290); published as
`ghcr.io/supabase/cli/postgres:15.14.1.167`)
- pooler `2.9.7` → `2.9.12`
- realtime `v2.129.9` → `v2.130.0`
- storage `v1.71.0` → `v1.72.1`

Majors 13/15 slim-translate that current PG15 pin when the flag is on.
Storage `v1.72.1` prefers `IMAGE_TRANSFORMATION_ENABLED` over
`ENABLE_IMAGE_TRANSFORMATION`, so the CLI now emits both keys on every
Storage spec (not slim-only).

The rewrite always targets `ghcr.io/supabase/cli/`. The stack catalog's
vector/pooler mirrors (`ghcr.io/supabase/{vector,supavisor}`) are not
used.

This is the code layer of a stack that splits the previous mixed review
on #6329. Docs live in #6383.

## Linked issue

Closes #

- [x] The linked issue is **open** and carries the
`open-for-contribution` label (or I'm a Supabase maintainer).

## Checklist

- [x] The PR title follows [Conventional
Commits](https://www.conventionalcommits.org/) (e.g. `fix(cli): …`).
- [x] Tests added or updated for the change.
- [ ] From the repository root, `pnpm check:all` passes; relevant
package tests pass for every touched workspace, and `pnpm types:check`
passes for each touched TypeScript workspace (or workspace declaring
it).

---------

Co-authored-by: Cursor <cursoragent@cursor.com>
avallete and others added 8 commits August 31, 2026 15:31
## Summary

Records `SUPABASE_USE_SLIM_IMAGES` on every legacy command whose image
resolution the flag reaches, so `SIDE_EFFECTS.md` matches the resolver.

Current contract:

- Ambient `process.env` only (`true`/`1`) — not project dotenv.
- Current Dockerfile pins rewrite to `ghcr.io/supabase/cli/`. Slim refs
skip `SUPABASE_INTERNAL_IMAGE_REGISTRY`.
- Kong, job images (`differ`/`migra`/`pgprove`), PG14, OrioleDB,
historical Postgres pins, and `deno_version = 1` stay on docker.io.
- Majors 13/15: flag-off keeps `15.8.1.085`; flag-on slim-translates the
published `15.14.1.167` pin.
- Slim postgres/studio/pg-meta/edge-runtime keep the docker.io probes
(`pg_isready` / `node`). Slim analytics still uses the docker.io start
spec (`./logflare` wrapper and BigQuery bind).
- Slim auth, storage, vector, realtime, analytics, and pooler ship
BusyBox wget (not GNU wget, not curl). In-container HEALTHCHECK is `wget
-q --spider` (realtime also `--header Host:realtime-dev`). Vector's
Logflare wait is `wget -q -T 2 --spider`. Flag-off docker.io wget stays
`--no-verbose --tries=1 --spider`.
- Storage emits both `ENABLE_IMAGE_TRANSFORMATION` and
`IMAGE_TRANSFORMATION_ENABLED`.
- Same-tag slim vs docker.io family mismatch remediates with `supabase
stop` then `supabase start` (same flag). `stop --all --no-backup` stays
for a real version mismatch.

Stacked on #6382 so reviewers see a docs-only diff.

---------

Co-authored-by: Cursor <cursoragent@cursor.com>
…an shadows (#6215)

## Summary

Rebased onto `develop` now that #6102, #6184, and #6203 are merged. The
PR is only the plan-shadow overlap — not the lower-stack cache/stop
work.

A declarative sync provisions two shadow databases (migrations +
declarative). Those used to run strictly sequentially, so the
declarative shadow's whole provision was **added** to the runtime
instead of overlapping it.

Provisioning now peeks each shadow's baseline-cache state
(`legacyPeekShadowBaseline`) and picks one of three strategies
(`legacy-pgdelta-next-shadow.plan.ts`):

- **`parallel`** — both snapshots already published: both warm-restore
concurrently. A warm restore skips the platform baseline, so only the
migrations fiber prints (`Applying migration ...`), live and in order.
- **`baseline-handoff`** — first run, both cold under one cache key: the
platform baseline is built once. The migrations shadow cold-provisions;
its snapshot export at the baseline seam signals the declarative fiber,
which warm-restores from the just-published tar concurrently with
migration replay. A handle that will never snapshot signals immediately,
and the runner `Effect.ensuring`s the signal onto the whole provision as
a liveness backstop.
- **`sequential`** — different keys, mixed states, `--no-cache`, cache
env off, PG≤14/OrioleDB: no baseline can be shared, so this keeps the
pre-parallel flow and transcript.

**Output ordering is a hard guarantee.** In the concurrent strategies
the declarative fiber's `Output` writes go through
`legacyBufferedShadowOutput` and flush after the join. Post-flush writes
pass through live so late teardown warnings are never lost.

Same-database identity still uses the **acquired** handles'
`snapshotKey`s (not the peeks), so a delayed declarative re-resolve
cannot lie about snapshot lineage.

Supporting cache changes:

- `legacyPeekShadowBaseline` answers "what would the acquire do right
now" without provisioning. The acquire always re-checks disk state.
- Immediate acquires reuse peeked key inputs via `precomputedKeyInputs`
so the JWKS discovery request is not resolved twice. Delayed declarative
acquires re-resolve so a mid-run `roles.sql` edit cannot publish under a
stale key.
- Cold snapshot exports are serialized by an in-process mutex
(`legacyExportPgDataTar`'s temp name is pid-scoped). The
absent-at-acquire dedupe skips a re-export only when the tar appeared
after the cold acquisition began; a tar retained through a failed warm
restore is still atomically replaced.

Dogfooded this PR against its merge base (`develop@38f31b4`) on
`supabase db schema declarative sync --no-apply --experimental`
(pg-delta next), full 2×2 matrix of {base, PR} ×
{`SUPABASE_SHADOW_CACHE` off/on}, 5 timed runs per cell plus extra
cold-cache samples. All docker images pre-pulled and the local stack
already running, so no run pays pull or stack-start cost. Times are full
CLI wall-clock on a converged project ("No schema changes found" — both
shadows still provisioned every run).

| Scenario | develop (base) | this PR | Delta |
|---|---|---|---|
| `SUPABASE_SHADOW_CACHE=0` | 21.96s ± 0.42 (n=5) | 22.32s ± 0.61 (n=5)
| none (within noise) |
| `SUPABASE_SHADOW_CACHE=1`, cold cache | 16.02s ± 0.66 (n=4) | 16.18s ±
0.38 (n=4) | none (within noise) |
| `SUPABASE_SHADOW_CACHE=1`, warm cache | 6.71s ± 0.49 (n=4) | **5.25s ±
0.14** (n=4) | **−1.46s, 21.8% faster (1.28×)** |

Per-run warm values — base: `6.03, 6.80, 6.79, 7.21` · PR: `5.38, 5.14,
5.12, 5.35`. The PR is also noticeably less noisy (σ 0.14 vs 0.49).

Co-authored-by: Claude <noreply@anthropic.com>
## Summary

Bumps the pinned pg-meta image from `v0.98.0` to `v0.99.0` in the shared
service-image manifest (`apps/cli-go/pkg/config/templates/Dockerfile`,
imported by the TypeScript CLI as its image source).

postgres-meta v0.99.0 replaces the embedded type-generation templates
with the shared
[`@supabase/postgrest-typegen`](https://github.com/supabase/sdk/tree/main/packages/postgrest-typegen)
package (supabase/postgres-meta#1084). This is part of a coordinated
rollout with the hosted path (supabase/platform#37764) so `gen types`
produces the same output locally and via `--project-id`.

## Relationship to #6404

#6404 makes `gen types` run postgrest-typegen in-process, removing the
pg-meta container from that command entirely. This pin still matters
independently of it: the same manifest entry provides the `pgmeta`
service that `supabase start` runs for Studio's local API, and it covers
`gen types` for any release cut before #6404 lands. The two do not
conflict (different files), and output is consistent either way since
v0.99.0 serves the same generator package that #6404 embeds.

## What changes for users

Generated TypeScript output changes in two deliberate ways:
deterministic metadata ordering (a one-time reordering diff when
regenerating existing types) and oxfmt formatting instead of prettier
(style-only). Content is otherwise unchanged.

## Validation

- `go build ./...` passes in both modules.
- The pre-existing `gen types` e2e tests pull this image tag directly,
so CI exercises the new release; the image is published on Docker Hub
and ECR Public.
This PR was automatically created to sync the generated `@supabase/api`
package with the latest Management API OpenAPI document.

Changes were detected in the upstream OpenAPI documents exposed by
`https://api.supabase.com/api/v1-json` and
`https://api.supabase.com/api/v2-json`.

Co-authored-by: jgoux <1443499+jgoux@users.noreply.github.com>
Co-authored-by: Andrew Valleteau <avallete@users.noreply.github.com>
## Summary

Changes the shadow baseline cache (`SUPABASE_SHADOW_CACHE`) from opt-in
(default OFF) to opt-out (default ON). This improves performance for `db
diff`, `db pull`, and schema declarative operations by caching the
baseline PGDATA snapshot by default, while allowing users to disable it
by explicitly setting `SUPABASE_SHADOW_CACHE=0` or `false`.

### Key Changes

1. **Environment variable semantics**: `SUPABASE_SHADOW_CACHE` now
defaults to enabled when unset. Setting it to any non-viper-true value
(`0`, `false`, empty, or garbage) disables the cache.

2. **New `whenUnset` option**: Extended
`legacyViperEnvBoolWithProjectFallback` with an optional `whenUnset`
parameter that resolves unset keys to a specified boolean, enabling
opt-out gate semantics while preserving exact `ParseBool` behavior for
present values.

3. **Updated documentation**: All SIDE_EFFECTS.md files and code
comments reflect the new default-ON behavior and opt-out mechanism.

4. **Test coverage**: Added tests for the new `whenUnset` option,
flipped the default-gate integration test to assert the default-ON cold
export + warm restore, and added a project-dotenv opt-out test.

### Behavior

- **Unset or true**: Cache is enabled (cold run snapshots baseline, warm
runs restore from snapshot)
- **Explicitly set to `0`/`false`/empty/garbage**: Cache is disabled
(uncached create/remove pair, identical to old default)
- **Project dotenv support**: The setting is honored from both shell
environment and project `.env` files
- **`sync --no-cache`** still bypasses restore and publish per
invocation

Users who explicitly disabled the cache keep their behavior; all other
runs now leave up to 3 ~90MB baseline tars (2-day TTL) under
`~/.supabase/cache/shadow-baseline/`.

## Linked issue

Closes #

- [x] The linked issue is **open** and carries the
`open-for-contribution` label (or I&#39;m a Supabase maintainer).

## Checklist

- [x] The PR title follows [Conventional
Commits](https://www.conventionalcommits.org/) (e.g. `fix(cli): …`).
- [x] Tests added or updated for the change.
- [x] From the repository root, `pnpm check:all` passes; relevant
package tests pass for every touched workspace, and `pnpm types:check`
passes for each touched TypeScript workspace (or workspace declaring
it).

https://claude.ai/code/session_01Uj7BjiXEnbcWy41ToxCnPs

🤖 Generated with [Claude Code](https://claude.com/claude-code)

---------

Co-authored-by: Claude <noreply@anthropic.com>
Co-authored-by: Cursor <cursoragent@cursor.com>
## Summary

Prefetch and version unit tests were pinning published pgmeta and vector
image tags. Those assertions fail whenever `ServiceCatalog.ts` and the
template Dockerfile are bumped.

The tests now derive the expected images from `DEFAULT_VERSIONS` /
`dockerImageForService`, matching the other catalog-backed cases in the
same files.

## Linked issue

No linked issue — test-only maintenance so image bumps do not fail
unrelated unit tests.

Made with [Cursor](https://cursor.com)

Co-authored-by: Cursor <cursoragent@cursor.com>
Add a `supabase experimental` command family, registered with
`Command.unlisted`, and move `workers` underneath it so the family stays
invocable but is explicitly marked unstable and excluded from help,
shell
completions, the wizard, and generated docs.

- Add `legacy/commands/experimental/experimental.command.ts` as the new
unlisted parent and mount it in `root.ts`, replacing the direct
`workers` registration
- Relocate the `workers` command tree (`delete`, `list`, `new`, `push`,
`status`, shared helpers, and tests) under `experimental/workers/`,
updating relative imports accordingly
- Update every user-facing invocation string (examples, suggestions,
error messages, comments) in handlers, tests, and shared worker
utilities from `supabase workers ...` to `supabase experimental workers
...`
- Drop the `supabase-workers` entries from the legacy docs tables so the
family no longer appears in generated docs

---------

Co-authored-by: Kanad Gupta <git@kanad.dev>
…n /apps/cli-go in the go-minor group across 1 directory (#6412)

Bumps the go-minor group with 1 update in the /apps/cli-go directory:
[github.com/posthog/posthog-go](https://github.com/posthog/posthog-go).

Updates `github.com/posthog/posthog-go` from 1.23.1 to 1.24.0
<details>
<summary>Release notes</summary>
<p><em>Sourced from <a
href="https://github.com/posthog/posthog-go/releases">github.com/posthog/posthog-go's
releases</a>.</em></p>
<blockquote>
<h2>1.24.0</h2>
<h2>Unreleased</h2>
</blockquote>
</details>
<details>
<summary>Changelog</summary>
<p><em>Sourced from <a
href="https://github.com/PostHog/posthog-go/blob/main/CHANGELOG.md">github.com/posthog/posthog-go's
changelog</a>.</em></p>
<blockquote>
<h2>1.24.0</h2>
<h3>Minor Changes</h3>
<ul>
<li>150f03e: Fall back to <code>/flags</code> when a requested flag is
missing from loaded local definitions. This changes the earlier behavior
where the key was omitted without a request.</li>
</ul>
</blockquote>
</details>
<details>
<summary>Commits</summary>
<ul>
<li><a
href="https://github.com/PostHog/posthog-go/commit/2eaba7155afd758bf9027371a6f9ee9a9b5f6bcf"><code>2eaba71</code></a>
chore: release v1.24.0 [version bump] [skip ci]</li>
<li><a
href="https://github.com/PostHog/posthog-go/commit/35100f0aace345e153da3e1d284d56f71c96f8f7"><code>35100f0</code></a>
fix(release): gate released Slack notification on an actual release (<a
href="https://redirect.github.com/posthog/posthog-go/issues/293">#293</a>)</li>
<li><a
href="https://github.com/PostHog/posthog-go/commit/bded1a0e9f9ba01e22f0fac12997ba2a53ff34fb"><code>bded1a0</code></a>
fix(release): opt private package into changesets v3 versioning (<a
href="https://redirect.github.com/posthog/posthog-go/issues/292">#292</a>)</li>
<li><a
href="https://github.com/PostHog/posthog-go/commit/150f03e2ec5e034f5a0a219bd46545bcaa55a147"><code>150f03e</code></a>
fix(flags): fall back for missing local definitions (<a
href="https://redirect.github.com/posthog/posthog-go/issues/286">#286</a>)</li>
<li><a
href="https://github.com/PostHog/posthog-go/commit/fd8580e08c50150a2c27e6941fa9717326dd94dc"><code>fd8580e</code></a>
chore(deps): bump the github-actions group with 3 updates (<a
href="https://redirect.github.com/posthog/posthog-go/issues/290">#290</a>)</li>
<li><a
href="https://github.com/PostHog/posthog-go/commit/176cbdca624348e82d56a26c305ec724eef78759"><code>176cbdc</code></a>
chore(deps-dev): bump <code>@​changesets/cli</code> from 2.31.1 to 3.0.0
in the release-too...</li>
<li><a
href="https://github.com/PostHog/posthog-go/commit/803058843e9b42b54eec13c077c3e7286064bc0d"><code>8030588</code></a>
chore: update flags project workflow caller (<a
href="https://redirect.github.com/posthog/posthog-go/issues/287">#287</a>)</li>
<li><a
href="https://github.com/PostHog/posthog-go/commit/d0ba449b96cf32bd34ff272441c01f0418f20a82"><code>d0ba449</code></a>
test: expand server SDK wire snapshots (<a
href="https://redirect.github.com/posthog/posthog-go/issues/285">#285</a>)</li>
<li>See full diff in <a
href="https://github.com/posthog/posthog-go/compare/v1.23.1...v1.24.0">compare
view</a></li>
</ul>
</details>
<br />


[![Dependabot compatibility
score](https://dependabot-badges.githubapp.com/badges/compatibility_score?dependency-name=github.com/posthog/posthog-go&package-manager=go_modules&previous-version=1.23.1&new-version=1.24.0)](https://docs.github.com/en/github/managing-security-vulnerabilities/about-dependabot-security-updates#about-compatibility-scores)

Dependabot will resolve any conflicts with this PR as long as you don't
alter it yourself. You can also trigger a rebase manually by commenting
`@dependabot rebase`.

[//]: # (dependabot-automerge-start)
[//]: # (dependabot-automerge-end)

---

<details>
<summary>Dependabot commands and options</summary>
<br />

You can trigger Dependabot actions by commenting on this PR:
- `@dependabot rebase` will rebase this PR
- `@dependabot recreate` will recreate this PR, overwriting any edits
that have been made to it
- `@dependabot show <dependency name> ignore conditions` will show all
of the ignore conditions of the specified dependency
- `@dependabot ignore <dependency name> major version` will close this
group update PR and stop Dependabot creating any more for the specific
dependency's major version (unless you unignore this specific
dependency's major version or upgrade to it yourself)
- `@dependabot ignore <dependency name> minor version` will close this
group update PR and stop Dependabot creating any more for the specific
dependency's minor version (unless you unignore this specific
dependency's minor version or upgrade to it yourself)
- `@dependabot ignore <dependency name>` will close this group update PR
and stop Dependabot creating any more for the specific dependency
(unless you unignore this specific dependency or upgrade to it yourself)
- `@dependabot unignore <dependency name>` will remove all of the ignore
conditions of the specified dependency
- `@dependabot unignore <dependency name> <ignore condition>` will
remove the ignore condition of the specified dependency and ignore
conditions


</details>

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
@supabase-cli-releaser
supabase-cli-releaser Bot requested a review from a team as a code owner September 1, 2026 02:26
@supabase-cli-releaser supabase-cli-releaser Bot added the do not merge Approve to apply; do not merge. label Sep 1, 2026

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: 95f0c2bfac

ℹ️ About Codex in GitHub

Codex has been enabled to automatically review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

When you sign up for Codex through ChatGPT, Codex can also answer questions or update the PR, like "@codex address that feedback".

const entries: Record<string, string> = {
should_run: String(result.shouldRun),
pr_number: String(prNumber),
head_ref: `refs/pull/${prNumber}/head`,

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P2 Badge Pin the review run to one head SHA

Capture the PR's immutable head.sha here instead of exporting the mutable refs/pull/<n>/head. These reviews can run for up to an hour, and the Claude job, independent Codex job, adjudicator, and posting code each resolve or fetch the PR at different times; if another commit is pushed during the run, they can review different revisions and ultimately post incomplete or stale findings against the newest diff. Export the resolved SHA and either use it for every checkout/diff or abort before posting when the PR head has changed.

Useful? React with 👍 / 👎.

Comment on lines +54 to +55
(github.event_name == 'issue_comment' && github.event.comment.body != '/ai-review')
&& github.run_id || 'review' }}

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P2 Badge Normalize valid commands in the concurrency key

Use the same normalization as the resolver when deciding whether this is an /ai-review command. The resolver accepts a trimmed first line, so /ai-review and /ai-review\n... are valid requests, but this full-body equality assigns each one a unique github.run_id group. Consequently, repeated valid requests in those forms do not cancel the in-flight review and can run multiple expensive pipelines that race to post and supersede each other's output.

Useful? React with 👍 / 👎.

);
}

await supersedePriorRunsBestEffort(io, prNumber);

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P1 Badge Exclude the review that was just posted

The successful POST is followed by a fresh listReviews call, but supersedePriorRuns updates every unsuperseded marker-bearing review by github-actions[bot] and has no ID or body exclusion for the review just created. Once GitHub returns that new review in the list—which is the normal result of querying after creation—the pipeline immediately wraps its own current review as “Superseded by a newer AI review.” Capture the prior entries before posting or return the created review ID and exclude it.

Useful? React with 👍 / 👎.

Comment on lines +798 to +799
const marker = `\n\n… (truncated — see workflow run: ${runUrl})`;
return body.slice(0, GITHUB_REVIEW_BODY_MAX - marker.length) + marker;

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P2 Badge Preserve the review marker when truncating

When a rendered review exceeds the limit, this slices off its tail and appends only the visible truncation notice. Because AI_REVIEW_MARKER is emitted at the very end of the original body, oversized reviews are posted without the marker, so the automatic dedup check cannot recognize them and later manual runs cannot supersede them. Include the hidden marker in the reserved truncation suffix.

Useful? React with 👍 / 👎.

name: AI Review

# One-shot AI code review: replaces the Codex GitHub App's automatic
# per-push reviews (which churned 30-40 short rounds per PR) with a single

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P1 Badge Remove the internal review-volume metric

Replace the exact “30-40” review-round count with a qualitative statement. This workflow is committed to the public repository, while the repository guidance explicitly prohibits publishing absolute internal event counts in code comments and directs that context to the private issue tracker instead.

AGENTS.md reference: AGENTS.md:L276-L276

Useful? React with 👍 / 👎.

Comment on lines +539 to +540
permissions:
pull-requests: write

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P1 Badge Grant contents read access to the posting job

Add contents: read to this job's permissions. The workflow-level permissions: {} disables every unspecified token scope, and this job currently grants only pull-requests: write, yet its first step checks out develop; actions/checkout requires repository contents read access, so the job can fail before it downloads or posts the completed review.

Useful? React with 👍 / 👎.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

do not merge Approve to apply; do not merge.

Projects

None yet

Development

Successfully merging this pull request may close these issues.

7 participants