Skip to content

feat(stack): run the complete native service graph - #6385

Closed
jgoux wants to merge 36 commits into
developfrom
juliengoux/cli-2141-stack-run-the-remaining-native-service-graph-from-slim
Closed

feat(stack): run the complete native service graph#6385
jgoux wants to merge 36 commits into
developfrom
juliengoux/cli-2141-stack-run-the-remaining-native-service-graph-from-slim

Conversation

@jgoux

@jgoux jgoux commented Aug 28, 2026

Copy link
Copy Markdown
Contributor

Summary

Extends the strict native stack runtime from the Postgres/Auth/PostgREST core to the complete service graph using the frozen slim-services releases.

Adds native launch, configuration, lifecycle, and private companion ownership for Edge Runtime, Realtime, Storage/imgproxy, PgMeta/Studio, Analytics/Vector, Pooler, and Mailpit. Native logs remain supervisor-owned and isolated per stack, while the public package surface preserves eager, lazy, and explicit preparation closure semantics.

The representative consumer journey covers the public service graph and exact resource ownership. This change does not add per-service Docker fallback or absorb unrelated proxy hardening.

@jgoux
jgoux requested a review from a team as a code owner August 28, 2026 18:01
Comment thread packages/stack/src/services/imgproxy.ts

@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: d1515d4700

ℹ️ About Codex in GitHub

Your team has set up Codex to 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 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

Comment thread packages/stack/src/StackBuilder.ts
Comment thread packages/stack/src/ServiceCatalog.ts Outdated
Comment thread packages/stack/src/services/analytics.ts Outdated
@chatgpt-codex-connector

chatgpt-codex-connector Bot commented Aug 29, 2026

Copy link
Copy Markdown

Codex Review Summary

This comment shows the latest Codex review activity on this pull request.

Review Status Commit Review trigger
📝 Code Review Completed 2026-08-31T22:08:21.432566Z dfe88c3 New commits
ℹ️ About Codex in GitHub

Your team has set up Codex to 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" or "@codex security review".

Codex reacts with 👀 while any review is running, comments if it has suggestions, and reacts with 👍 once all reviews finish with no findings.

Comment thread packages/stack/src/services/pooler.ts
Comment thread packages/stack/src/ServiceCatalog.ts

@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: c912c31e38

ℹ️ About Codex in GitHub

Your team has set up Codex to 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 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

Comment thread packages/stack/src/ServiceCatalog.ts Outdated
Comment thread packages/stack/src/versions.ts
Comment thread packages/stack/src/services/imgproxy.ts
Comment thread packages/stack/src/services/realtime.ts Outdated
Comment thread packages/stack/vitest.config.ts Outdated
Comment thread packages/stack/src/services/analytics.ts
Comment thread packages/stack/src/services/realtime.ts Outdated

@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: 3a0834d944

ℹ️ About Codex in GitHub

Your team has set up Codex to 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 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

Comment thread packages/stack/src/PortCatalog.ts
Comment thread packages/stack/src/managed/document.ts
Comment thread packages/stack/src/services/edge-runtime.ts Outdated

@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: 5fe089ab55

ℹ️ About Codex in GitHub

Your team has set up Codex to 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 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

Comment thread packages/stack/src/services/storage.ts
Comment thread apps/cli/src/next/commands/services/services.handler.ts
Comment thread apps/cli/src/next/commands/link/link.handler.ts
@jgoux

jgoux commented Aug 29, 2026

Copy link
Copy Markdown
Contributor Author

Automated review convergence checkpoint after three batched fix rounds:

  • Fixed the in-scope, reproduced findings through 69acdd0, including runtime-specific version planning, normal integration parallelism, Analytics loopback binding, and the CliConfig Pooler-port projection.
  • Deferred direct-listener/proxy confinement that the frozen runtimes cannot currently express (Pooler and Realtime), plus coordinated imgproxy hardening, to CLI-2227. Edge Runtime loopback binding belongs with that same direct-listener audit rather than another isolated patch.
  • Reproduced the Storage cleanup concern: the child supervisor currently runs configured cleanup actions on requested shutdown as well as owner loss, so auto-managed Storage data can be removed on restart. This is a valid lifecycle question and may be a merge blocker; it needs a human scope decision rather than a fourth automated patch round.
  • Fresh-stack stack services runtime selection and partial linked-version fallback are CLI-consumer semantics outside the authoritative CLI-2141 public @supabase/stack scope. They arose in code expanded during the previous review round and are deferred for separate CLI follow-up.
  • Rejected migration support for the unreleased managed db.pooler.port key per the explicit no-backward-compatibility direction.

