@rehearsal-db/core 0.1.0-rc.1 → 0.1.0-rc.2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/CHANGELOG.md CHANGED
@@ -5,6 +5,27 @@ a Changelog, and versions will follow Semantic Versioning after the package exis
5
5
 
6
6
  ## Unreleased
7
7
 
8
+ ## [0.1.0-rc.2] - 2026-10-09
9
+
10
+ ### Changed
11
+
12
+ - Container-engine startup is now explicit by default. Rehearsal starts Colima only
13
+ when a project deliberately enables `containerRuntime.autoStartColima`, reports that
14
+ action, and never silently stops the shared engine.
15
+ - Package-managed Supabase containers use Docker's non-resuming restart policy after
16
+ each start, preventing stopped Rehearsal stacks from waking merely because Docker or
17
+ Colima restarts. Exact Supabase project labels keep the change inside the selected
18
+ disposable target.
19
+ - Runtime diagnostics and a new lifecycle guide explain which commands need Docker,
20
+ what remains running, and how to finish a low-memory local session without pruning or
21
+ deleting persistent data.
22
+
23
+ ### Fixed
24
+
25
+ - A stopped Colima VM no longer restarts from a default Rehearsal configuration.
26
+ - Independent Test Lab acceptance now reaps exact workspace-owned interactive children
27
+ after success, failure, interruption, and timeout.
28
+
8
29
  ## [0.1.0-rc.1] - 2026-10-08
9
30
 
10
31
  ### Changed
@@ -554,7 +575,8 @@ a Changelog, and versions will follow Semantic Versioning after the package exis
554
575
  publication uses short-lived trusted OIDC, and every release tag must already exist on
555
576
  protected `main`.
556
577
 
557
- [Unreleased]: https://github.com/Ddupasquier/rehearsal-db/compare/v0.1.0-rc.1...HEAD
578
+ [Unreleased]: https://github.com/Ddupasquier/rehearsal-db/compare/v0.1.0-rc.2...HEAD
579
+ [0.1.0-rc.2]: https://github.com/Ddupasquier/rehearsal-db/compare/v0.1.0-rc.1...v0.1.0-rc.2
558
580
  [0.1.0-rc.1]: https://github.com/Ddupasquier/rehearsal-db/compare/v0.1.0-beta.18...v0.1.0-rc.1
559
581
  [0.1.0-beta.18]: https://github.com/Ddupasquier/rehearsal-db/compare/v0.1.0-beta.17...v0.1.0-beta.18
560
582
  [0.1.0-beta.17]: https://github.com/Ddupasquier/rehearsal-db/compare/v0.1.0-beta.16...v0.1.0-beta.17
package/README.md CHANGED
@@ -1,12 +1,39 @@
1
- # Rehearsal
1
+ <p align="center">
2
+ <img src="https://raw.githubusercontent.com/Ddupasquier/rehearsal-db/main/docs/site/logo-mark.svg" width="104" height="104" alt="Rehearsal logo" />
3
+ </p>
2
4
 
