Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
47 commits
Select commit Hold shift + click to select a range
3b3cc56
fix(ci): use supported Compose create flags
Aug 11, 2026
320c02b
feat(ci): probe Compose service startup
Aug 11, 2026
090b9e6
feat(ci): probe collective Compose startup
Aug 11, 2026
6f566c0
fix(local-stack): start Compose services individually
Aug 11, 2026
d032680
fix(ci): recover service probe after collective failure
Aug 11, 2026
9115407
fix(ci): continue after bounded startup diagnostics
Aug 11, 2026
c98bb1d
fix(local-stack): distinguish Compose create failures
Aug 11, 2026
2a0ea3c
fix(local-stack): use supported image pull policy
Aug 11, 2026
854fe68
fix(local-stack): gate dependent service startup
Aug 11, 2026
b8f7e4e
fix(ci): preserve failed stack for diagnostics
Aug 11, 2026
4135ebd
feat(ci): capture bounded runtime health diagnostics
Aug 11, 2026
dcbc416
feat(ci): classify Compose runtime logs
Aug 11, 2026
64fcc21
fix(local-stack): gate analytics on database bootstrap
Aug 11, 2026
f8a293d
fix(local-stack): allow database bootstrap completion
Aug 11, 2026
115bc27
feat(ci): capture database bootstrap status
Aug 11, 2026
c1e411d
fix(local-stack): stage database init files
Aug 11, 2026
a13c3c7
fix(local-stack): stage readable database init copies
Aug 11, 2026
d6b5b07
fix(ci): remove stale nightly project volumes
Aug 11, 2026
8e3ab50
fix(local-stack): keep image migration mounts intact
Aug 11, 2026
d7d5e2f
test(ci): expose bounded database bootstrap evidence
Aug 11, 2026
fdc0a4d
fix(local-stack): stage SQL through readable init volumes
Aug 11, 2026
865ad92
fix(local-stack): stage non-root config inputs
Aug 11, 2026
dd6ba96
test(ci): classify Supavisor startup failures
Aug 12, 2026
d3bfccc
test(ci): classify Tini startup failures
Aug 12, 2026
59b72c0
test(ci): verify staged runtime mounts
Aug 12, 2026
7d9f8a4
fix(ci): import runtime diagnostic validator
Aug 12, 2026
71f5ee4
fix(ci): import runtime mount diagnostics
Aug 12, 2026
a9f0a75
fix(local-stack): bypass denied Supavisor subreaper
Aug 12, 2026
9cf5355
test(ci): record Supavisor entrypoint evidence
Aug 12, 2026
19fe208
test(ci): retain bounded runtime signatures
Aug 12, 2026
96f024a
fix(local-stack): disable unsupported Supavisor clustering
Aug 12, 2026
a44ac36
fix(local-stack): disable unused Erlang distribution
Aug 12, 2026
79031df
fix(local-stack): allow Erlang startup syscalls
Aug 12, 2026
7a2d828
revert(local-stack): keep hosted seccomp default
Aug 12, 2026
fc24d39
test(ci): classify Erlang permission failures
Aug 12, 2026
94b3ff2
fix(local-stack): clear inherited Erlang environment
Aug 12, 2026
b8d49c2
fix(local-stack): clear image Erlang flags
Aug 12, 2026
55d4d1e
fix(local-stack): clear Supavisor file limit override
Aug 12, 2026
5985274
fix(ci): verify tracked prerequisite in place
Aug 12, 2026
f312986
fix(local-migrate): admit hosted CI Docker socket
Aug 12, 2026
a52e301
fix(local-runtime): admit hosted CI Docker socket
Aug 12, 2026
c984ae4
fix(local-runtime): validate staged database volumes
Aug 12, 2026
64390c0
fix(local-runtime): retain smoke failure receipt
Aug 12, 2026
39e801c
fix(local-runtime): allow privacy guard smoke state
Aug 12, 2026
79cdbc9
test(web): match restricted announcement branch
Aug 12, 2026
eb7607c
fix(nightly): propagate Node24 supervisor runtime
Aug 12, 2026
838ff76
fix(storyboard): allow Linux supervisor drain grace
Aug 12, 2026
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
492 changes: 486 additions & 6 deletions .github/workflows/nightly-local-regression.yml