The automated loop is now capped per AGENTS.md because new findings are primarily in code introduced by prior bot-driven rounds. Please provide human review, especially on whether Storage restart persistence should be folded into CLI-2141 before merge or tracked separately.

Comment thread packages/stack/src/services/pgmeta.ts Outdated
Comment thread packages/stack/src/services/pooler.ts

@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: 69acdd0e84

ℹ️ About Codex in GitHub

Your team has set up Codex to 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 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

Comment thread packages/stack/src/services/pooler.ts
Comment thread packages/stack/src/services/realtime.ts
@jgoux jgoux self-assigned this Aug 31, 2026

@avallete avallete left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

Review

Cross-reviewed the stacked diff (ccbf5c5...69acdd0) only: Cursor + Claude Fable + Codex. Graph wiring, companions, journals, version planning, and eager/lazy/explicit prepare closures look coherent. Remaining problems sit at the host-native seam this PR introduced.

Changes requested — three small, diff-local fixes. Storage wipe is a follow-up, not a hold.

Ask before merge

  1. Native Analytics / BEAM cookiesanalytics.ts still uses RELEASE_COOKIE: "cookie" on the host EPMD. Thread a random per-stack cookie to Analytics/Realtime/Pooler and bind epmd/dist to loopback. See inline.
  2. Native PgMeta bind — set PG_META_HOST=127.0.0.1. It is the only native HTTP service left on 0.0.0.0. See inline.
  3. Realtime Host probe on Node — native health check sets Host: <tenantId> via fetch. Please confirm Node does not strip it; Bun e2e would miss that. See inline.

Parked (do not hold CLI-2141)

  • Storage/Mailpit orphanCleanup on requested stop/restart is real (supervisor-runtime.ts runs cleanup on ShutdownRequested). CLI managed start always passes a persisted stackRoot, so supabase start/stop/restart does not wipe uploads. The wart is programmatic createStack() temp roots and mid-session restartService("storage") there — same parent contract already on Postgres. Fix in process-compose: RemovePath only on owner loss.
  • imgproxy IMGPROXY_LOCAL_FILESYSTEM_ROOT: "/" stays with CLI-2227; native blast radius is wider than Docker.
  • start --mode restamping the previous mode's versions is a next/ consumer follow-up, not the stack graph.
  • Realtime ERL_CRASH_DUMP at cwd, missing runtime.env footprint profile, and the NativeLogWriter NUL sentinel leaking through LogBuffer are real ownership/DX misses. Follow-up.

Cleanup

No review/tool attributions. Leftovers worth trimming if you are already in the files:

  • Pooler native env asserted twice (services.unit.test.ts and pooler.unit.test.ts).
  • orphanCleanup copied in storage.ts / mailpit.ts.
  • Dead aliases after applyNativeDefaults removal (supervisor.ts runtimeConfigInput, SupervisorUpgradeRestart.ts effectiveConfigInput).
  • startNativeLogWriter exported from effect.ts with only LocalStack as a consumer.
  • e2e bindAndClose after dispose is released-port reuse; the PID check is enough.

Cross-review logs: Claude Fable + Codex on the stacked head. Nothing else posted besides this review.

Comment thread packages/stack/src/services/analytics.ts Outdated
Comment thread packages/stack/src/services/pgmeta.ts
Comment thread packages/stack/src/services/realtime.ts
Base automatically changed from juliengoux/cli-2121-stack-qualify-the-native-postgres-auth-and-postgrest-core to develop August 31, 2026 09:51
@jgoux
jgoux force-pushed the juliengoux/cli-2141-stack-run-the-remaining-native-service-graph-from-slim branch from 69acdd0 to 246d59d Compare August 31, 2026 20:25
@jgoux
jgoux requested a review from avallete August 31, 2026 20:29
@github-actions