3
- [![Monthly npm downloads](https://img.shields.io/npm/dm/%40rehearsal-db%2Fcore?style=flat-square&logo=npm&logoColor=white&label=npm%20downloads&labelColor=1c2a34&color=287b5c)](https://www.npmjs.com/package/@rehearsal-db/core)
5
+ <h1 align="center">Rehearsal</h1>
4
6
 
5
- [Read the documentation](https://ddupasquier.github.io/rehearsal-db/) · [View on npm](https://www.npmjs.com/package/@rehearsal-db/core) · [Report a problem](https://github.com/Ddupasquier/rehearsal-db/issues)
7
+ <p align="center"><strong>Your migration passed on an empty database. Production will not be empty.</strong></p>
6
8
 
7
- Rehearsal tests PostgreSQL and Supabase migrations on your computer before you run them
8
- anywhere important. It restores safe test data into a disposable local database, applies
9
- only the migrations you approve, and runs your project's own test command.
9
+ <p align="center">
10
+ <a href="https://www.npmjs.com/package/@rehearsal-db/core"><img alt="npm version" src="https://img.shields.io/npm/v/%40rehearsal-db%2Fcore?style=flat-square&logo=npm&logoColor=white&labelColor=1c2a34&color=287b5c" /></a>
11
+ <a href="https://www.npmjs.com/package/@rehearsal-db/core"><img alt="Monthly npm downloads" src="https://img.shields.io/npm/dm/%40rehearsal-db%2Fcore?style=flat-square&logo=npm&logoColor=white&label=downloads&labelColor=1c2a34&color=287b5c" /></a>
12
+ <a href="LICENSE"><img alt="MIT license" src="https://img.shields.io/npm/l/%40rehearsal-db%2Fcore?style=flat-square&labelColor=1c2a34&color=287b5c" /></a>
13
+ <a href="https://ddupasquier.github.io/rehearsal-db/"><img alt="Read the documentation" src="https://img.shields.io/badge/docs-read_the_guide-269fab?style=flat-square&labelColor=1c2a34" /></a>
14
+ </p>
15
+
16
+ <p align="center">
17
+ <a href="https://ddupasquier.github.io/rehearsal-db/">Read the documentation</a> ·
18
+ <a href="https://www.npmjs.com/package/@rehearsal-db/core">View on npm</a> ·
19
+ <a href="https://github.com/Ddupasquier/rehearsal-db/issues">Report a problem</a>
20
+ </p>
21
+
22
+ Most migration tests start with an empty database. Production does not.
23
+
24
+ Existing rows, relationships, authentication identities, stored files, and migration
25
+ history are where risky changes break. A migration can build successfully and still fail
26
+ against the data and application behavior you actually have.
27
+
28
+ **Rehearsal catches those problems before deployment.** It restores a reviewed,
29
+ sanitized baseline into a disposable local PostgreSQL or Supabase environment, applies
30
+ only the exact migrations you approve, and runs your application's own proof.
31
+
32
+ | An empty database cannot prove… | Rehearsal lets you verify… |
33
+ | ---------------------------------------------------- | ------------------------------------------------------------ |
34
+ | old rows still satisfy new constraints | the migration against a reviewed, production-shaped copy |
35
+ | relationships, identities, and stored files survive | database, Auth, and Storage behavior in one local sandbox |
36
+ | the application still works after the schema changes | your own tests and hands-on flows before anything is shipped |
10
37
 
11
38
  Projects with a separate publication or read-model database can declare it as a
12
39
  dependent target. Rehearsal then manages the complete isolated runtime stack.
@@ -17,7 +44,7 @@ it through a reviewed privacy policy, and retire the access again. It is never p
17
44
  `run`, `reset`, `migrate`, or application launch. Rehearsal is not a backup system or a
18
45
  production deployment tool.
19
46
 
20
- > Rehearsal is in public beta. Use it on a branch and keep a working backup of your
47
+ > **Pre-1.0 safety note:** use Rehearsal on a branch and keep a working backup of your
21
48
  > project.
22
49
 
23
50
  ## What you need
@@ -37,7 +64,7 @@ your migration is intended to change.
37
64
  From your project directory:
38
65
 
39
66
  ```bash
40
- npm install --save-dev @rehearsal-db/core@beta
67
+ npm install --save-dev @rehearsal-db/core
41
68
  npx rehearsal
42
69
  ```
43
70
 
@@ -145,6 +172,7 @@ Reference:
145
172
 
146
173
  - [CLI commands](docs/commands.md)
147
174
  - [Configuration](docs/configuration.md)
175
+ - [Container runtime lifecycle](docs/runtime-lifecycle.md) — keep Docker and Supabase use on demand
148
176
  - [TypeScript types](docs/typescript.md)
149
177
  - [Baselines](docs/baselines.md)
150
178
  - [Sanitization](docs/sanitization.md)
package/dist/package.json CHANGED
@@ -1,8 +1,8 @@
1
1
  {
2
2
  "name": "@rehearsal-db/core",
3
- "version": "0.1.0-rc.1",
3
+ "version": "0.1.0-rc.2",
4
4
  "private": false,
5
- "description": "Safely rehearse PostgreSQL and Supabase migrations against sanitized, production-shaped data.",
5
+ "description": "Catch PostgreSQL and Supabase migrations that pass on empty databases but fail on real data—before deploy.",
6
6
  "repository": {
7
7
  "type": "git",
8
8
  "url": "git+https://github.com/Ddupasquier/rehearsal-db.git"
@@ -106,7 +106,7 @@ export declare const REHEARSAL_DEFAULTS: Readonly<{
106
106
  artifactDirectory: ".rehearsal";
107
107
  }>;
108
108
  containerRuntime: Readonly<{
109
- autoStartColima: true;
109
+ autoStartColima: false;
110
110
  }>;
111
111
  cleanup: Readonly<{
112
112
  retainBaselineGenerations: 2;
@@ -2,7 +2,7 @@
2
2
  export const REHEARSAL_CONFIG_VERSION = 1;
3
3
  export const REHEARSAL_DEFAULTS = Object.freeze({
4
4
  baseline: Object.freeze({ artifactDirectory: ".rehearsal" }),
5
- containerRuntime: Object.freeze({ autoStartColima: true }),
5
+ containerRuntime: Object.freeze({ autoStartColima: false }),
6
6
  cleanup: Object.freeze({ retainBaselineGenerations: 2 }),
7
7
  runtime: Object.freeze({
8
8
  applicationUrl: "http://localhost:5175",
@@ -61,9 +61,10 @@ export default defineRehearsalConfig({
61
61
  // After setup, run: npx rehearsal identity connect
62
62
  // identityPolicy: "infrastructure/rehearsal/identity-policy.json",
63
63
 
64
- // Reuse any running Docker-compatible engine; start Colima only when needed.
64
+ // Reuse any running Docker-compatible engine. Keep startup explicit so a
65
+ // Rehearsal command cannot wake unrelated containers after Docker was stopped.
65
66
  containerRuntime: {
66
- autoStartColima: true,
67
+ autoStartColima: false,
67
68
  },
68
69
 
69
70
  // Keep this many baseline generations, always including the active one.
@@ -166,9 +167,10 @@ export default defineRehearsalConfig({
166
167
  // After setup, run: npx rehearsal identity connect
167
168
  // identityPolicy: "infrastructure/rehearsal/identity-policy.json",
168
169
 
169
- // Reuse any running Docker-compatible engine; start Colima only when needed.
170
+ // Reuse any running Docker-compatible engine. Keep startup explicit so a
171
+ // Rehearsal command cannot wake unrelated containers after Docker was stopped.
170
172
  containerRuntime: {
171
- autoStartColima: true,
173
+ autoStartColima: false,
172
174
  },
173
175
 
174
176
  // Keep this many baseline generations, always including the active one.
@@ -94,6 +94,9 @@ const resultCheck = async ({ id, label, run, remediation, }) => {
94
94
  }
95
95
  };
96
96
  const assertRuntimeConfigMatches = async ({ config, paths, }) => {
97
+ const startupPolicy = config.containerRuntime.autoStartColima
98
+ ? "Colima auto-start is enabled and may wake shared Docker containers"
99
+ : "container-engine startup is explicit";
97
100
  if (config.runtime.target === "postgresql") {
98
101
  if (paths.rehearsalConfig !== null || paths.supabaseWorkdir !== null) {
99
102
  throw new Error("The PostgreSQL target unexpectedly resolved Supabase paths.");
@@ -101,7 +104,7 @@ const assertRuntimeConfigMatches = async ({ config, paths, }) => {
101
104
  if (!config.postgresql) {
102
105
  throw new Error("The PostgreSQL target is missing its configuration.");
103
106
  }
104
- return `isolated PostgreSQL image ${config.postgresql.image} and a loopback database port are configured`;
107
+ return `isolated PostgreSQL image ${config.postgresql.image} and a loopback database port are configured; ${startupPolicy}`;
105
108
  }
106
109
  if (!paths.rehearsalConfig) {
107
110
  throw new Error("The Supabase target is missing its runtime configuration.");
@@ -121,7 +124,7 @@ const assertRuntimeConfigMatches = async ({ config, paths, }) => {
121
124
  if (/\blinked\s*=\s*true\b/iu.test(source)) {
122
125
  throw new Error("Local Supabase config unexpectedly enables a linked target.");
123
126
  }
124
- return "isolated Supabase project and ports match the project contract";
127
+ return `isolated Supabase project and ports match the project contract; ${startupPolicy}`;
125
128
  };
126
129
  const assertBaselinePermissions = async ({ paths, }) => {
127
130
  const details = await stat(paths.dataPath);
@@ -388,6 +388,7 @@ const resetRuntime = async () => {
388
388
  exclude: ["edge-runtime", "logflare", "vector", "realtime"],
389
389
  environment: serviceEnvironment,
390
390
  autoStartColima: config.containerRuntime.autoStartColima,
391
+ projectId: config.runtime.projectId,
391
392
  });
392
393
  const structuralSchemaSha256 = await restoreProductionSchema(active);
393
394
  await restoreBaselineRows(active);
@@ -446,6 +447,7 @@ const startRuntime = async () => {
446
447
  exclude: ["edge-runtime", "logflare", "vector", "realtime"],
447
448
  environment: serviceEnvironment,
448
449
  autoStartColima: config.containerRuntime.autoStartColima,
450
+ projectId: config.runtime.projectId,
449
451
  });
450
452
  const projectRuntime = configureProjectRuntime({ environment, baseline });
451
453
  await writeRuntimeEnvironment({
@@ -35,11 +35,16 @@ export declare const ensureLocalContainerRuntime: ({ cwd, autoStartColima, }?: {
35
35
  cwd?: string | undefined;
36
36
  autoStartColima?: boolean;
37
37
  }) => void;
38
+ export declare const preventOwnedSupabaseAutoRestart: ({ cwd, projectId, }: {
39
+ cwd?: string | undefined;
40
+ projectId: string;
41
+ }) => readonly string[];
38
42
  export declare const readLocalSupabaseEnvironment: ({ cwd, workdir, environment, }?: SupabaseCommandOptions) => LocalSupabaseEnvironment;
39
- export declare const startLocalSupabase: ({ cwd, workdir, exclude, environment, applyMigrations, autoStartColima, }?: SupabaseCommandOptions & {
43
+ export declare const startLocalSupabase: ({ cwd, workdir, exclude, environment, applyMigrations, autoStartColima, projectId, }?: SupabaseCommandOptions & {
40
44
  exclude?: readonly string[];
41
45
  applyMigrations?: boolean;
42
46
  autoStartColima?: boolean;
47
+ projectId?: string | undefined;
43
48
  }) => LocalSupabaseEnvironment;
44
49
  export declare const stopLocalSupabase: ({ cwd, workdir, environment, }?: SupabaseCommandOptions) => void;
45
50
  export declare const removeLocalSupabaseProjectResources: ({ cwd, projectId, }?: {
@@ -90,22 +90,42 @@ export const localCommandSucceeds = (command, args, { cwd = process.cwd(), envir
90
90
  env: createCleanProcessEnvironment({ overrides: environment }),
91
91
  stdio: "ignore",
92
92
  }).status === 0;
93
- export const ensureLocalContainerRuntime = ({ cwd = process.cwd(), autoStartColima = true, } = {}) => {
93
+ export const ensureLocalContainerRuntime = ({ cwd = process.cwd(), autoStartColima = false, } = {}) => {
94
94
  if (localCommandSucceeds("docker", ["info"], { cwd }))
95
95
  return;
96
96
  if (autoStartColima && localCommandSucceeds("colima", ["version"], { cwd })) {
97
97
  runLocalCommand("colima", ["start"], { cwd });
98
+ console.log("Started Colima because containerRuntime.autoStartColima is enabled. Rehearsal will not stop this shared Docker runtime automatically.");
98
99
  }
99
100
  if (!localCommandSucceeds("docker", ["info"], { cwd })) {
100
- throw new Error("A local Docker-compatible runtime is required. Install Docker or Colima, then rerun the command.");
101
+ throw new Error(autoStartColima
102
+ ? "A local Docker-compatible runtime is required. Install Docker or Colima, then rerun the command."
103
+ : "A local Docker-compatible runtime is stopped or unavailable. Start Docker or Colima explicitly, or opt in with containerRuntime.autoStartColima: true.");
101
104
  }
102
105
  };
106
+ export const preventOwnedSupabaseAutoRestart = ({ cwd = process.cwd(), projectId, }) => {
107
+ if (!/^[a-z0-9][a-z0-9-]{1,62}$/u.test(projectId)) {
108
+ throw new Error("Refusing to change container restart policies without an exact safe Supabase project id.");
109
+ }
110
+ const label = `com.supabase.cli.project=${projectId}`;
111
+ const containers = runLocalCommand("docker", ["ps", "--all", "--filter", `label=${label}`, "--format", "{{.ID}}"], { capture: true, cwd })
112
+ .split("\n")
113
+ .map((value) => value.trim())
114
+ .filter(Boolean);
115
+ if (containers.length) {
116
+ runLocalCommand("docker", ["update", "--restart=no", ...containers], {
117
+ capture: true,
118
+ cwd,
119
+ });
120
+ }
121
+ return Object.freeze(containers);
122
+ };
103
123
  const withWorkdir = (args, workdir) => (workdir ? [...args, "--workdir", workdir] : [...args]);
104
124
  export const readLocalSupabaseEnvironment = ({ cwd, workdir, environment = {}, } = {}) => {
105
125
  const output = runLocalCommand("supabase", withWorkdir(["status", "-o", "env"], workdir), { capture: true, cwd, environment });
106
126
  return parseLocalSupabaseEnvironment(output);
107
127
  };
108
- export const startLocalSupabase = ({ cwd, workdir, exclude = [], environment = {}, applyMigrations = true, autoStartColima = true, } = {}) => {
128
+ export const startLocalSupabase = ({ cwd, workdir, exclude = [], environment = {}, applyMigrations = true, autoStartColima = false, projectId, } = {}) => {
109
129
  ensureLocalContainerRuntime({ cwd, autoStartColima });
110
130
  const startArguments = withWorkdir(["start", ...(exclude.length ? ["--exclude", exclude.join(",")] : [])], workdir);
111
131
  runLocalCommand("supabase", startArguments, {
@@ -113,6 +133,8 @@ export const startLocalSupabase = ({ cwd, workdir, exclude = [], environment = {
113
133
  cwd,
114
134
  environment,
115
135
  });
136
+ if (projectId)
137
+ preventOwnedSupabaseAutoRestart({ cwd, projectId });
116
138
  if (applyMigrations) {
117
139
  runLocalCommand("supabase", withWorkdir(["migration", "up", "--local"], workdir), { capture: true, cwd, environment });
118
140
  }
package/docs/README.md CHANGED
@@ -1,7 +1,14 @@
1
1
  # Rehearsal documentation
2
2
 
3
- Welcome. You do not need to read this documentation from top to bottom. Choose what you
4
- want to accomplish and follow that path.
3
+ Most migration tests start with an empty database. Production does not. Existing rows,
4
+ relationships, authentication identities, stored files, and migration history are where
5
+ risky changes break.
6
+
7
+ Rehearsal restores a reviewed, sanitized baseline into a disposable local environment,
8
+ applies only the exact migrations you approve, and runs your application's own proof.
9
+
10
+ You do not need to read this documentation from top to bottom. Choose what you want to
11
+ accomplish and follow that path.
5
12
 
6
13
  ## Start here
7
14
 
@@ -24,6 +31,7 @@ want to accomplish and follow that path.
24
31
 
25
32
  - [CLI commands](commands.md)
26
33
  - [Configuration](configuration.md)
34
+ - [Container runtime lifecycle](runtime-lifecycle.md)
27
35
  - [TypeScript](typescript.md)
28
36
  - [Runtime and identity policies](runtime-policies.md)
29
37
  - [Database adapters](adapters.md)
@@ -4,7 +4,7 @@ An ordinary npm application install creates this file in the application root wh
4
4
  root can be identified safely:
5
5
 
6
6
  ```bash
7
- npm install --save-dev @rehearsal-db/core@beta
7
+ npm install --save-dev @rehearsal-db/core
8
8
  ```
9
9
 
10
10
  The install hook detects the database type, project name, migration folder,
@@ -82,7 +82,7 @@ export default defineRehearsalConfig({
82
82
  // After setup, run: npx rehearsal identity connect
83
83
  // identityPolicy: "infrastructure/rehearsal/identity-policy.json",
84
84
  containerRuntime: {
85
- autoStartColima: true,
85
+ autoStartColima: false,
86
86
  },
87
87
  cleanup: {
88
88
  retainBaselineGenerations: 2,
@@ -227,7 +227,7 @@ SHA-256 receipts are tracked. See
227
227
 
228
228
  ```ts
229
229
  containerRuntime: {
230
- autoStartColima: true,
230
+ autoStartColima: false,
231
231
  },
232
232
  cleanup: {
233
233
  retainBaselineGenerations: 2,
@@ -235,9 +235,17 @@ cleanup: {
235
235
  ```
236
236
 
237
237
  Rehearsal uses whichever Docker-compatible engine already answers `docker info`. If none
238
- is running and `autoStartColima` is `true`, Rehearsal may run `colima start`. It respects
239
- the user's Colima CPU, memory, and disk settings and never changes them. Set the field to
240
- `false` when you prefer to start Docker or Colima yourself.
238
+ is running and `autoStartColima` is `true`, Rehearsal may run `colima start`. This is an
239
+ explicit opt-in because starting a shared Docker engine can also restart unrelated
240
+ containers whose restart policy is `always` or `unless-stopped`. Rehearsal respects the
241
+ user's Colima CPU, memory, and disk settings and never changes them. The generated default
242
+ is `false`: start Docker or Colima yourself before a mutating command. Rehearsal never
243
+ stops a shared container engine automatically.
244
+
245
+ After each Supabase start, Rehearsal changes only the exact target's containers to
246
+ Docker's `no` restart policy. Its database and Storage volumes remain intact,
247
+ `rehearsal start` can resume it, and restarting Docker does not silently wake stopped
248
+ Rehearsal stacks.
241
249
 
242
250
  `retainBaselineGenerations` controls how many immutable baseline generations survive an
243
251
  approved `rehearsal refresh` or `rehearsal cleanup`; it must be at least 1. Refresh shows
@@ -35,7 +35,7 @@ Rehearsal will use that image with downloads disabled.
35
35
  Run these commands from the directory containing your project's `package.json`:
36
36
 
37
37
  ```bash
38
- npm install --save-dev @rehearsal-db/core@beta
38
+ npm install --save-dev @rehearsal-db/core
39
39
  npx rehearsal
40
40
  ```
41
41
 
package/docs/index.md CHANGED
@@ -1,18 +1,37 @@
1
1
  # Rehearsal documentation
2
2
 
3
+ ## Why an empty database is not enough
4
+
5
+ Most migration tests start with an empty database. Production does not.
6
+
7
+ Existing rows, relationships, authentication identities, stored files, and migration
8
+ history are where risky changes break. A migration can build successfully and still fail
9
+ against the data and application behavior you actually have.
10
+
11
+ Rehearsal catches those problems before deployment. It restores a reviewed, sanitized
12
+ baseline into a disposable local PostgreSQL or Supabase environment, applies only the
13
+ exact migrations you approve, and runs your application's own proof.
14
+
15
+ | Empty-database tests miss… | Rehearsal exercises… |
16
+ | ------------------------------------------------- | --------------------------------------------------------- |
17
+ | old rows and edge cases | a reviewed, production-shaped baseline |
18
+ | relationships between data, identities, and files | database, Auth, and Storage in one local sandbox |
19
+ | whether the product still behaves correctly | your automated proof and hands-on application walkthrough |
20
+
3
21
  ## Pick the path that fits today
4
22
 
5
23
  You do not need to read everything before your first rehearsal. Start with the outcome
6
24
  you want, then follow the links when a term or safety check is new.
7
25
 
8
- | I want to… | Go here |
9
- | ------------------------------------- | ----------------------------------------------------------------- |
10
- | Set up my own project | [Getting started](getting-started.md) |
11
- | Try Rehearsal without touching my app | [Hands-on tutorial](tutorial.md) |
12
- | Understand what makes a copy safe | [Baselines](baselines.md) and [Sanitization](sanitization.md) |
13
- | Look up a command or setting | [CLI commands](commands.md) and [Configuration](configuration.md) |
14
- | Add editor and compiler type checks | [TypeScript](typescript.md) |
15
- | Fix something that did not work | [Troubleshooting](troubleshooting.md) |
26
+ | I want to… | Go here |
27
+ | --------------------------------------- | ----------------------------------------------------------------- |
28
+ | Set up my own project | [Getting started](getting-started.md) |
29
+ | Try Rehearsal without touching my app | [Hands-on tutorial](tutorial.md) |
30
+ | Understand what makes a copy safe | [Baselines](baselines.md) and [Sanitization](sanitization.md) |
31
+ | Look up a command or setting | [CLI commands](commands.md) and [Configuration](configuration.md) |
32
+ | Reduce Docker and Supabase resource use | [Container runtime lifecycle](runtime-lifecycle.md) |
33
+ | Add editor and compiler type checks | [TypeScript](typescript.md) |
34
+ | Fix something that did not work | [Troubleshooting](troubleshooting.md) |
16
35
 
17
36
  ## The short version
18
37
 
@@ -0,0 +1,99 @@
1
+ # Container runtime lifecycle
2
+
3
+ Rehearsal uses a local Docker-compatible engine for disposable PostgreSQL and Supabase
4
+ targets. It owns the targets it creates; it does not own the shared engine or another
5
+ project's containers.
6
+
7
+ ## What starts Docker?
8
+
9
+ Read-only commands such as `doctor`, `status`, `candidates`, `explain`, and `inspect` do
10
+ not start Docker. Commands that create or resume a database—such as `start`, `reset`,
11
+ `run`, and `open`—need an already-running engine.
12
+
13
+ Generated configurations keep startup explicit:
14
+
15
+ ```js
16
+ containerRuntime: {
17
+ autoStartColima: false,
18
+ },
19
+ ```
20
+
21
+ With the default, a stopped engine produces an actionable error. Start Docker Desktop,
22
+ Colima, Rancher Desktop, Podman with Docker compatibility, or another supported engine,
23
+ then repeat the command.
24
+
25
+ Setting `autoStartColima: true` is an explicit convenience opt-in. If Docker is
26
+ unavailable and the `colima` command exists, Rehearsal runs plain `colima start` and
27
+ reports it. Rehearsal does not resize Colima and does not stop the shared engine
28
+ automatically. Starting Docker can also wake unrelated containers that use Docker's
29
+ `always` or `unless-stopped` restart policy.
30
+
31
+ ## What remains after a command?
32
+
33
+ - `run` stops the application proof process but keeps the database target available for
34
+ hands-on testing.
35
+ - `open` keeps the application and databases available until the application session is
36
+ interrupted. The database target remains available afterward.
37
+ - `stop` stops every configured Rehearsal target in reverse dependency order and retains
38
+ its local data.
39
+ - `start` resumes a stopped target, reusing compatible state.
40
+ - `reset` recreates the target from the active immutable baseline.
41
+ - `discard` removes the selected disposable target. It is the data-destructive runtime
42
+ operation and retains the immutable baseline.
43
+
44
+ After Supabase starts, Rehearsal changes only containers with the exact configured
45
+ Supabase project label to Docker's `no` restart policy. This does not remove containers
46
+ or volumes. It prevents a later Docker restart from silently waking stopped Rehearsal
47
+ stacks; `rehearsal start` still resumes them normally.
48
+
49
+ ## A low-memory daily workflow
50
+
51
+ 1. Start your Docker-compatible engine.
52
+ 2. Run `rehearsal run` or `rehearsal open`.
53
+ 3. When finished, run `rehearsal stop` from the project root.
54
+ 4. Check other projects before stopping the shared engine:
55
+
56
+ ```bash
57
+ docker ps
58
+ ```
59
+
60
+ 5. If nothing else needs Docker, stop the engine using its own command, such as
61
+ `colima stop`.
62
+
63
+ Rehearsal intentionally does not infer that every running container belongs to it. It
64
+ also never runs a global Docker prune. Database and Storage volumes are not deleted by
65
+ `stop`.
66
+
67
+ ## Choosing PostgreSQL or Supabase
68
+
69
+ Use the PostgreSQL target for migration, schema, trigger, privacy, and ordinary relational
70
+ data checks that do not require Supabase services. It uses one database container.
71
+
72
+ Use the Supabase target when the proof needs Auth, Storage, PostgREST, or the local API
73
+ gateway. Rehearsal already excludes Realtime, Edge Runtime, Analytics/Logflare, and Vector
74
+ from its Supabase stack. A future service-profile feature will make additional optional
75
+ services explicit; until then, do not trade away application fidelity merely to reduce a
76
+ container count.
77
+
78
+ ## Diagnosing unexpected activity
79
+
80
+ Start with read-only checks:
81
+
82
+ ```bash
83
+ docker context show
84
+ docker ps --format 'table {{.Names}}\t{{.Status}}\t{{.Label "com.supabase.cli.project"}}'
85
+ docker stats --no-stream
86
+ colima status
87
+ ```
88
+
89
+ For each container, inspect its project ownership and restart policy before taking any
90
+ action:
91
+
92
+ ```bash
93
+ docker inspect --format '{{json .Config.Labels}} {{.HostConfig.RestartPolicy.Name}}' CONTAINER
94
+ ```
95
+
96
+ Do not remove anonymous volumes or old images based on names alone. Use `rehearsal
97
+ cleanup` for package-owned baseline retention and its reviewed, opt-in image cleanup.
98
+ Shared resource inventory and stale-environment cleanup are tracked separately; until
99
+ that lands, stopping a configured target from its own project is the safe path.
package/docs/stability.md CHANGED
@@ -26,7 +26,7 @@ file names, and undocumented package paths are not compatibility promises.
26
26
 
27
27
  ## What blocks a release candidate
28
28
 
29
- An issue blocks `0.1.0-rc.1` when it can cause any of the following within a supported
29
+ An issue blocks the active release candidate when it can cause any of the following within a supported
30
30
  configuration:
31
31
 
32
32
  - data loss, credential exposure, hosted-system access, or mutation outside resources
@@ -47,12 +47,13 @@ release.
47
47
 
48
48
  1. Ship beta.18 with only stability, release-safety, upgrade, and documentation work.
49
49
  2. Freeze broad feature development on the release branch.
50
- 3. Publish `0.1.0-rc.1` from protected `main` through the reviewed npm environment.
50
+ 3. Publish a release candidate from protected `main` through the reviewed npm environment.
51
51
  4. Run the complete Rehearsal Test Lab gate twice from clean isolated workspaces.
52
52
  5. Perform one final package-only upgrade in a real consumer. The consumer must use the
53
53
  published package rather than duplicate Rehearsal machinery.
54
- 6. Keep the candidate available for at least seven calendar days. Restart the window if
55
- a blocking package change is required.
54
+ 6. Keep the current candidate available for at least seven calendar days. Restart the
55
+ window if a blocking package change is required. The container-lifecycle correction
56
+ in `0.1.0-rc.2` restarts this observation window.
56
57
  7. Publish `0.1.0` only when no blocking issue remains and the accepted registry artifact
57
58
  matches the tested artifact exactly.
58
59
 
@@ -11,10 +11,10 @@ Doctor names each missing or unsafe item. If you still need help, run
11
11
 
12
12
  ## `npx rehearsal` cannot find the command
13
13
 
14
- Confirm you are in the project directory and install the beta locally:
14
+ Confirm you are in the project directory and install the current release locally:
15
15
 
16
16
  ```bash
17
- npm install --save-dev @rehearsal-db/core@beta
17
+ npm install --save-dev @rehearsal-db/core
18
18
  npx rehearsal --help
19
19
  ```
20
20
 
package/package.json CHANGED
@@ -1,8 +1,8 @@
1
1
  {
2
2
  "name": "@rehearsal-db/core",
3
- "version": "0.1.0-rc.1",
3
+ "version": "0.1.0-rc.2",
4
4
  "private": false,
5
- "description": "Safely rehearse PostgreSQL and Supabase migrations against sanitized, production-shaped data.",
5
+ "description": "Catch PostgreSQL and Supabase migrations that pass on empty databases but fail on real data—before deploy.",
6
6
  "repository": {
7
7
  "type": "git",
8
8
  "url": "git+https://github.com/Ddupasquier/rehearsal-db.git"