Large diffs are not rendered by default.

9 changes: 7 additions & 2 deletions apps/web/lib/admin/storyboard/backend-agent.ts
Original file line number Diff line number Diff line change
Expand Up @@ -87,6 +87,7 @@ const WINDOWS_PROCESS_TERMINATION_TIMEOUT_MS = 5_000;
const WINDOWS_JOB_SUPERVISOR_CLEANUP_GRACE_MS = 5_000;
const WINDOWS_JOB_SUPERVISOR_FINAL_CLOSE_TIMEOUT_MS = 5_000;
const LINUX_NAMESPACE_TERMINATION_TIMEOUT_MS = 10_000;
const LINUX_NAMESPACE_SUPERVISOR_DRAIN_TIMEOUT_MS = 7_000;
const MAX_STORYBOARD_AGENT_TIMEOUT_MS = 600_000;
function getRuntimeCwd() {
const cwd = Reflect.get(process, "cwd");
Expand Down Expand Up @@ -4320,6 +4321,10 @@ function runStoryboardAgentCommand(
processControl.platform === "linux" &&
isNativeProcessControl &&
!trustedLangGraphFixture;
const lifecycleStreamDrainTimeoutMs =
useLinuxNamespaceSupervisor && processControl.streamDrainTimeoutMs === undefined
? Math.max(streamDrainTimeoutMs, LINUX_NAMESPACE_SUPERVISOR_DRAIN_TIMEOUT_MS)
: streamDrainTimeoutMs;
const linuxSupervisorNonce = useLinuxNamespaceSupervisor
? randomBytes(32).toString("hex")
: "";
Expand Down Expand Up @@ -4414,7 +4419,7 @@ function runStoryboardAgentCommand(
);
stderr = stderrCapture.value;
finish();
}, streamDrainTimeoutMs);
}, lifecycleStreamDrainTimeoutMs);
streamWaiters.add(finish);
});
const terminateTree = async (awaitWindowsCleanupGrace = false) => {
Expand Down Expand Up @@ -4647,7 +4652,7 @@ function runStoryboardAgentCommand(
"diagnostic stream drain deadline exceeded",
exitCode,
);
}, streamDrainTimeoutMs);
}, lifecycleStreamDrainTimeoutMs);
}
};

Expand Down
6 changes: 5 additions & 1 deletion apps/web/scripts/run-nightly-regression.mjs
Original file line number Diff line number Diff line change
Expand Up @@ -1102,7 +1102,11 @@ async function waitForHealth(appProcess, healthUrl, mode, headers = undefined) {
}