github-actions Bot commented Aug 31, 2026

Copy link
Copy Markdown
Contributor

Supabase CLI preview

npx --yes https://pkg.pr.new/supabase/cli/supabase@0c269ae78d5974606085f1ec7540a86fe331af35

Preview package for commit 0c269ae.

Comment thread packages/stack/src/services/edge-runtime.ts
Comment thread packages/stack/src/services/realtime.ts Outdated

@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: 246d59d7bf

ℹ️ About Codex in GitHub

Your team has set up Codex to 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 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

Comment thread packages/stack/src/services/imgproxy.ts
Comment thread packages/stack/src/ApiProxy.ts Outdated
Comment thread packages/process-compose/src/LogBuffer.ts

@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: 9f3f0fbf21

ℹ️ About Codex in GitHub

Your team has set up Codex to 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 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

Comment thread packages/stack/src/PortCatalog.ts Outdated
Comment thread packages/stack/src/ApiProxy.ts

@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

Effect.andThen(Effect.sleep("25 millis")),

P2 Badge Wait for the 503 response to finish before disposing

When lazy service activation fails on a slow or loaded host, this fixed 25 ms delay can expire before the handler's 503 response has flushed, after which disposing the managed runtime closes the proxy and the client observes a reset or truncated response instead of Service unavailable. Coordinate teardown with completion of the active request/response rather than using a timing assumption.

AGENTS.md reference: AGENTS.md:L320-L322

ℹ️ About Codex in GitHub

Your team has set up Codex to 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 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

@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: dfe88c32f0

ℹ️ About Codex in GitHub

Your team has set up Codex to 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 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

Comment thread packages/stack/src/services/mailpit.ts

