Skip to content

chore(repo): sync develop into next - #7082

Closed
supabase-cli-releaser[bot] wants to merge 21 commits into
nextfrom
sync/develop-into-next
Closed

supabase-cli-releaser[bot] wants to merge 21 commits into
nextfrom
sync/develop-into-next

Conversation

@supabase-cli-releaser

Copy link
Copy Markdown
Contributor

Merging develop into next conflicted, so Claude resolved it on sync/develop-into-next. Every later push to develop updates this pull request instead of opening another one.

3 decisions need review.

Approve to fast-forward next; do not use the merge button. To change a resolution, push to sync/develop-into-next and explain the decision in a comment: later syncs read this pull request and reuse the decision. Converting this pull request to a draft pauses updates until it is marked ready again.

Earlier resolution comments on this pull request still apply. Latest:

Resolution for 5f82350

Claude (claude-opus-5-5) merged into sync/develop-into-next. Workflow run

develop (f825003)

I resolved all 8 files in group 1. next deletes the Go CLI, and develop's edits to the three Go-only files (two workflows and the Go Dockerfile) are covered elsewhere or no longer matter, so those files are deleted. In the remaining files, develop's content is ported onto next's Go-free wording. Nothing has been run, so CI is the first check. No earlier sync settled any of these files, so I followed no precedent. I resolved all eight files in group 2 and removed every conflict marker. No checks have been run, since I can't run commands here; CI will run them on the PR.

  • Most conflicts were the same pattern. next renamed tests and messages to drop Go wording and made pg-delta on by default. develop moved code to Effect 4.0.2 and the Effect lint style (scoped temp dirs, withEnv config providers, Cause.pretty, Effect.callback). I kept develop's new structure and applied next's names, messages and pg-delta default on top.
  • One field stays removed. next deleted envLookup from the config reader's result, while develop had only narrowed its type. I couldn't search the codebase from this session, so I haven't confirmed that no develop-side code still reads that field. If any does, the type-check will flag it.
  • Two files are deleted. next removed the supabase-go proxy layer and its test; develop only changed import paths in them.

No earlier sync PR covered these files, so none of the resolutions cites a precedent. I resolved all eight files in group 3. I couldn't run any checks, so CI has to confirm the result type-checks. The main change from develop is the effect 4.0.2 upgrade: imports move from effect/unstable/cli to effect/cli, and constructors are renamed from Flag.string/Argument.string to Flag.String/Argument.String. I applied that onto next's version of each file. next deleted the four db branch leaf command files and develop only changed their imports, so they are deleted. No earlier sync pull request covered these files. I resolved all 8 files in group 4. All conflict markers are gone, and nothing was run because I can't execute commands here; CI will check the result. Every resolution keeps next's breaking changes and adds develop's Effect 4.0.2 upgrade or its OrioleDB slim-image doc wording. No recorded precedent applied: the only earlier sync, #7059, was closed without landing. I resolved all 8 files in group 5. One needs a maintainer's call: next and develop each added a different ADR as 0030, and both entries are now in the ADR index under that number. No earlier sync settled any of these files; the only past sync (#7059) was closed without landing. I couldn't run any checks, so type-checking and tests are left to CI. In most files the merge combines develop's Effect 4.0.2 API renames (effect/cli imports, Flag.Literals, Flag.String, Flag.Int) with next's removal of Go wording. I resolved the conflict in mise.toml. The Go and golangci-lint entries stay removed, as next intended when it dropped the supabase-go binary. The jactionlint and shellcheck entries from develop are kept because the workflow lint checks need them.

Needs a decision

  1. next added ADR 0030 'Go CLI Removal' and develop added ADR 0030 'Hotfix Releases'. Which one keeps 0030? (docs/adr/README.md)
    • Chosen: Kept both index entries at 0030 so neither ADR is lost. One still has to be renumbered: probably next's Go CLI Removal ADR moves to 0031, since develop's ADR has already shipped. That means renaming its file and updating references to it.
    • Alternative: Renumber develop's Hotfix Releases ADR to 0031 instead. That breaks links that already point to it on develop.
  2. This workflow file conflicted and runs with repository secrets. Is the resolution right? (.github/workflows/cli-go-api-sync.yml)
    • Chosen: The resolution on this branch.
    • Alternative: Resolve it by hand on the sync branch.
  3. This workflow file conflicted and runs with repository secrets. Is the resolution right? (.github/workflows/cli-go-mirror.yml)
    • Chosen: The resolution on this branch.
    • Alternative: Resolve it by hand on the sync branch.

Resolved files

  • .github/workflows/cli-go-api-sync.yml: Deleted, as next removed the Go CLI and its workflows. develop only quoted $GITHUB_OUTPUT for the new jactionlint check, which doesn't apply to a removed workflow. Flagged for review because it is under .github/.
  • .github/workflows/cli-go-mirror.yml: Deleted, as next removed the Go CLI and its workflows. develop only quoted $GITHUB_OUTPUT for the new jactionlint check, which doesn't apply to a removed workflow. Flagged for review because it is under .github/.
  • CONTRIBUTING.md: Kept next's removal of the Go and golangci-lint tool entries and the Go version files. Added develop's jactionlint and shellcheck rows to the tool table, plus its note that pnpm check:all needs shellcheck on PATH.
  • apps/cli-go/pkg/config/templates/Dockerfile: Deleted along with the rest of the Go tree. develop's realtime v2.143.3, storage v1.81.0 and logflare 1.53.0 bumps are already in next's generated apps/cli/src/shared/services/Dockerfile.
  • apps/cli/docs/release-process.md: In See Also, kept develop's new link to ADR 0030 (hotfix releases) and next's single-binary description of binary-distribution.md. develop's hotfix, rollback and sync text merged without conflict.
  • apps/cli/src/cli/complete.ts: In the comment above the duration-flag set, combined next's Go-free wording (isValidDuration) with develop's Effect 4.0.2 name Flag.String. The rest of the Effect upgrade (imports, Int/Finite tags) merged cleanly.
  • apps/cli/src/command-internal/db-config.integration.test.ts: Used develop's Effect rewrite of the linked-config-ordering test (scoped temp dir via FileSystem, Cause.pretty, BunServices) under next's title without the Go ParseDatabaseConfig reference.
  • apps/cli/src/command-internal/db-config.parse.unit.test.ts: Took develop's full Effect rewrite (layered it.effect tests, withConfigEnv, scoped temp files instead of process.env and node:fs). Then applied each of next's renames that drop pgconn and Go references from test and describe titles.
  • apps/cli/src/command-internal/db-config.toml-read.ts: Kept next's removal of the envLookup field from the config reader's result. develop's other changes merged without conflict and are kept: the shell-env lookup that goes through Effect's config service, the list of SUPABASE_* override variable names, and failing with the error directly.
  • apps/cli/src/command-internal/db-config.toml-read.unit.test.ts: Kept develop's Effect-based setup (scoped temp dirs, withEnv providers, Cause.pretty) with next's test names and its new 'expected a string, got …' error text. The pg-delta tests follow next's on-by-default behaviour: the remote-block test now sets the env override to "false", and the absolute-path test still checks that pg-delta is enabled.
  • apps/cli/src/command-internal/db-connection.sql-pg.integration.test.ts: Used next's test name for the auth-failure rendering test, with develop's direct yield* fakePostgresServer(...) instead of the Effect.promise wrapper.
  • apps/cli/src/command-internal/db-connection.sql-pg.unit.test.ts: Rewrote the failing step-down test as develop's it.effect/Effect.callback version and dropped the Go-parity suffix from its name, as next did.
  • apps/cli/src/command-internal/db-image.unit.test.ts: Used develop's scoped withTemp effect with next's test name, which drops the Go reference.
  • apps/cli/src/command-internal/global-flags.ts: Kept next's hidden 'Removed' --create-ticket flag (description and comment) and switched it to develop's Effect 4.0.2 GlobalFlag.Setting / Flag.Boolean constructors.
  • apps/cli/src/command-internal/string-slice-flag.ts: Kept next's flagLabel rename and the wording without Go references, and switched the flag to develop's Flag.String constructor.
  • apps/cli/src/commands/db/branch/branch.command.ts: Kept next's removed-command placeholders for db branch, which are defined inline. They now import from effect/cli and use Argument.String, matching the effect upgrade. The imports of the deleted leaf files are dropped.
  • apps/cli/src/commands/db/branch/create/create.command.ts: Deleted, as on next. develop only updated its imports, and the replacement placeholder now lives in branch.command.ts.
  • apps/cli/src/commands/db/branch/delete/delete.command.ts: Deleted, as on next. develop only updated its imports, and the replacement placeholder now lives in branch.command.ts.
  • apps/cli/src/commands/db/branch/list/list.command.ts: Deleted, as on next. develop only updated its imports, and the replacement placeholder now lives in branch.command.ts.
  • apps/cli/src/commands/db/branch/switch/switch.command.ts: Deleted, as on next. develop only updated its imports, and the replacement placeholder now lives in branch.command.ts.
  • apps/cli/src/commands/db/diff/diff.command.ts: Kept next's engine-flag comment and its hidden --use-pg-schema flag that reports the removal, and switched both flags to develop's Flag.Boolean constructor.
  • apps/cli/src/commands/db/dump/SIDE_EFFECTS.md: Kept next's environment-variable table, which drops the DB_PASSWORD viper key. Added develop's OrioleDB wording ("OrioleDB tags the catalog does not pin") and realigned the table columns.
  • apps/cli/src/commands/db/pull/SIDE_EFFECTS.md: Kept develop's wider env-var table, including its new OrioleDB wording ("OrioleDB tags the catalog does not pin"). Dropped the SUPABASE_EXPERIMENTAL_PG_DELTA row because next no longer reads that variable.
  • apps/cli/src/commands/db/remote/changes/changes.command.ts: Kept next's stub that tells users the command was removed, with its runtime and telemetry imports. Switched the CLI import to develop's effect/cli path and dropped the unused handler and type imports.
  • apps/cli/src/commands/db/test/SIDE_EFFECTS.md: Took next's rewritten Notes. They no longer mention Flag.boolean, so develop's rename to Flag.Boolean has nothing left to update.
  • apps/cli/src/commands/functions/download/download.command.ts: Kept next's --legacy-bundle flag, which is optional and now only produces a removal error, along with its Effect/Layer/Option imports. Used develop's effect/cli import paths and its Flag.Boolean constructor.
  • apps/cli/src/commands/gen/keys/keys.command.ts: Kept next's stub that tells users the command was removed, with its imports. Switched the CLI import to effect/cli and dropped the unused handler and type imports.
  • apps/cli/src/commands/gen/types/types.command.ts: Kept next's updated comment ("the handler prints the deprecation line") and used develop's Flag.Boolean constructor for --postgrest-v9-compat.
  • apps/cli/src/commands/gen/types/types.handler.ts: Kept next's local loadCliConfig import from command-internal/cli-config-load.ts and used develop's effect/process import path. develop's change to the connection-string parser in the preview-branch pooler fallback had already merged cleanly.
  • apps/cli/src/commands/start/SIDE_EFFECTS.md: Took develop's env-var table with the new OrioleDB slim-image wording. Re-applied next's change of the SUPABASE_* row text to "Generic env override", which removes the Viper wording.
  • apps/cli/src/commands/storage/cp/cp.command.ts: Kept next's comment without the pflag/Go wording and applied develop's rename of Flag.integer to Flag.Int.
  • apps/cli/src/shared/cli/run.unit.test.ts: Kept next's Data/Runtime imports, which its custom-exit-code test error needs, and switched to develop's effect/cli import path.
  • apps/cli/src/shared/init/project-init.templates.unit.test.ts: Kept develop's change that reads the OrioleDB version from the rendered template instead of a hard-coded value, plus its new pinned-version test. Kept next's renamed helpers and its comments without Go wording.
  • apps/cli/src/shared/telemetry/error-actionability.ts: Merged the error-fingerprint lists alphabetically: develop's release_mismatch (from the stack-failure classification) next to next's removed_command and removed_flag. Both sides' other changes merged without conflict.
  • apps/cli/src/telemetry/command-telemetry.unit.test.ts: Used develop's Flag.Literals API with next's test names (no 'Go parity' wording) and its single-line test layout.
  • docs/adr/README.md: Kept both new ADR index entries: next's 'Go CLI Removal' and develop's 'Hotfix Releases'. Both currently use number 0030.
  • knip.jsonc: Dropped go from ignoreBinaries, since next removed the Go toolchain, and kept develop's new jactionlint entry.
  • mise.lock: Removed the go and golangci-lint lock entries as next did, and kept develop's new jactionlint and shellcheck entries.
  • mise.toml: Kept next's removal of the go and golangci-lint tool pins. Kept the [tools] table with only the jactionlint and shellcheck pins that develop added for GitHub Actions workflow linting.
  • .github/workflows/cli-go-api-sync.yml: deleted
  • .github/workflows/cli-go-mirror.yml: deleted
  • apps/cli-go/pkg/config/templates/Dockerfile: deleted
  • apps/cli/src/command-internal/go-proxy.layer.ts: deleted
  • apps/cli/src/command-internal/go-proxy.layer.unit.test.ts: deleted
  • apps/cli/src/commands/db/branch/create/create.command.ts: deleted
  • apps/cli/src/commands/db/branch/delete/delete.command.ts: deleted
  • apps/cli/src/commands/db/branch/list/list.command.ts: deleted
  • apps/cli/src/commands/db/branch/switch/switch.command.ts: deleted

Format and type check

Passed after these changes to the merged tree:

  • apps/cli/src/commands/functions/download/download.removed-flag.integration.test.ts: Changed the CliOutput/Command import from 'effect/unstable/cli' to 'effect/cli'.
  • apps/cli/src/commands/services/services.integration.test.ts: Renamed the setup option goOutput to outputFlag in the OrioleDB test.

@supabase/cli: 3 choices need a decision. Approve to keep them. To reverse one, push the change to sync/develop-into-next and reply here with the decision; later syncs follow it.

supabase-cli-releaser Bot and others added 21 commits October 8, 2026 10:51
This bumps storage from v1.80.0-r0 to v1.80.2-r0.


https://github.com/supabase/slim-services/releases/tag/storage-v1.80.2-r0

Planned after supabase/slim-services published v1.80.1-r0. This branch
is rewritten from develop whenever a newer relevant release arrives.

Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>
…nt (CLI-2653) (#7045)

## TL;DR

brings the `db` connection string parser, `pgpass` and `pgservicefile`
under the effect lint

## whats introduced?

- `db-config.parse`, `pgpass` and `pgservicefile` join the allow list
file by file, so the rest of the `db` module waits for the later PRs in
this stack
- the parser reads `pgpass` and the service file through the
`FileSystem` and `Path` services, and its libpq env reads go through
`Config` once up front
- `parseConnectionString` and `poolerConfigFromConnectionString` become
effects, and every caller across `db`, `stack`, `test-db`, `migration
squash`, `gen types` and the pg-delta engine yields them
- an empty shell var still wins over the project `.env`, a missing
`pgpass` or service file still reads as absent, and every parse error
keeps its text
- unit tests run on temp dirs and a pinned `Config` env instead of
`process.env` writes, with a new case for the empty shell var

## ref

- related: CLI-2653
) (#7046)

## TL;DR

brings the `db` pg connection layer and few resolvers under the effect
lint

## whats introduced?

- `db-connection` and `db-dns` join the allow list
- the `sslrootcert`, `sslcert` and `sslkey` reads go through
`FileSystem`, keeping the BOM and the errno messages, and
`dbConnectionLayer` captures it at build so `DbConnection.connect` keeps
its type
- a cert path with a NUL byte, only reachable as `%00` in a DSN, now
reads `FileSystem.readFile: ...` instead of `TypeError
[ERR_INVALID_ARG_VALUE]: ...`, since the platform keeps only the message
for that throw
- `--dns-resolver https` sends the same request through `HttpClient`
with automatic HTTP tracing disabled, so no trace headers reach
Cloudflare, and keeps every failure text and the 10s timeout; a
`Db.resolveHostsOverHttps` span records the response status and answer
count
- tests pin the full cert read errors and cover the DoH resolver:
non-200, rejected request, no valid IP, invalid and empty JSON and the
timeout

## ref

- related: CLI-2653
…I-2653) (#7048)

## TL;DR

brings the `db` config toml reader under the effect lint

## whats introduced?

- `db-config.toml-read` joins the allow list
- shell env reads go through `Config` once, for the override names and
every `env(...)` ref in the toml, and the sync `envLookup` reads from
that snapshot
- `config push` drops its copy of the env ref helpers and uses the
reader's
- the toml parse runs before the env snapshot with the same failure
order and messages
- invalid signing keys files retain native JSON parser details in both
`config.toml` loading and `local-config-values`, with the same narrow
lint exception used by the SSO readers
- unit tests pin env through `Config` and temp dirs instead of
`process.env` writes, and the push, reset and start integration tests
pin the three values the reader now takes from `Config`

## ref

- related: CLI-2653
…I-2653) (#7049)

## TL;DR

brings the rest of the `db` module under the effect lint

## whats introduced?

- the per file `db-config.parse`, `db-config.toml-read`, `db-connection`
and `db-dns` entries collapse into `db-*.ts`, and `branch-target`,
`connect-errors`, `pooler-fallback` and `schema-flags` join, which
covers the whole `db` module
- `db-config.layer`, `db-pull-run` and `db-push-core` yield their errors
directly with the same classes and messages, and `branch-target`
recovers through `Effect.option` and `orElseSucceed`
- `db-config` integration tests feed env through `Config` instead of
`process.env` hooks, and `db-image` and `db-target-flags` move to
`it.effect`

## ref

- closes: CLI-2653
This bumps realtime from v2.142.0-r0 to v2.143.0-r0.


https://github.com/supabase/slim-services/releases/tag/realtime-v2.143.0-r0

Planned after supabase/slim-services published v2.143.0-r0. This branch
is rewritten from develop whenever a newer relevant release arrives.

---------

Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>
Co-authored-by: Andrew Valleteau <avallete@users.noreply.github.com>
Co-authored-by: Julien Goux <hi@jgoux.dev>
Linear: [CLI-2442](https://linear.app/supabase/issue/CLI-2442)

Hotfix PR gating, the first of three PRs that complete the hotfix flow
on top of the branch and release work from #7038. A hotfix is a
`hotfix/*` PR into `main` with a `fix`, `perf`, or `revert` title;
squash-merging publishes the next stable patch and the existing sync
carries it back to `develop`.

- **Check Deploy** always runs and reports. On the scheduled `develop`
promotion it succeeds. On `hotfix/*` heads it requires the title to
start with `fix`, `perf`, or `revert`, with an optional scope and no
`!`, and the failure message says what to change. Any other head fails,
and so does a fork head on either path: hotfixes come from this
repository. The job is named so it can become a required status check on
`main` later; because `main` has no App bypass, the promotion's head SHA
must carry a real success for the deploy fast-forward push to pass.
- **Release Smoke Test** triggers on hotfix PRs into `main` and runs the
shared release pipeline with `dry_run: true`, restoring the
build-and-smoke rehearsal that beta normally provides. Dispatch inputs
keep their defaults. Runs are per-PR concurrent with cancel-in-progress,
and fork pull requests are skipped since their token cannot hold the
permissions the shared workflow declares.
- **Release dispatch guard**: a non-dry-run stable release can only be
dispatched from `main`. The `hotfix/*` exemption existed for the manual
rehearsal, which this PR makes automatic. @Coly010, was a real stable
publish from an unmerged hotfix branch intended? If so, say so and I
will restore it.

Verified on a scratch repository: with a ruleset requiring only this
check on `main`, a direct push of a deploy PR head and of a hotfix PR
head both passed once the job had reported on the head SHA, and a push
with no check run was rejected (rule suites 4418391424 and 4418634505).
The runbook's hotfix section and the rollback policy change in a
separate PR.

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

---------

Co-authored-by: Claude <noreply@anthropic.com>
…#7052)

Linear: [CLI-2442](https://linear.app/supabase/issue/CLI-2442)

Third of three PRs for the hotfix flow on top of #7038. Documentation
only.

- **Runbook, hotfix section** (`apps/cli/docs/release-process.md`): when
a hotfix is warranted, the patch-type title rule and why not to edit the
squash subject, the checks that run automatically including the dry-run
release rehearsal, the sync back into `develop` and what to do when it
conflicts, the interaction with an open deploy PR, and how a hotfix
reaches `@supabase/config` consumers. The manual dry-run dispatch step
is gone.
- **Runbook, rollback section**: replaced by the forward-only policy. A
`revert:` hotfix is the response to a bad release.
- **ADR 0030**: hotfix criteria, forward-only, the required `Check
deploy`, the automatic rehearsal, and the notifications, referencing ADR
0028 for the sync and fast-forward mechanics.
- **Maintainers guide and root instructions**: a short hotfix paragraph
and one sentence respectively, pointing at the runbook.

Stacked on #7050, so the workflows this runbook describes are in the
checkout: review this diff against that branch. It merges after #7050
and #7051 (Slack and the fast-forward comment); once #7050 lands, GitHub
retargets this PR to `develop` and I bring `develop` in before it goes
through the queue.

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

Co-authored-by: Claude <noreply@anthropic.com>
Linear: [CLI-2442](https://linear.app/supabase/issue/CLI-2442)

Second of three PRs for the hotfix flow on top of #7038. After a hotfix
publishes from `main`, the sync merges `main` back into `develop`. When
that conflicts, the bot opens a sync PR that nobody is told about, and a
Tuesday deploy approved in the meantime is refused with a comment that
only says `main` moved. This PR closes both gaps without changing how
the sync or the fast-forward work.

- **Sync branches** exposes the conflict PR number as a job output. For
the `main-into-develop` pair a new job posts a `sync-conflict` message
to the release Slack channel with the PR link and the resolution steps,
through the shared Slack workflow. The `develop-into-next` pair is
unchanged. CODEOWNERS already requests the CLI team on these PRs, so no
review request is added.
- **Fast-forward on approval**: when a deploy PR is refused because
`main` has commits `develop` lacks, the comment names the open
`sync/main-into-develop` PR, or tells the approver to dispatch the sync
if none is open. A failed lookup falls back to the generic comment
rather than skipping it.
- **Slack notify** gains the `sync-conflict` status and a `pull_request`
input; `version` becomes optional for messages that are not about a
release.

Draft alongside #7050; both are independent of each other.

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

---------

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

**TL;DR** Failures from the new local stack (`supabase stack *`, and
stack-backed `db reset`, `db dump`, `db diff`, `test db` and `functions
serve`) now reach telemetry with a cause. Before, most of them were
reported as one fingerprint per error tag with category `unknown`, so
start and destroy failures couldn't be told apart. A port conflict now
counts as user-actionable only when the user pinned the port.

### Before

```mermaid
flowchart LR
  A["typed failure<br/>port, pull, timeout"] --> B["StackError<br/>message only"]
  B --> C["…StartError<br/>reason unknown"]
  C --> D["tag:ExperimentalStackStartError<br/>category unknown"]
```

### After

```mermaid
flowchart LR
  A["typed failure<br/>port, pull, timeout"] -->|failureKind| B["StackError<br/>kind + reason"]
  B --> C["…StartError<br/>reason stack"]
  C -->|StackError adapter| D["tag:ExperimentalStackStartError:port_conflict<br/>invalid_config"]
```

### Why

Every `@supabase/stack` failure crossed the owner RPC boundary as
message text. The CLI wrapped each one as `reason: "unknown"`, and none
of the `ExperimentalStack*Error` reasons set a fingerprint suffix. As a
result:

- the top new-stack start and destroy errors showed as `unknown`;
- `stack status` "no stack" and real flag errors shared one fingerprint;
- a raw `StackError` that escaped a command was reported as
`tag:unknown`, losing even its tag.

### What changed

- **`@supabase/stack` carries a failure kind.** `failureKind()` derives
a closed `StackFailureKind` from the typed cause chain. It is carried on
`StackError`, each failed composition outcome, the `POST /shutdown`
failure body and the owner readiness line.
- Failure sites that know the cause set the kind explicitly: port
claims, engine command failures, health and startup timeouts, process
exit and stop, artifact preparation, state, owner startup, connection
and exit, and lease conflicts.
- Docker stderr is classified only where the container error is built,
as with the existing retry classifiers.
- **The wire field is an open string.** An older client that decodes a
newer owner's error ignores kinds it doesn't know instead of rejecting
the response.
- **Port provenance.** `port-conflict` (user-actionable) is reserved for
a port requested by number, i.e. set in `config.toml` or a
`SUPABASE_*_PORT` override. The stack's own allocation reports
`port-allocation` (internal bug):
- auto-assigned ports, including a saved auto assignment that is now
taken;
  - native backend port collisions;
  - Docker publish refusals, since Docker chooses the host port.
- **A typed `StackError` adapter in the CLI.** It lives in
`error-actionability.ts` and checks, in order:
  1. the client `reason`;
  2. the `kind`;
  3. the first failed outcome's kind;
  4. otherwise `:unclassified`.
- **Per-reason fingerprints.** Every new-stack command error reason,
plus `FunctionsServeStackError`, has its own fingerprint suffix (for
example `:not_found`, `:flags`, `:confirmation`). A `stack` reason
classifies through its wrapped cause, so wrapped CLI errors such as
`DbSetupError` keep their own classification.
- **Stack-backed db and functions wrappers** keep the stack cause, so
the real failure shows through: `LocalDbRunningError`, `db reset`, `db
dump`, `db diff`, declarative sync, `test db` and `functions serve`.
- **Engine command failures** are classified as `runtime_crash` /
`engine_command` rather than `invalid_config`.
- **Unused internal CLI reasons are removed:** `registry`, `port`,
`artifact` and `impossible-state`.

### Reviewer notes

- **Dashboards:** fingerprint values change for these errors. A query
matching `tag:ExperimentalStackStartError` exactly needs a prefix match
now.
- **`functions serve` edge case:** on a stack with no API service it
still binds the CLI's default API port, so a conflict there reports as
user-actionable. That number also forms the served `SUPABASE_URL` before
the instance exists, so it is left as is.
- **Not covered here** (both pre-existing, for every command): parse
errors (an unknown flag or unexpected argument) and Ctrl+C send no
`cli_command_executed` event.

## Linked issue

None.

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

---------

Co-authored-by: Claude Opus 5.5 <noreply@anthropic.com>
This bumps analytics from v1.52.0-r0 to v1.53.0-r0.


https://github.com/supabase/slim-services/releases/tag/analytics-v1.53.0-r0

Planned after supabase/slim-services published v1.53.0-r0. This branch
is rewritten from develop whenever a newer relevant release arrives.

Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>
This bumps realtime from v2.143.0-r0 to v2.143.1-r0.


https://github.com/supabase/slim-services/releases/tag/realtime-v2.143.1-r0

Planned after supabase/slim-services published v2.143.1-r0. This branch
is rewritten from develop whenever a newer relevant release arrives.

Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>
This bumps realtime from v2.143.1-r0 to v2.143.2-r0.


https://github.com/supabase/slim-services/releases/tag/realtime-v2.143.2-r0

Planned after supabase/slim-services published v2.143.2-r0. This branch
is rewritten from develop whenever a newer relevant release arrives.

Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>
This bumps realtime from v2.143.2-r0 to v2.143.3-r0.


https://github.com/supabase/slim-services/releases/tag/realtime-v2.143.3-r0

Planned after supabase/slim-services published v2.143.3-r0. This branch
is rewritten from develop whenever a newer relevant release arrives.

Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>
Adds [jactionlint](https://github.com/jdx/jactionlint) as a core lint
for our GitHub Actions workflows and runs it as part of `check:all`.

- Replaces `.github/actionlint.yaml` with `.github/jactionlint.yaml` and
enables `require-commit-hash`, so actions, reusable workflows, and
`docker://` images must be pinned to a full SHA or digest.
- Pins `jactionlint` and `shellcheck` through mise. jactionlint only
checks `run:` scripts when shellcheck is on `PATH`, so pinning it keeps
local and CI results the same.
- Adds a root `lint:actions:check` script, registers it as an uncached
Turbo task, and includes it in `check:all`.

Fixes for existing findings:

- The `publish` jobs in `cli-go-pg-prove.yml` and
`cli-go-publish-migra.yml` now grant `packages: write` and `id-token:
write`. The reusable `cli-go-mirror-image.yml` workflow needs both, and
these callers only had the workflow-level `contents: read`.
- `$GITHUB_OUTPUT` redirects in workflow scripts are now quoted.

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

---------

Co-authored-by: Claude <noreply@anthropic.com>
Co-authored-by: Julien Goux <hi@jgoux.dev>
This bumps storage from v1.80.2-r0 to v1.81.0-r0.


https://github.com/supabase/slim-services/releases/tag/storage-v1.81.0-r0

Planned after supabase/slim-services published v1.81.0-r0. This branch
is rewritten from develop whenever a newer relevant release arrives.

Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>
…7068)

## TL;DR

stops a database helper from being left behind as a `Created` container
when readiness times out mid create

## whats introduced?

the helper is now created by name with `docker create --rm -i` and 
then attached with `docker start --attach --interactive`, so the name
exists before any readiness timeout and `rm -f` always finds it. `create
--rm -i` keeps the `AutoRemove` and `StdinOnce` of `run`, so a dead
owner still ends the helper...

the create is bounded to 30 seconds and its stderr stays in readiness
errors. a create the daemon finishes after that timeout is removed again
by name on owner shutdown, and an owner killed between `create` and
`start` leaves a helper the stack sweep on stop and destroy removes.

## ref:

- closes: #7063
- left/spotted in: #7014

---------

Co-authored-by: 7ttp <117663341+7ttp@users.noreply.github.com>
…7075)

## TL;DR

stops the local stack gateway from opening a new upstream connection for
every write.

## whats broken?

every `.rpc()`, `auth.admin.createUser`, delete or upload went upstream
on its own connection and left it in `TIME_WAIT`, so a busy test run
used up the macOS port range.

## now fixed by:

writes reuse the gateway's keep alive pool like reads do. a write is
still never resent.
Studio and its `/mcp` route keep a fresh connection per write, as before

chunked GET and DELETE bodies are forwarded as chunked, so they reach
the upstream and stay off the next request
PS: Auth's own Postgres churn is tracked in #6981

## ref:

- closes: #6987
- extends: #6925
Bumps `effect`, `@effect/platform-bun`, `@effect/platform-node`,
`@effect/platform-node-shared`, `@effect/sql-pg`, and `@effect/vitest`
from `4.0.0-rc.112` to the stable `4.0.2` release. `@effect/tsgo` is
unchanged.

The goal is zero change to CLI behaviour. Every edit is either required
by a removed or renamed API, or restores a behaviour whose upstream
default moved.

## Commit layout

The first three commits are the bump plus two scripted rewrites and can
be skipped by reviewers:

- `effect/unstable/*` import paths moved to `effect/*` (removed upstream
in rc.118,
[effect#8354](Effect-TS/effect#8354)).
- CLI and Config constructors renamed to PascalCase
([effect#7453](Effect-TS/effect#7453),
[effect#8121](Effect-TS/effect#8121)).

The remaining commits are hand migrations, one topic each.

## Hand migrations

- **node-postgres pool bridge** — `@effect/sql-pg` 4.0 is a native
client and dropped `PgClient.fromPool`
([effect#7426](Effect-TS/effect#7426)). The
remote database session keeps its own node-postgres pool for the zero
idle timeout, the per-connection role step-down hook, and raw `COPY`
connections, so `db-connection.pool-client.ts` is a small
`SqlClient.make` adapter over that pool with the same statement
execution, cancellation, and error classification the old bridge had.
- **Stack RPC strictness** — parse-option annotations no longer affect
decoding ([effect#8131](Effect-TS/effect#8131))
and the RPC transport passes no parse options, so the initialization
command and `runCommand` payload schemas now reject unknown keys through
a `Record` filter ahead of the struct decode, with the same "Expected no
excess property" wording. Encoding drops `undefined` entries first, so
optional fields passed as explicit `undefined` (for example
`pgProve.workingDir`) still cross the RPC JSON codec as they did with
the plain struct.
- **One statement per query** — the native `@effect/sql-pg` client sends
everything through the extended protocol, which rejects multi-command
strings. The realtime schema bootstrap runs as two statements, and the
generated `ALTER ROLE` / `ALTER DATABASE` batches come back from
Postgres as an array and run one at a time inside the same transaction.
- **Socket addresses, file sizes, encoding, sockets** — server addresses
are `NetAddress.SocketAddress` values, `File.seek` and `File.Info.size`
use `bigint` and `ByteSize`, `Encoding` moved to
`effect/encoding/Base64Url`, and the whole-stack WebSocket test helper
uses the reader and writer pair.
- **`Effect.partition`** returns `[passes, fails]`; the `stack destroy`
handler destructures in that order.
- **Management API contracts** — `packages/api` contracts are
regenerated; the 4.0.2 schema codegen emits code-point length checks and
Unicode-flagged patterns.
- **Config package** — `SchemaAST.Union.mode` moved under `options`,
`ToJsonSchemaOptions.additionalProperties` became `onExcessProperty`,
and regex patterns need the Unicode flag to be exported into JSON Schema
([effect#8482](Effect-TS/effect#8482)). Peer
dependency ranges are untouched and already satisfy 4.0.2.

## Preserved defaults

- The stack's `PgClient.layer` calls pin `idleTimeout: "10 seconds"`;
the default since 4.0.1 is 60 seconds
([effect#8679](Effect-TS/effect#8679)).
- The published JSON Schema files (`@supabase/config` `schema.json` and
`project-schema.json`, mirrored at `apps/docs/public/cli/*.schema.json`)
are byte-identical to the develop build. `toCliConfigJsonSchema` passes
`onExcessProperty: "error"` so structs keep `additionalProperties:
false` ([effect#8147](Effect-TS/effect#8147));
the shared document assembler leaves pattern-keyed records open, as the
generator has no per-schema setting for that; and bucket tables are
modelled so they render as the published object-or-array union.

## Behaviour changes reviewed and accepted

These upstream changes have no configuration knob. Each was checked
against the repo's call sites and judged not user-visible:

- Child-process `kill` and scoped release now wait for the process
group, bounded to one second without `forceKillAfter`
([effect#8018](Effect-TS/effect#8018)). The
stack host, bundled Postgres clients, and containers already set
`forceKillAfter`; other spawn sites can only see up to one extra second
of teardown when a descendant lingers.
- `Effect.cached` treats interruption as abandonment
([effect#8719](Effect-TS/effect#8719)). Every
cached effect in the repo is awaited by a single fiber or forked into an
owning scope, so the shared-interruption semantics do not apply.
- Empty bucket tables under `storage.analytics.buckets` and
`storage.vector.buckets` are modelled as an object-or-array union
instead of `Schema.Struct({})`. Runtime decoding now rejects a primitive
bucket value (`foo = "x"`), which the old schema accepted and ignored;
objects and arrays decode as before.
- HTTP client spans are named after the bare method (`GET` instead of
`http.client GET`), following the OpenTelemetry convention. Nothing in
the repo keys on the old name.
- Generated Management API string length checks count code points
instead of UTF-16 code units, which only differs for characters outside
the Basic Multilingual Plane.

## Patches

- Rebased: the `@effect/platform-node-shared` stdin EPIPE listener, now
against 4.0.2. 4.0.2 still removes the stdin sink's error listener
before the final `end()` flush, so a child that exits before reading its
input raises an uncaught EPIPE on Linux;
[effect#7712](Effect-TS/effect#7712) and
[effect#7714](Effect-TS/effect#7714) do not
cover that path.
- Rewritten: the `@effect/vitest` `runTest` patch. Upstream's finalizer
ordering fix
([effect#8154](Effect-TS/effect#8154)) covers
the abort hook, so the patch now only layers the two behaviours the
stack's `effect-timeout` tests assert on top of it: rejecting with the
pretty errors and reporting a finalizer failure after a timeout.

## Test-only changes

- Stack integration and CLI `db reset` e2e fixtures that seeded data
through `PgClient.layer` with semicolon-joined statements now issue one
statement per call; fixtures that go through `psql` are unchanged.
- The `db reset` e2e fixture reads `count(*)::int`, since the native
client decodes `int8` as `bigint`.

## Follow-ups

- Migrate the remote database session to the native `@effect/sql-pg`
client and delete the pool adapter. That changes result decoding (int8,
timestamps, bytea) across the SQL consumers and needs its own review.

---------

Co-authored-by: Claude Fable 5.1 <noreply@anthropic.com>
Co-authored-by: Julien Goux <hi@jgoux.dev>
## Summary

**TL;DR:** The experimental local stack can now run OrioleDB through
`db.orioledb_version`, on both the Docker and native runtimes. It uses
the new slim-services OrioleDB release line (`<upstream>-orioledb`). A
version without a published artifact fails closed, listing the supported
ones.

### Before

```mermaid
flowchart LR
  A["db.orioledb_version set"] --> B{"experimental stack?"}
  B -- yes --> C["error: unsupported by the experimental stack"]
  B -- no --> D["Compose: docker.io supabase/postgres:&lt;v&gt;-orioledb"]
```

### After

```mermaid
flowchart LR
  A["db.orioledb_version set"] --> B{"OrioleDB pin in catalog?"}
  B -- no --> C["fail closed: lists published versions"]
  B -- yes --> D["stack: slim &lt;v&gt;-orioledb-rN<br/>docker or native"]
  D --> E["db diff / declarative shadow<br/>use the same pin"]
  D --> F["data reuse only within<br/>the OrioleDB line"]
  G["slim-services publishes<br/>&lt;v&gt;-orioledb-r0"] --> H["catalog sync opens<br/>add postgres PR"]
  H --> B
```

### Why

OrioleDB is leaving experimental. The new stack rejected
`db.orioledb_version` with `db.orioledb_version is unsupported by the
experimental stack`. supabase/slim-services#315 now builds and publishes
OrioleDB as its own Postgres release line, next to stock 15 and 17, so
the stack can pin it like any other artifact.

### What changed

- **Catalog sync.** `-orioledb` releases form their own catalog line
(`17-orioledb`).
  - The first publish opens an `add` PR.
  - Later releases upgrade or hotfix that line on their own.
  - An OrioleDB release never touches the stock 17 pin, and the reverse.
  - Legacy tags without `-rN` are ignored.
- **One version resolver.** `db.orioledb_version` (and
`SUPABASE_DB_ORIOLEDB_VERSION`) resolves to `<v>-orioledb` through one
shared resolver. `stack start`, the `db diff` shadow and its cache key,
and the versions output all use it.
  - The setting requires `db.major_version = 17`.
  - An unpinned version fails with the list of published versions.
  - `postgresVersion("17")` still resolves to stock.
- **Data safety.** The ready-marker, `PG_VERSION` and snapshot checks
compare the engine line, not only the major. Stock and OrioleDB data,
snapshots and shadow caches never mix.
- Unmarked data, including data left behind by an interrupted first
start, is refused for an OrioleDB request.
  - The error suggests `supabase stack destroy`.
- Switching `orioledb_version` on a saved stack requires `stack
destroy`, because the stack keeps its database version.
- **`test db`.** Maps OrioleDB to its major for pg_prove.
- **Declarative shadow.** No CLI-side handling: pg-delta's Supabase
profile treats `orioledb` as a platform extension
([supabase/pg-toolbelt#513](supabase/pg-toolbelt#513)),
so declarative export never emits it and the diff never creates or drops
it. Shipped in pg-delta `1.0.0-alpha.58`, which this PR pins.
- **Compose.** With `SUPABASE_USE_SLIM_IMAGES`, Compose maps
`supabase/postgres:<v>-orioledb` to the pinned slim OrioleDB image.
Unpinned versions stay on docker.io.
- **Docs.** `stack-commands.md`, `SIDE_EFFECTS.md`,
`packages/stack/ARCHITECTURE.md` and ADR 0026.

It also pins the first published OrioleDB release,
`17.11.0.002-orioledb-r0`, added with the catalog sync's `--release`
mode. Later OrioleDB releases arrive through the existing
`slim-release-published` sync.

## Linked issue

Part of CLI-2387. Depends on supabase/slim-services#315.

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

---------

Co-authored-by: Claude Opus 5.5 <noreply@anthropic.com>
@supabase-cli-releaser
supabase-cli-releaser Bot requested review from a team and supabase-oss as code owners October 9, 2026 18:41
@supabase-cli-releaser supabase-cli-releaser Bot added the do not merge Approve to apply; do not merge. label Oct 9, 2026
@supabase-cli-releaser

Copy link
Copy Markdown
Contributor Author

Resolution for 5f82350

Claude (claude-opus-5-5) merged into sync/develop-into-next. Workflow run

develop (f825003)

I resolved all 8 files in group 1. next deletes the Go CLI, and develop's edits to the three Go-only files (two workflows and the Go Dockerfile) are covered elsewhere or no longer matter, so those files are deleted. In the remaining files, develop's content is ported onto next's Go-free wording. Nothing has been run, so CI is the first check. No earlier sync settled any of these files, so I followed no precedent. I resolved all eight files in group 2 and removed every conflict marker. No checks have been run, since I can't run commands here; CI will run them on the PR.

  • Most conflicts were the same pattern. next renamed tests and messages to drop Go wording and made pg-delta on by default. develop moved code to Effect 4.0.2 and the Effect lint style (scoped temp dirs, withEnv config providers, Cause.pretty, Effect.callback). I kept develop's new structure and applied next's names, messages and pg-delta default on top.
  • One field stays removed. next deleted envLookup from the config reader's result, while develop had only narrowed its type. I couldn't search the codebase from this session, so I haven't confirmed that no develop-side code still reads that field. If any does, the type-check will flag it.
  • Two files are deleted. next removed the supabase-go proxy layer and its test; develop only changed import paths in them.

No earlier sync PR covered these files, so none of the resolutions cites a precedent. I resolved all eight files in group 3. I couldn't run any checks, so CI has to confirm the result type-checks. The main change from develop is the effect 4.0.2 upgrade: imports move from effect/unstable/cli to effect/cli, and constructors are renamed from Flag.string/Argument.string to Flag.String/Argument.String. I applied that onto next's version of each file. next deleted the four db branch leaf command files and develop only changed their imports, so they are deleted. No earlier sync pull request covered these files. I resolved all 8 files in group 4. All conflict markers are gone, and nothing was run because I can't execute commands here; CI will check the result. Every resolution keeps next's breaking changes and adds develop's Effect 4.0.2 upgrade or its OrioleDB slim-image doc wording. No recorded precedent applied: the only earlier sync, #7059, was closed without landing. I resolved all 8 files in group 5. One needs a maintainer's call: next and develop each added a different ADR as 0030, and both entries are now in the ADR index under that number. No earlier sync settled any of these files; the only past sync (#7059) was closed without landing. I couldn't run any checks, so type-checking and tests are left to CI. In most files the merge combines develop's Effect 4.0.2 API renames (effect/cli imports, Flag.Literals, Flag.String, Flag.Int) with next's removal of Go wording. I resolved the conflict in mise.toml. The Go and golangci-lint entries stay removed, as next intended when it dropped the supabase-go binary. The jactionlint and shellcheck entries from develop are kept because the workflow lint checks need them.

Needs a decision

  1. next added ADR 0030 'Go CLI Removal' and develop added ADR 0030 'Hotfix Releases'. Which one keeps 0030? (docs/adr/README.md)
    • Chosen: Kept both index entries at 0030 so neither ADR is lost. One still has to be renumbered: probably next's Go CLI Removal ADR moves to 0031, since develop's ADR has already shipped. That means renaming its file and updating references to it.
    • Alternative: Renumber develop's Hotfix Releases ADR to 0031 instead. That breaks links that already point to it on develop.
  2. This workflow file conflicted and runs with repository secrets. Is the resolution right? (.github/workflows/cli-go-api-sync.yml)
    • Chosen: The resolution on this branch.
    • Alternative: Resolve it by hand on the sync branch.
  3. This workflow file conflicted and runs with repository secrets. Is the resolution right? (.github/workflows/cli-go-mirror.yml)
    • Chosen: The resolution on this branch.
    • Alternative: Resolve it by hand on the sync branch.

Resolved files

  • .github/workflows/cli-go-api-sync.yml: Deleted, as next removed the Go CLI and its workflows. develop only quoted $GITHUB_OUTPUT for the new jactionlint check, which doesn't apply to a removed workflow. Flagged for review because it is under .github/.
  • .github/workflows/cli-go-mirror.yml: Deleted, as next removed the Go CLI and its workflows. develop only quoted $GITHUB_OUTPUT for the new jactionlint check, which doesn't apply to a removed workflow. Flagged for review because it is under .github/.
  • CONTRIBUTING.md: Kept next's removal of the Go and golangci-lint tool entries and the Go version files. Added develop's jactionlint and shellcheck rows to the tool table, plus its note that pnpm check:all needs shellcheck on PATH.
  • apps/cli-go/pkg/config/templates/Dockerfile: Deleted along with the rest of the Go tree. develop's realtime v2.143.3, storage v1.81.0 and logflare 1.53.0 bumps are already in next's generated apps/cli/src/shared/services/Dockerfile.
  • apps/cli/docs/release-process.md: In See Also, kept develop's new link to ADR 0030 (hotfix releases) and next's single-binary description of binary-distribution.md. develop's hotfix, rollback and sync text merged without conflict.
  • apps/cli/src/cli/complete.ts: In the comment above the duration-flag set, combined next's Go-free wording (isValidDuration) with develop's Effect 4.0.2 name Flag.String. The rest of the Effect upgrade (imports, Int/Finite tags) merged cleanly.
  • apps/cli/src/command-internal/db-config.integration.test.ts: Used develop's Effect rewrite of the linked-config-ordering test (scoped temp dir via FileSystem, Cause.pretty, BunServices) under next's title without the Go ParseDatabaseConfig reference.
  • apps/cli/src/command-internal/db-config.parse.unit.test.ts: Took develop's full Effect rewrite (layered it.effect tests, withConfigEnv, scoped temp files instead of process.env and node:fs). Then applied each of next's renames that drop pgconn and Go references from test and describe titles.
  • apps/cli/src/command-internal/db-config.toml-read.ts: Kept next's removal of the envLookup field from the config reader's result. develop's other changes merged without conflict and are kept: the shell-env lookup that goes through Effect's config service, the list of SUPABASE_* override variable names, and failing with the error directly.
  • apps/cli/src/command-internal/db-config.toml-read.unit.test.ts: Kept develop's Effect-based setup (scoped temp dirs, withEnv providers, Cause.pretty) with next's test names and its new 'expected a string, got …' error text. The pg-delta tests follow next's on-by-default behaviour: the remote-block test now sets the env override to "false", and the absolute-path test still checks that pg-delta is enabled.
  • apps/cli/src/command-internal/db-connection.sql-pg.integration.test.ts: Used next's test name for the auth-failure rendering test, with develop's direct yield* fakePostgresServer(...) instead of the Effect.promise wrapper.
  • apps/cli/src/command-internal/db-connection.sql-pg.unit.test.ts: Rewrote the failing step-down test as develop's it.effect/Effect.callback version and dropped the Go-parity suffix from its name, as next did.
  • apps/cli/src/command-internal/db-image.unit.test.ts: Used develop's scoped withTemp effect with next's test name, which drops the Go reference.
  • apps/cli/src/command-internal/global-flags.ts: Kept next's hidden 'Removed' --create-ticket flag (description and comment) and switched it to develop's Effect 4.0.2 GlobalFlag.Setting / Flag.Boolean constructors.
  • apps/cli/src/command-internal/string-slice-flag.ts: Kept next's flagLabel rename and the wording without Go references, and switched the flag to develop's Flag.String constructor.
  • apps/cli/src/commands/db/branch/branch.command.ts: Kept next's removed-command placeholders for db branch, which are defined inline. They now import from effect/cli and use Argument.String, matching the effect upgrade. The imports of the deleted leaf files are dropped.
  • apps/cli/src/commands/db/branch/create/create.command.ts: Deleted, as on next. develop only updated its imports, and the replacement placeholder now lives in branch.command.ts.
  • apps/cli/src/commands/db/branch/delete/delete.command.ts: Deleted, as on next. develop only updated its imports, and the replacement placeholder now lives in branch.command.ts.
  • apps/cli/src/commands/db/branch/list/list.command.ts: Deleted, as on next. develop only updated its imports, and the replacement placeholder now lives in branch.command.ts.
  • apps/cli/src/commands/db/branch/switch/switch.command.ts: Deleted, as on next. develop only updated its imports, and the replacement placeholder now lives in branch.command.ts.
  • apps/cli/src/commands/db/diff/diff.command.ts: Kept next's engine-flag comment and its hidden --use-pg-schema flag that reports the removal, and switched both flags to develop's Flag.Boolean constructor.
  • apps/cli/src/commands/db/dump/SIDE_EFFECTS.md: Kept next's environment-variable table, which drops the DB_PASSWORD viper key. Added develop's OrioleDB wording ("OrioleDB tags the catalog does not pin") and realigned the table columns.
  • apps/cli/src/commands/db/pull/SIDE_EFFECTS.md: Kept develop's wider env-var table, including its new OrioleDB wording ("OrioleDB tags the catalog does not pin"). Dropped the SUPABASE_EXPERIMENTAL_PG_DELTA row because next no longer reads that variable.
  • apps/cli/src/commands/db/remote/changes/changes.command.ts: Kept next's stub that tells users the command was removed, with its runtime and telemetry imports. Switched the CLI import to develop's effect/cli path and dropped the unused handler and type imports.
  • apps/cli/src/commands/db/test/SIDE_EFFECTS.md: Took next's rewritten Notes. They no longer mention Flag.boolean, so develop's rename to Flag.Boolean has nothing left to update.
  • apps/cli/src/commands/functions/download/download.command.ts: Kept next's --legacy-bundle flag, which is optional and now only produces a removal error, along with its Effect/Layer/Option imports. Used develop's effect/cli import paths and its Flag.Boolean constructor.
  • apps/cli/src/commands/gen/keys/keys.command.ts: Kept next's stub that tells users the command was removed, with its imports. Switched the CLI import to effect/cli and dropped the unused handler and type imports.
  • apps/cli/src/commands/gen/types/types.command.ts: Kept next's updated comment ("the handler prints the deprecation line") and used develop's Flag.Boolean constructor for --postgrest-v9-compat.
  • apps/cli/src/commands/gen/types/types.handler.ts: Kept next's local loadCliConfig import from command-internal/cli-config-load.ts and used develop's effect/process import path. develop's change to the connection-string parser in the preview-branch pooler fallback had already merged cleanly.
  • apps/cli/src/commands/start/SIDE_EFFECTS.md: Took develop's env-var table with the new OrioleDB slim-image wording. Re-applied next's change of the SUPABASE_* row text to "Generic env override", which removes the Viper wording.
  • apps/cli/src/commands/storage/cp/cp.command.ts: Kept next's comment without the pflag/Go wording and applied develop's rename of Flag.integer to Flag.Int.
  • apps/cli/src/shared/cli/run.unit.test.ts: Kept next's Data/Runtime imports, which its custom-exit-code test error needs, and switched to develop's effect/cli import path.
  • apps/cli/src/shared/init/project-init.templates.unit.test.ts: Kept develop's change that reads the OrioleDB version from the rendered template instead of a hard-coded value, plus its new pinned-version test. Kept next's renamed helpers and its comments without Go wording.
  • apps/cli/src/shared/telemetry/error-actionability.ts: Merged the error-fingerprint lists alphabetically: develop's release_mismatch (from the stack-failure classification) next to next's removed_command and removed_flag. Both sides' other changes merged without conflict.
  • apps/cli/src/telemetry/command-telemetry.unit.test.ts: Used develop's Flag.Literals API with next's test names (no 'Go parity' wording) and its single-line test layout.
  • docs/adr/README.md: Kept both new ADR index entries: next's 'Go CLI Removal' and develop's 'Hotfix Releases'. Both currently use number 0030.
  • knip.jsonc: Dropped go from ignoreBinaries, since next removed the Go toolchain, and kept develop's new jactionlint entry.
  • mise.lock: Removed the go and golangci-lint lock entries as next did, and kept develop's new jactionlint and shellcheck entries.
  • mise.toml: Kept next's removal of the go and golangci-lint tool pins. Kept the [tools] table with only the jactionlint and shellcheck pins that develop added for GitHub Actions workflow linting.
  • .github/workflows/cli-go-api-sync.yml: deleted
  • .github/workflows/cli-go-mirror.yml: deleted
  • apps/cli-go/pkg/config/templates/Dockerfile: deleted
  • apps/cli/src/command-internal/go-proxy.layer.ts: deleted
  • apps/cli/src/command-internal/go-proxy.layer.unit.test.ts: deleted
  • apps/cli/src/commands/db/branch/create/create.command.ts: deleted
  • apps/cli/src/commands/db/branch/delete/delete.command.ts: deleted
  • apps/cli/src/commands/db/branch/list/list.command.ts: deleted
  • apps/cli/src/commands/db/branch/switch/switch.command.ts: deleted

Format and type check

Passed after these changes to the merged tree:

  • apps/cli/src/commands/functions/download/download.removed-flag.integration.test.ts: Changed the CliOutput/Command import from 'effect/unstable/cli' to 'effect/cli'.
  • apps/cli/src/commands/services/services.integration.test.ts: Renamed the setup option goOutput to outputFlag in the OrioleDB test.

@supabase/cli: 3 choices need a decision. Approve to keep them. To reverse one, push the change to sync/develop-into-next and reply here with the decision; later syncs follow it.

@avallete

avallete commented Oct 9, 2026

Copy link
Copy Markdown
Member

/ai-review

@github-actions github-actions Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

🤖 AI Review

Confirmed all five findings from both independent reviews: two major runtime bugs, two minor concerns, and one nit. No duplicates were found. Verification used code inspection and a static scanner check; missing dependencies and blocked local sockets prevented full runtime testing.

Findings

Severity Location Category Sources Claim
🟠 MAJOR apps/cli/src/command-internal/db-connection.pool-client.ts:205 cancellation codex SQL cancellation queues behind the statement it must cancel because it acquires a connection from the same saturated pool. After cancellation times out, the active client is released without discarding it, allowing the interrupted statement to continue.
🟠 MAJOR packages/stack/src/HttpProxy.ts:372 resource-lifecycle codex An early upstream response can leave its incomplete HTTP request open after the downstream response completes, retaining an occupied upstream connection.
🟡 MINOR apps/cli/src/command-internal/db-target-flags.unit.test.ts:200 test-coverage codex Both flag-completeness tests pass vacuously because their scanner recognizes lowercase constructors while command declarations now use capitalized constructors.
🟡 MINOR docs/adr/README.md:74 documentation claude Two different ADRs share number 0030, making references by ADR number ambiguous.
⚪ NIT apps/cli/src/command-internal/db-config.toml-read.ts:1062 dead-code claude The removed SUPABASE_EXPERIMENTAL_PG_DELTA toggle remains in ENV_OVERRIDE_NAMES despite no longer controlling any configuration setting.

Stats

Claude findings: 2 · Codex findings: 3 · Confirmed: 5 · Refuted: 0 · Uncertain: 0


Models: claude-opus-5-5 + gpt-6.1-sol · Trigger: manual · Workflow run

This review runs once per PR. A maintainer can request another with a /ai-review comment.

Comment on lines +205 to +208
pool.query(`SELECT pg_cancel_backend(${processId})`, () => {
resume(Effect.void);
});
}).pipe(Effect.interruptible, Effect.timeoutOption(5000), Effect.asVoid)

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

🟠 MAJOR · cancellation · source: codex

SQL cancellation queues behind the statement it must cancel because it acquires a connection from the same saturated pool. After cancellation times out, the active client is released without discarding it, allowing the interrupted statement to continue.

Evidence: db-connection.pool-client.ts:205-208 submits pg_cancel_backend through pool.query with a five-second Effect timeout and no queue-removal cleanup. Lines 65-66 release the client normally, and line 110 waits for cancellation before releasing it. db-connection.sql-pg.layer.ts:547 configures max: 1, and line 872 passes that pool to makePoolSqlClient.

Suggested fix: Use a separate cancellation connection or PostgreSQL CancelRequest transport. Discard the active client when cancellation cannot be confirmed, and ensure timed-out cancellation requests cannot remain queued.

Comment on lines +372 to +379
const onUpstreamEnd = () => {
if (outgoing !== undefined) request.unpipe(outgoing);
if (request.readableEnded) endResponse();
else {
request.once("end", endResponse);
Deferred.doneUnsafe(draining, Effect.void);
request.resume();
}

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

🟠 MAJOR · resource-lifecycle · source: codex

An early upstream response can leave its incomplete HTTP request open after the downstream response completes, retaining an occupied upstream connection.

Evidence: HttpProxy.ts:373 unpipes the upstream request, while lines 376-378 drain subsequent client bytes without forwarding them. Normal response completion calls finish at line 366; its cleanup at lines 342-354 neither ends nor destroys outgoing. Destruction occurs on abandonment or interruption at lines 358-362 and 429-433.

Suggested fix: Destroy the incomplete upstream request after its response finishes while preserving the valid downstream response. Extend early-rejection tests to assert upstream connection cleanup.

Comment on lines +200 to 203
function extractDeclaredFlags(filePath: string, source: string): Array<DeclaredFlag> {
const callRegex = /Flag\.(string|integer|choice|choiceWithValue|float|boolean)\(/g;
const calls = Array.from(source.matchAll(callRegex), (match) => ({
index: match.index,

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

🟡 MINOR · test-coverage · source: codex

Both flag-completeness tests pass vacuously because their scanner recognizes lowercase constructors while command declarations now use capitalized constructors.

Evidence: db-target-flags.unit.test.ts:183 retains lowercase VALUE_FLAG_KINDS, and line 201 matches lowercase Flag constructors. Lines 240-247 and 262-271 only assert empty missing lists. dump.command.ts:63 uses Flag.String("file"). A static scan across 185 included command files found zero matches for the existing scanner.

Suggested fix: Prefer parser-level coverage of value-consuming flags. If retaining the scanner, update constructor names and kinds, and assert that declarations were actually extracted.

Comment thread docs/adr/README.md
Comment on lines 74 to +75
| 0030 | [Go CLI Removal](0030-go-cli-removal.md) | accepted |
| 0030 | [Hotfix Releases](0030-hotfix-releases.md) | accepted |

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

🟡 MINOR · documentation · source: claude

Two different ADRs share number 0030, making references by ADR number ambiguous.

Evidence: docs/adr/README.md:74-75 lists both Go CLI Removal and Hotfix Releases as 0030. Both files exist and their headings use 0030. ADR 0016:3 references the Go removal decision, while apps/cli/docs/release-process.md:293,568,576 labels the hotfix decision ADR 0030.

Suggested fix: Renumber the Go CLI Removal ADR to 0031 and update its filename, heading, index entry, supersession link, and remaining references.

"SUPABASE_DB_MIGRATIONS_SCHEMA_PATHS",
"SUPABASE_API_AUTO_EXPOSE_NEW_TABLES",
"SUPABASE_API_SCHEMAS",
"SUPABASE_EXPERIMENTAL_PG_DELTA",

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

⚪ NIT · dead-code · source: claude

The removed SUPABASE_EXPERIMENTAL_PG_DELTA toggle remains in ENV_OVERRIDE_NAMES despite no longer controlling any configuration setting.

Evidence: db-config.toml-read.ts:1062 retains the name. Lines 1132-1145 resolve and scan all registered override values, but pg-delta configuration at lines 1402-1433 uses SUPABASE_EXPERIMENTAL_PGDELTA_ENABLED instead. diff-engine.ts:12-16 computes activation solely from configEnabled and usePgDeltaFlag.

Suggested fix: Remove SUPABASE_EXPERIMENTAL_PG_DELTA from ENV_OVERRIDE_NAMES.

@avallete avallete closed this Oct 12, 2026
@avallete

Copy link
Copy Markdown
Member

Superseded by a fresh sync from the reworked workflow (#7083)

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.

4 participants