async function runUnitRegression(environment) {
const result = await runCommand('bun', ['run', 'test:unit'], { env: environment });
const supervisorExecutable = process.env.TZUDONG_NODE24_EXECUTABLE?.trim();
const unitEnvironment = supervisorExecutable
? { ...environment, TZUDONG_NODE24_EXECUTABLE: supervisorExecutable }
: environment;
const result = await runCommand('bun', ['run', 'test:unit'], { env: unitEnvironment });
if (result.code !== 0) {
throw new Error(`Nightly unit regressions failed with exit code ${result.code}.`);
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -69,7 +69,9 @@ describe('admin announcements console integration source contract', () => {
expect(headerSource).toContain('AnnouncementPanelLoadingFallback');
expect(headerSource).toContain('HeaderAnnouncementPanel ?');
expect(desktopControlPanelSource).toContain('AnnouncementPanelLoadingFallback');
expect(desktopControlPanelSource).toContain('activeLeftPanelView === "announcement" ?');
expect(desktopControlPanelSource).toContain(
'activeLeftPanelView === "announcement" && !isPublicRestrictedMode ?',
);
expect(homeSidePanelsSource).toContain('loading: () => <AnnouncementPanelLoadingFallback');
});

Expand Down
62 changes: 61 additions & 1 deletion apps/web/tests-unit/nightly-regression-workflow.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -44,6 +44,15 @@ describe("nightly regression package and source contracts", () => {
expect(nightlyRunnerSource).toContain("function main()");
});

test("passes the verified Node 24 supervisor into the unit lane", () => {
expect(nightlyRunnerSource).toContain(
"const supervisorExecutable = process.env.TZUDONG_NODE24_EXECUTABLE?.trim();",
);
expect(nightlyRunnerSource).toContain(
"TZUDONG_NODE24_EXECUTABLE: supervisorExecutable",
);
});

test("preserves the hosted nightly schedule and bounded diagnostics", () => {
expect(hostedWorkflowSource).toContain("cron: '30 18 * * *'");
expect(hostedWorkflowSource).toContain("workflow_dispatch:");
Expand Down Expand Up @@ -280,6 +289,7 @@ describe("nightly regression package and source contracts", () => {
"user.max_user_namespaces=28633",
"python3 backend/supabase/scripts/local-stack.py reset",
"python3 backend/supabase/scripts/local-migrate.py apply-prerequisite",
"python3 backend/supabase/scripts/local-migrate.py verify-prerequisite",
"python3 backend/supabase/scripts/local-migrate.py apply",
"python3 backend/supabase/scripts/local-function-runtime-scan.py smoke",
"python3 backend/supabase/scripts/local-migrate.py receipt",
Expand All @@ -301,12 +311,62 @@ describe("nightly regression package and source contracts", () => {
"Probe Compose container creation",
"backend/supabase/scripts/local-stack.py render",
"local-compose-create-preflight-v1",
"create', '--no-start'",
"create', '--pull=never'",
"mount_invalid",
"network_create",
"runtime_create",
"Probe Compose service startup",
"local-compose-start-preflight-v1",
"collective",
"up', '-d', '--pull=never'",
"docker', 'compose",
"'start', service",
"exec_invalid",
"Capture bounded Compose runtime diagnostics",
"local-compose-runtime-diagnostics-v1",
"health_failing_streak",
"health_log_exit_codes",
"log_failure_class",
"oom_killed",
"restart_count",
"database_bootstrap",
"database_presence",
"database_init_files",
"database_permission",
"config_permission",
"auth_failure",
"tini_runtime",
"thread_create",
"scheduler_permission",
"procfs_permission",
"socket_permission",
"signal_permission",
"namespace_permission",
"operation_not_permitted",
"erl_runtime",
"runtime_input_checks",
"runtime_env_presence",
"RLIMIT_NOFILE",
"nonempty",
"empty",
"entrypoint_class",
"log_signatures",
"supabase_db_present",
"supabase_db_missing",
"analytics_schema_present",
"analytics_schema_missing",
"stack.env and credentials excluded",
"down --volumes --remove-orphans",
"docker volume rm -f",
"${LOCAL_PROJECT}-db-data",
"${LOCAL_PROJECT}-db-config",
"${LOCAL_PROJECT}-db-init-migrations",
"${LOCAL_PROJECT}-db-init-scripts",
"${LOCAL_PROJECT}-functions",
"${LOCAL_PROJECT}-kong-config",
"${LOCAL_PROJECT}-pooler-config",
"${LOCAL_PROJECT}-storage-data",
"${LOCAL_PROJECT}-vector-config",
]) {
expect(localWorkflowSource).toContain(token);
}
Expand Down
50 changes: 39 additions & 11 deletions backend/supabase/docker-compose.local.yml
Original file line number Diff line number Diff line change
Expand Up @@ -45,7 +45,7 @@ services:
- "127.0.0.1:${KONG_HTTP_PORT}:8000/tcp"
- "127.0.0.1:${KONG_HTTPS_PORT}:8443/tcp"
volumes: !override
- "${LOCAL_INPUT_ROOT}/kong.yml:/home/kong/temp.yml:ro,z"
- "local-kong-config:/home/kong:Z"

auth:
container_name: !reset null
Expand Down Expand Up @@ -74,7 +74,7 @@ services:
functions:
container_name: !reset null
volumes: !override
- "${LOCAL_INPUT_ROOT}/functions:/home/deno/functions:ro,Z"
- "local-functions:/home/deno/functions:Z"

analytics:
container_name: !reset null
Expand All @@ -84,34 +84,62 @@ services:
db:
container_name: !reset null
volumes: !override
- "${LOCAL_INPUT_ROOT}/db-realtime.sql:/docker-entrypoint-initdb.d/migrations/99-realtime.sql:ro,z"
- "${LOCAL_INPUT_ROOT}/db-webhooks.sql:/docker-entrypoint-initdb.d/init-scripts/98-webhooks.sql:ro,z"
- "${LOCAL_INPUT_ROOT}/db-roles.sql:/docker-entrypoint-initdb.d/init-scripts/99-roles.sql:ro,z"
- "${LOCAL_INPUT_ROOT}/db-jwt.sql:/docker-entrypoint-initdb.d/init-scripts/99-jwt.sql:ro,z"
- "local-db-init-migrations:/docker-entrypoint-initdb.d/migrations:Z"
- "local-db-init-scripts:/docker-entrypoint-initdb.d/init-scripts:Z"
Comment on lines +87 to +88

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 Verify staged volume contents before accepting the stack

The new database-init volumes are mounted read-write, but after _stage_input_files copies the source-bound SQL, subsequent readiness and runtime admission verify only service health and volume identities—not the hashes or modes of the files actually mounted in the container. If database startup or another volume consumer alters a staged file, the stack can still emit receipts claiming the checkout provenance while executing different bytes. Mount staged inputs read-only where possible, or read back and hash each staged destination before accepting the stack.

AGENTS.md reference: AGENTS.md:L80-L80

Useful? React with 👍 / 👎.

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 Preserve image-provided database initialization scripts

Mounting a fresh named volume over the entire init-scripts directory hides the scripts supplied by supabase/postgres:15.8.1.085; the repository itself extracts and requires /docker-entrypoint-initdb.d/init-scripts/00000000000001-auth-schema.sql from that image in backend/supabase/scripts/generate_g014_catalog_contract_baseline.sh:646-656. _stage_input_files copies only the repository's 98-webhooks.sql, 99-roles.sql, and 99-jwt.sql, so a fresh local database boots without the image's platform auth bootstrap. Stage into the volume without masking the image defaults, or copy the required image-provided scripts into it before starting db.

AGENTS.md reference: AGENTS.md:L80-L80

Useful? React with 👍 / 👎.

- "local-db-data:/var/lib/postgresql/data:Z"
- "${LOCAL_INPUT_ROOT}/db-supabase.sql:/docker-entrypoint-initdb.d/migrations/97-_supabase.sql:ro,z"
- "${LOCAL_INPUT_ROOT}/db-logs.sql:/docker-entrypoint-initdb.d/migrations/99-logs.sql:ro,z"
- "${LOCAL_INPUT_ROOT}/db-pooler.sql:/docker-entrypoint-initdb.d/migrations/99-pooler.sql:ro,z"
- "local-db-config:/etc/postgresql-custom"

vector:
container_name: !reset null
volumes: !override
- "${LOCAL_INPUT_ROOT}/vector.yml:/etc/vector/vector.yml:ro,z"
- "local-vector-config:/etc/vector:Z"

supavisor:
container_name: !reset null
# GitHub-hosted Docker denies Tini's subreaper setup; the image's limits
# wrapper preserves bounded startup without requiring that capability.
entrypoint: ["/app/limits.sh"]
environment: !override
PORT: 4000
POSTGRES_PORT: ${POSTGRES_PORT}
POSTGRES_DB: ${POSTGRES_DB}
POSTGRES_PASSWORD: ${POSTGRES_PASSWORD}
DATABASE_URL: ecto://supabase_admin:${POSTGRES_PASSWORD}@${POSTGRES_HOST}:${POSTGRES_PORT}/_supabase
SECRET_KEY_BASE: ${SECRET_KEY_BASE}
VAULT_ENC_KEY: ${VAULT_ENC_KEY}
API_JWT_SECRET: ${JWT_SECRET}
METRICS_JWT_SECRET: ${JWT_SECRET}
REGION: local
ERL_AFLAGS: ""
RLIMIT_NOFILE: ""
POOLER_TENANT_ID: ${POOLER_TENANT_ID}
POOLER_DEFAULT_POOL_SIZE: ${POOLER_DEFAULT_POOL_SIZE}
POOLER_MAX_CLIENT_CONN: ${POOLER_MAX_CLIENT_CONN}
POOLER_POOL_MODE: transaction
DB_POOL_SIZE: ${POOLER_DB_POOL_SIZE}
ports: !override
# POSTGRES_PORT remains the internal 5432 listener; only the host mapping is derived.
- "127.0.0.1:${POSTGRES_HOST_PORT}:5432/tcp"
- "127.0.0.1:${POOLER_PROXY_PORT_TRANSACTION}:6543/tcp"
volumes: !override
- "${LOCAL_INPUT_ROOT}/pooler.exs:/etc/pooler/pooler.exs:ro,z"
- "local-pooler-config:/etc/pooler:Z"

volumes: !override
local-db-data:
name: "${PROJECT_NAME}-db-data"
local-db-init-migrations:
name: "${PROJECT_NAME}-db-init-migrations"
local-db-init-scripts:
name: "${PROJECT_NAME}-db-init-scripts"
local-db-config:
name: "${PROJECT_NAME}-db-config"
local-functions:
name: "${PROJECT_NAME}-functions"
local-kong-config:
name: "${PROJECT_NAME}-kong-config"
local-pooler-config:
name: "${PROJECT_NAME}-pooler-config"
local-storage-data:
name: "${PROJECT_NAME}-storage-data"
local-vector-config:
name: "${PROJECT_NAME}-vector-config"
66 changes: 18 additions & 48 deletions backend/supabase/local-inputs/manifest.v1.json
Original file line number Diff line number Diff line change
Expand Up @@ -133,9 +133,9 @@
"mounts": [
{
"service": "kong",
"source": "kong.yml",
"type": "bind",
"destination": "/home/kong/temp.yml"
"source": "local-kong-config",
"type": "volume",
"destination": "/home/kong"
},
{
"service": "storage",
Expand All @@ -151,33 +151,15 @@
},
{
"service": "functions",
"source": "functions",
"type": "bind",
"source": "local-functions",
"type": "volume",
"destination": "/home/deno/functions"
},
{
"service": "db",
"source": "db-realtime.sql",
"type": "bind",
"destination": "/docker-entrypoint-initdb.d/migrations/99-realtime.sql"
},
{
"service": "db",
"source": "db-webhooks.sql",
"type": "bind",
"destination": "/docker-entrypoint-initdb.d/init-scripts/98-webhooks.sql"
},
{
"service": "db",
"source": "db-roles.sql",
"type": "bind",
"destination": "/docker-entrypoint-initdb.d/init-scripts/99-roles.sql"
},
{
"service": "db",
"source": "db-jwt.sql",
"type": "bind",
"destination": "/docker-entrypoint-initdb.d/init-scripts/99-jwt.sql"
"source": "local-db-init-migrations",
"type": "volume",
"destination": "/docker-entrypoint-initdb.d/migrations"
},
{
"service": "db",
Expand All @@ -187,21 +169,9 @@
},
{
"service": "db",
"source": "db-supabase.sql",
"type": "bind",
"destination": "/docker-entrypoint-initdb.d/migrations/97-_supabase.sql"
},
{
"service": "db",
"source": "db-logs.sql",
"type": "bind",
"destination": "/docker-entrypoint-initdb.d/migrations/99-logs.sql"
},
{
"service": "db",
"source": "db-pooler.sql",
"type": "bind",
"destination": "/docker-entrypoint-initdb.d/migrations/99-pooler.sql"
"source": "local-db-init-scripts",
"type": "volume",
"destination": "/docker-entrypoint-initdb.d/init-scripts"
},
{
"service": "db",
Expand All @@ -211,15 +181,15 @@
},
{
"service": "vector",
"source": "vector.yml",
"type": "bind",
"destination": "/etc/vector/vector.yml"
"source": "local-vector-config",
"type": "volume",
"destination": "/etc/vector"
},
{
"service": "supavisor",
"source": "pooler.exs",
"type": "bind",
"destination": "/etc/pooler/pooler.exs"
"source": "local-pooler-config",
"type": "volume",
"destination": "/etc/pooler"
}
],
"compose_files": [
Expand All @@ -229,7 +199,7 @@
},
{
"path": "backend/supabase/docker-compose.local.yml",
"sha256": "ba8ad34ed798b306bdfba45c9b0c6410f91ca74b44361afc29b8b531ee555086"
"sha256": "d46ddc6ff5bfb3a268d8e2a537c5c202d7e3d6f055fd67759912ad3e8d7c5c8a"
},
{
"path": "backend/supabase/docker-compose.mail.yml",
Expand Down
Loading
Loading