const realtimeEnv = (opts: RealtimeEnvOptions): Record<string, string> => {
return {
PORT: String(opts.port),

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

🟡 Severity: MEDIUM

Native Realtime is now launched directly on the host, but its environment sets only PORT and no HTTP bind address. The Phoenix listener therefore uses its all-interface default; a network client can bypass the API proxy and reach Realtime directly, avoiding proxy-side key translation and exposing its HTTP/WebSocket surface.
Helpful? Add 👍 / 👎

💡 Fix Suggestion

Suggestion: Add PHX_HTTP_IP: "127.0.0.1" to the realtimeNativeEnv function alongside the existing loopback settings (GEN_RPC_SOCKET_IP). This follows the same pattern used by the Analytics service (PHX_HTTP_IP in analytics.ts) to restrict the Phoenix HTTP/WebSocket listener to the loopback interface only, preventing external clients from bypassing the API proxy and reaching Realtime directly. The change should be placed in realtimeNativeEnv (around line 86) rather than realtimeEnv, so Docker deployments (which legitimately bind to all interfaces within their network namespace) are not affected:

const realtimeNativeEnv = (
  opts: Omit<RealtimeEnvOptions, "native">,
  genRpcPort: number,
): Record<string, string> => ({
  ...realtimeEnv({ ...opts, native: true }),
  // The local stack has one Realtime node. Keep each helper's gen_rpc listener
  // on loopback and give it a distinct port during sequential startup.
  PHX_HTTP_IP: "127.0.0.1",
  GEN_RPC_SOCKET_IP: "127.0.0.1",
  GEN_RPC_TCP_SERVER_PORT: String(genRpcPort),
  GEN_RPC_TCP_CLIENT_PORT: String(genRpcPort),
});

paths.configPath,
nativeVectorConfig(opts),
"Failed to write the native Vector configuration",
{ flag: "w", mode: 0o600 },

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Severity: LOW

The generated native Vector YAML embeds analyticsApiKey in plaintext. Passing mode: 0o600 to writeFileString with flag: "w" only controls creation; an existing permissive vector.yaml keeps its mode, so a shared or caller-supplied runtime root can expose the Analytics credential to other local users.
Helpful? Add 👍 / 👎

💡 Fix Suggestion

Suggestion: The mode: 0o600 option passed to writeFileString (via writeNativeFile) only sets the file permissions when the file is newly created; if vector.yaml already exists on disk, flag: "w" truncates and overwrites the content but leaves the pre-existing file mode intact, potentially exposing the analyticsApiKey to other local users.

The recommended fix is to explicitly chmod the file after writing it, so permissions are always enforced regardless of the file's prior existence. In packages/stack/src/native-filesystem.ts, update writeNativeFile to call fs.chmod after fs.writeFileString when a mode is specified:

export const writeNativeFile = (
  path: string,
  content: string,
  detail: string,
  options?: WriteFileOptions,
): Effect.Effect<void, StackBuildError, FileSystem.FileSystem> =>
  Effect.gen(function* () {
    const fs = yield* FileSystem.FileSystem;
    yield* fs
      .writeFileString(path, content, options)
      .pipe(Effect.mapError((cause) => new StackBuildError({ detail, cause })));
    if (options?.mode !== undefined) {
      yield* fs
        .chmod(path, options.mode)
        .pipe(Effect.mapError((cause) => new StackBuildError({ detail, cause })));
    }
  });

Alternatively, inside prepareVectorConfig in vector.ts, add an explicit chmod call immediately after the writeNativeFile yield at line 162 using the FileSystem.FileSystem service to lock down the config file's permissions unconditionally.

@jgoux jgoux closed this Sep 4, 2026
pull Bot pushed a commit to oogalieboogalie/cli that referenced this pull request Sep 7, 2026
## Summary

Rewrites `@supabase/stack` around one managed-only runtime shared by
strict native and container execution modes. The package owns durable
configuration and secrets, sticky ports, artifact preparation, lifecycle
arbitration, per-service eager or lazy activation, service migrations,
ingress, retained and live logs, and exact resource cleanup.

A stopped stack has no resident supervisor or runtime resources: status
and retained logs come from durable state, while a later start creates a
fresh owner and performs clean recovery. PostgreSQL 17 is the only eager
service by default; other enabled services activate through stack
ingress, and callers can configure eager activation. Dependency-ready
workloads start concurrently. Docker-compatible engines, including
Podman, share the same container path.

Enabled lazy services prepare their artifacts in the background after
startup by default. `preparation: "on-demand"` retains full lazy
downloading, while explicit `prepare()` remains available in either
mode. Foreground activation prepares its dependency closure concurrently
and shares in-flight downloads with background preparation. All selected
workload downloads can run concurrently. Native archives are streamed to
disk while hashing, verified before extraction, and decompressed without
retaining whole archives in memory. Runtime cleanup cancels unfinished
transfers and retains completed cache entries. Status exposes artifact
preparation separately from service readiness, and explicit preparation
reports progress through `onProgress`.

Edge Functions are served through the stack-owned Edge Runtime for
package consumers. The package runs independently of the CLI and accepts
normalized `StackConfig` values without reading `config.toml`. All CLI
integration, including `supabase functions serve` and lifecycle commands
under `experimental start`, belongs to M5 in separate PRs. Existing CLI
Functions behavior is preserved. The deleted `next` CLI was a disposable
proving ground and is not part of this PR.

Service preparation now lives in the published runtime artifacts:
PostgreSQL owns first boot and bundled migrations, service helpers own
migration and Pooler tenant provisioning, and Node services expose
public launchers shared with their images. The stack supplies instance
settings and sequences those commands. Default images use the configured
slim-services tags or digests, including the artifacts from
[slim-services #299](supabase/slim-services#299)
and the BEAM versions republished after [slim-services
#302](supabase/slim-services#302). Native
downloads are checked against the checksum published with the same
release. BEAM launchers own the shared runtime defaults in native and
container modes; Vector configuration and Edge Functions bootstrap
remain stack-owned.

Unix control sockets bind inside owner-private directories. Container
mount paths preserve CSV special characters, and default state paths use
the user home directory when `HOME` is absent.

Obsolete process-compose integration and superseded runtime helpers are
removed.

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

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants