@rehearsal-db/core 1.0.0 → 1.0.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.
Files changed (48) hide show
  1. package/CHANGELOG.md +46 -1
  2. package/COMPATIBILITY.md +43 -0
  3. package/README.md +31 -12
  4. package/dist/package.json +2 -2
  5. package/dist/scripts/install/create_root_config.mjs +9 -2
  6. package/dist/src/cli/failure_output.d.mts +3 -0
  7. package/dist/src/cli/failure_output.mjs +48 -0
  8. package/dist/src/cli/rehearsal.mjs +15 -4
  9. package/dist/src/cli/runtime_action_handlers.mjs +11 -4
  10. package/dist/src/cli/runtime_commands.mjs +23 -24
  11. package/dist/src/cli/runtime_failure_summary.d.mts +1 -0
  12. package/dist/src/cli/runtime_failure_summary.mjs +30 -4
  13. package/dist/src/cli/runtime_planning.mjs +6 -0
  14. package/dist/src/project/install_scaffold.mjs +7 -0
  15. package/dist/src/project/project_discovery_metadata.mjs +9 -11
  16. package/dist/src/runtime/migration_failure.d.mts +28 -0
  17. package/dist/src/runtime/migration_failure.mjs +197 -0
  18. package/dist/src/runtime/migration_failure_source.d.mts +16 -0
  19. package/dist/src/runtime/migration_failure_source.mjs +68 -0
  20. package/dist/src/runtime/plan.mjs +26 -15
  21. package/dist/src/shared/diagnostics.mjs +5 -0
  22. package/dist/src/shared/host_platform.d.mts +16 -0
  23. package/dist/src/shared/host_platform.mjs +109 -0
  24. package/dist/src/shared/operation_guard.d.mts +4 -1
  25. package/dist/src/shared/operation_guard.mjs +18 -13
  26. package/dist/src/shared/operation_progress.mjs +35 -1
  27. package/dist/src/shared/operation_progress_storage.d.mts +27 -6
  28. package/dist/src/shared/operation_progress_storage.mjs +65 -9
  29. package/dist/src/shared/process_environment.d.mts +2 -1
  30. package/dist/src/shared/process_environment.mjs +47 -5
  31. package/dist/src/targets/port_start_failure.d.mts +15 -0
  32. package/dist/src/targets/port_start_failure.mjs +46 -0
  33. package/dist/src/targets/postgresql.mjs +8 -7
  34. package/dist/src/targets/postgresql_process.d.mts +8 -1
  35. package/dist/src/targets/postgresql_process.mjs +46 -2
  36. package/dist/src/targets/supabase_process.mjs +2 -1
  37. package/dist/src/targets/supabase_start_failure.mjs +5 -1
  38. package/docs/architecture.md +32 -2
  39. package/docs/commands.md +35 -0
  40. package/docs/getting-started.md +48 -0
  41. package/docs/index.md +15 -9
  42. package/docs/releasing.md +28 -24
  43. package/docs/roadmap.md +8 -3
  44. package/docs/stability.md +8 -4
  45. package/docs/troubleshooting.md +54 -2
  46. package/docs/tutorial.md +93 -8
  47. package/docs/vscode.md +220 -37
  48. package/package.json +2 -2
@@ -70,6 +70,24 @@ typed registry and produce the same result contract:
70
70
  Command handlers receive an explicit context containing parsed flags, selected config,
71
71
  guided state, and session-local caches. They return a rendered, text, or silent result;
72
72
  only the shared output boundary creates JSON envelopes or writes final human output.
73
+ `runtime/migration_failure.mts` owns bounded provider-envelope SQLSTATE recognition,
74
+ fixed classification/remediation and closed safe diagnostic validation. Target drivers
75
+ never forward SQL or provider error details. The manager summary reconstructs that
76
+ fixed diagnostic across the child-process boundary; CLI JSON and private operation
77
+ history expose the same projection. Activity adds a separate `recentFailures` list,
78
+ leaving existing strict progress/recent receipt shapes unchanged for old clients.
79
+ The optional `source` projection is owned by `runtime/migration_failure_source.mts`.
80
+ For individually dispatched PostgreSQL files, it identifies the attempted execution
81
+ input by its reviewed filename, exact SHA-256 and baseline/candidate kind. The driver
82
+ hashes the bytes it loads before dispatch; changed reviewed bytes refuse execution.
83
+ Only a safe project-relative candidate path may be included, never an absolute path;
84
+ baseline inputs keep that path null. This is not attribution of the failing SQL's actual
85
+ origin: included scripts, functions and triggers can fail elsewhere. SQL line and column
86
+ remain null. Supabase batch execution currently supplies no file attribution, and
87
+ ambiguous or unavailable evidence is not inferred from candidate count or provider text.
88
+ `cli/failure_output.mts` preserves the outer category and cleanup warning when a
89
+ stack failure wraps the original migration error. It projects only a validated fixed
90
+ diagnosis from at most four original-error wrappers, never cleanup siblings or causes.
73
91
  Session caches never appear in the public parsed-flags type.
74
92
  Owned child output has a byte boundary. If a process floods it, Rehearsal sends TERM
75
93
  and forcibly reaps only that owned process group after one second; a child ignoring
@@ -129,14 +147,18 @@ Each scenario remains independently runnable through its `test:fixture:*` script
129
147
  complete release gate runs every catalog entry against the same immutable tarball and
130
148
  writes its version, SHA-256, tool environment, commands, timings, and results under
131
149
  `test-results/release-gate/`.
150
+ The existing Supabase scenario includes native syntax and populated-row constraint
151
+ failures, fixed public error/history diagnostics, reviewed corrections and independent
152
+ data/Storage preservation checks. It does not infer a rollback from a failed migration.
132
153
 
133
154
  ## Runtime lifecycle
134
155
 
135
156
  `runtime/lifecycle_engine.mts` owns the target-neutral lifecycle contract. Both
136
157
  PostgreSQL and Supabase use it to dispatch commands, verify active baseline inputs,
137
158
  calculate and confirm the exact migration set, write target-bound receipts, validate
138
- runtime markers, and roll back a failed reset or migration without hiding the original
139
- failure.
159
+ runtime markers, and attempt owned failure cleanup without hiding the original error.
160
+ That cleanup can remove the disposable runtime; a failure message does not establish a
161
+ SQL transaction rollback, restoration of sandbox edits, or successful resource removal.
140
162
 
141
163
  The files in `src/targets/` remain drivers. They prove ownership before deleting local
142
164
  resources and implement only the behavior that genuinely differs: Docker PostgreSQL
@@ -144,6 +166,14 @@ containers and SQL setup on one side; Supabase CLI, Auth, Storage, and generated
144
166
  on the other. An ordinary `stop` never enters rollback or discard, so later `start`
145
167
  preserves the sandbox database and Storage contents.
146
168
 
169
+ CLI command completion and database lifecycle are separate. A successful `run` can finish
170
+ and release its project lock while the configured keep-until-stop database remains
171
+ running. The project-owned CLI proof has its own primary `application-proof` stage;
172
+ HTTP readiness is optional and is not a prerequisite for a database-only proof. Public
173
+ operation receipts record those past stages, not fresh proof of subsequently changed
174
+ configuration, baseline or migration bytes. Editor presentation consumes that evidence
175
+ without interpreting database liveness as an active command or successful proof.
176
+
147
177
  Repository contracts keep each target driver at 900 lines or fewer and the shared
148
178
  lifecycle engine at 300 lines or fewer. A new database target must use this lifecycle
149
179
  boundary rather than copying an existing driver's orchestration.
package/docs/commands.md CHANGED
@@ -238,6 +238,41 @@ provides a stable category, code, safe message, suggestions, diagnostic ID, and
238
238
  context under `error`. Callers should use the category and code for decisions and show
239
239
  the message and suggestions to people.
240
240
 
241
+ Failed migration execution additionally supplies `error.context.migrationFailure`:
242
+ schema version `1`, provider (`postgresql` or `supabase`), classification (`syntax`,
243
+ `schema`, `constraint`, `permission`, `connectivity`, `timeout_or_cancel`, or `unknown`),
244
+ nullable `sqlState`, evidence (`provider_sqlstate`, `unavailable`, or `ambiguous`),
245
+ fixed `summary` and fixed `suggestions`. Classification uses recognized native SQLSTATE
246
+ envelopes, never SQL-text guessing. Unknown evidence does not establish syntax failure.
247
+ Direct manager failures separately name the target in `error.context.target`; raw
248
+ SQL, row values, provider DETAIL, absolute paths and connection strings are not
249
+ included. Optional attempted-input metadata is described below; it does not locate
250
+ the failing SQL statement. Existing exit codes and `MANAGER_RUN_FAILED` / `MANAGER_MIGRATE_FAILED`
251
+ codes are unchanged. If cleanup also fails, the outer failure keeps its existing
252
+ category, exit and cleanup warning while retaining the original fixed migration
253
+ diagnosis. A diagnosis is not borrowed from a cleanup error, and is not evidence that
254
+ cleanup completed.
255
+
256
+ When PostgreSQL submits one known migration file, the diagnostic may include a closed
257
+ `source` object: schema version `1`, `kind` (`baseline` or `candidate`), `filename`,
258
+ `sha256`, nullable `workspaceRelativePath`, `line: null`, `column: null`, and
259
+ `evidence: "owned_execution_input"`. The loaded bytes must match the reviewed hash.
260
+ This identifies the attempted input, not the exact origin of failing SQL; statements,
261
+ functions and included files can fail elsewhere. No statement counting, provider caret,
262
+ or batch candidate count is converted into a source position. Baseline snapshot paths
263
+ are not exposed; unavailable or ambiguous attribution is omitted, including the
264
+ current Supabase batch path. The editor opens a project-local input only after fresh
265
+ containment, regular-file, identity and exact-byte checks; a changed file needs manual
266
+ review instead of a stale link.
267
+
268
+ `activity --json` may also provide `data.recentFailures`: up to 20 entries with
269
+ `operationId` and the same `diagnostic`, joined to a failed receipt in `data.recent`.
270
+ Missing means an older producer; `null` means private history is unavailable; `[]`
271
+ means no retained migration diagnosis. These are recent observations, not current
272
+ runtime verification. Existing `recent[]` and progress object fields are unchanged,
273
+ so older clients can ignore the new top-level projection. The local owner-only history
274
+ stores only this fixed safe projection, not arbitrary errors or terminal output.
275
+
241
276
  Invalid positive-integer settings and rejected proposal structure or fields use
242
277
  `configuration_invalid` with code `CONFIGURATION_INVALID` (exit `2`), including
243
278
  baseline-retention settings and fields that require manual review. They are not
@@ -5,6 +5,54 @@ your computer. Normal setup and rehearsal commands never connect to a hosted dat
5
5
 
6
6
  Want to experiment first? Use the [safe hands-on tutorial](tutorial.md).
7
7
 
8
+ ## OS-specific setup files (optional)
9
+
10
+ Separate setup folders are available for
11
+ [Windows / WSL 2](https://github.com/Ddupasquier/rehearsal-db/tree/main/installers/windows),
12
+ [macOS](https://github.com/Ddupasquier/rehearsal-db/tree/main/installers/macos) and
13
+ [Linux](https://github.com/Ddupasquier/rehearsal-db/tree/main/installers/linux).
14
+ They are readable helpers, not native executables or bundled Node/Docker installers.
15
+ Existing Node.js 24 or 26 is required. The default only checks an existing project;
16
+ installation needs an explicit option and does not start a database. Review the
17
+ [shared behavior and release availability](https://github.com/Ddupasquier/rehearsal-db/blob/main/installers/README.md)
18
+ before choosing an install option. An exact core 1.0.2 install requires that version to
19
+ be published; a checked-in helper is not proof of publication.
20
+
21
+ ### Windows: use a WSL 2 Linux workspace
22
+
23
+ The Windows compatibility route is Linux execution inside **WSL 2**, not a native
24
+ PowerShell/Command Prompt database runtime. Core 1.0.1 and extension 0.1.21 make that
25
+ boundary explicit; native Windows version/help/discovery do not authorize runtime work.
26
+
27
+ 1. Follow Microsoft's [WSL installation guide](https://learn.microsoft.com/en-us/windows/wsl/install)
28
+ to prepare a WSL 2 Linux distribution, such as Ubuntu 24.04. Do not use WSL 1.
29
+ 2. Clone or open the project inside the distribution's Linux home directory, such as
30
+ `/home/your-name/projects/app`. Do not keep the runtime project under `/mnt/c`, a
31
+ Windows share or a Windows-mounted drive. Rehearsal does not relocate your files.
32
+ 3. Install a supported **Linux** Node/npm and a Docker-compatible Linux engine in that
33
+ environment. Docker Engine in WSL or an already configured Docker Desktop WSL
34
+ integration are user-controlled setup choices; Rehearsal does not install or license
35
+ Docker Desktop for you. In the Linux terminal, check:
36
+
37
+ ```bash
38
+ node -p "process.platform"
39
+ pwd
40
+ docker info --format '{{.OSType}}'
41
+ ```
42
+
43
+ Both platform results must be `linux`, and `pwd` must be in the Linux filesystem.
44
+
45
+ 4. For editor use, install Microsoft's **WSL** extension, then run `code .` from that
46
+ Linux project directory. Confirm the VS Code window says **WSL** in its remote
47
+ indicator, and install Rehearsal into **WSL**, not only the Windows-side extension host.
48
+ 5. Continue below from that Linux terminal. Keep the existing baseline, approval and
49
+ local-only checks; do not substitute a hosted database to make setup pass.
50
+
51
+ WSL is a compatibility preview. A real WSL PostgreSQL fixture and a native Remote-WSL
52
+ editor walkthrough are different evidence; do not infer the latter from Linux unit
53
+ tests. Supabase/Auth/Storage in WSL and other remote hosts remain unclaimed until their
54
+ own checks pass. See the [complete platform boundary](https://github.com/Ddupasquier/rehearsal-db/blob/main/COMPATIBILITY.md#operating-systems-and-execution-location).
55
+
8
56
  ## 1. Check the required tools
9
57
 
10
58
  You need Node.js 22, 24, or 26, npm, and a running Docker-compatible engine. Node.js 24
package/docs/index.md CHANGED
@@ -12,6 +12,11 @@ Rehearsal catches those problems before deployment. It restores a reviewed, sani
12
12
  baseline into a disposable local PostgreSQL or Supabase environment, applies only the
13
13
  exact migrations you approve, and runs your application's own proof.
14
14
 
15
+ The [CLI is free and MIT-licensed](https://www.npmjs.com/package/@rehearsal-db/core).
16
+ Prefer clicks to commands? [Install the free VS Code Starter preview](vscode.md).
17
+ All features included in its Starter-licensed releases are free indefinitely, with no
18
+ account, payment card, or trial period.
19
+
15
20
  | Empty-database tests miss… | Rehearsal exercises… |
16
21
  | ------------------------------------------------- | --------------------------------------------------------- |
17
22
  | old rows and edge cases | a reviewed, production-shaped baseline |
@@ -23,15 +28,16 @@ exact migrations you approve, and runs your application's own proof.
23
28
  You do not need to read everything before your first rehearsal. Start with the outcome
24
29
  you want, then follow the links when a term or safety check is new.
25
30
 
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) |
31
+ | I want to… | Go here |
32
+ | ---------------------------------------- | ----------------------------------------------------------------- |
33
+ | Set up my own project | [Getting started](getting-started.md) |
34
+ | Use the free visual workbench in VS Code | [Install VS Code Starter](vscode.md) |
35
+ | Try Rehearsal without touching my app | [Hands-on tutorial](tutorial.md) |
36
+ | Understand what makes a copy safe | [Baselines](baselines.md) and [Sanitization](sanitization.md) |
37
+ | Look up a command or setting | [CLI commands](commands.md) and [Configuration](configuration.md) |
38
+ | Reduce Docker and Supabase resource use | [Container runtime lifecycle](runtime-lifecycle.md) |
39
+ | Add editor and compiler type checks | [TypeScript](typescript.md) |
40
+ | Fix something that did not work | [Troubleshooting](troubleshooting.md) |
35
41
 
36
42
  ## The short version
37
43
 
package/docs/releasing.md CHANGED
@@ -95,23 +95,27 @@ than seven days or in the future. Public fields and timestamps must still match
95
95
  bypass metadata is hidden; an explicitly malformed or nonempty bypass list always
96
96
  refuses publication.
97
97
 
98
- The prepare job prints an exact approval comment in its summary. Independently check
99
- the live no-bypass settings and accepted artifact checksum, then paste the comment into
100
- **Review deployments → npm** and approve manually. Before publishing or repairing
101
- tags, the workflow reads GitHub's actual approval history and requires the configured
102
- owner's authenticated review for that npm environment. The comment binds the operation,
103
- run ID, run attempt, source commit, artifact SHA-256 and settings-record SHA-256.
104
- GitHub may store the form's line breaks as CRLF instead of LF. The checker treats
105
- those two encodings as equivalent; it does not trim whitespace or change any field.
106
- An approval copied from another artifact, run or attempt is refused. Rerun the whole
107
- workflow after failure so preparation prints a new attempt-bound comment; do not reuse
108
- an earlier comment when rerunning only the mutation job.
109
-
110
- The record alone is never authorization. This mechanism relies on the owner's fresh
111
- settings review and GitHub's reported timestamps; timestamps are not cryptographic
112
- proof of every hidden setting change. No settings check eliminates a subsequent
113
- administrator change or check-to-use race. Keep the npm environment's no-bypass human
114
- gate enforced. See [GitHub's ruleset metadata boundary](https://docs.github.com/en/rest/repos/rules#get-a-repository-ruleset)
98
+ The prepare job displays the exact package version, SHA-256, source commit and run
99
+ in its summary. Review the candidate and passed checks, then choose **Review
100
+ deployments → npm → Approve and deploy**. That ordinary GitHub approval is the
101
+ publication authorization: no separate chat approval, secret phrase or pasted block
102
+ is required. Comments are optional.
103
+
104
+ GitHub's enforced, no-bypass `npm` environment admits the publishing job only after
105
+ its protection rules pass. The workflow also reads this run's actual review history
106
+ to corroborate the configured human owner's approval for the exact npm environment.
107
+ That history does not identify an approval's run attempt or verify artifact bytes;
108
+ the workflow independently checks the prepared tarball's hashes before publication,
109
+ and freshly downloads/checks registry bytes before tag repair. Reruns keep the same
110
+ source/ref and remain subject to GitHub's environment controls; old review text is
111
+ never presented as proof of new bytes or a fresh attempt.
112
+
113
+ The unsigned settings record remains a bounded drift check, not authorization or
114
+ cryptographic proof of current hidden bypass settings. Refresh its owner observation
115
+ when stale or changed; never advance its timestamp without reading the settings.
116
+ No settings check eliminates a later administrator change or check-to-use race.
117
+ See [GitHub's deployment review](https://docs.github.com/en/actions/how-tos/deploy/configure-and-manage-deployments/review-deployments),
118
+ [ruleset metadata boundary](https://docs.github.com/en/rest/repos/rules#get-a-repository-ruleset)
115
119
  and [workflow approval history](https://docs.github.com/en/rest/actions/workflow-runs#get-the-review-history-for-a-workflow-run).
116
120
 
117
121
  Keep customer evidence, credentials, runtime data and the internal tracker out of public
@@ -137,11 +141,12 @@ release-source migration.
137
141
  5. Change `private` to `false` only in the reviewed release change.
138
142
  6. Record the exact tarball filename, SHA-1, SHA-256, allowlisted files, unpacked size,
139
143
  executable, declared runtime dependency inventory, and dependency audit result.
140
- 7. Obtain explicit publication authorization for that exact version and artifact.
141
- 8. Merge the approved release commit through protected `main` and create the exact
144
+ 7. Review the release change and its exact artifact evidence.
145
+ 8. Merge the reviewed release commit through protected `main` and create the exact
142
146
  `v<package-version>` tag and GitHub release.
143
- 9. Review and approve the protected `npm` deployment only after its prepare job matches
144
- the approved version and checksum, using its exact approval comment.
147
+ 9. Authorize publication once, in the protected `npm` deployment review, after its
148
+ prepare job matches the tested version and checksum. No comment or chat approval
149
+ is required.
145
150
  10. Verify public visibility, ownership, provenance, registry SHA-1, README rendering,
146
151
  exact-version clean installation, CLI execution, signatures, and the unrelated
147
152
  installed Docker fixture. Allow up to six minutes for a first package to propagate
@@ -199,6 +204,5 @@ package or select a different version. The `npm` environment must supply the ver
199
204
  human approval gate; a workflow reference to that environment is not sufficient.
200
205
 
201
206
  Creating the repository, passing CI, extracting the engine, merging a release branch,
202
- or creating a tag does not authorize npm publication. Publication requires explicit
203
- authorization for the exact packed artifact, and the protected GitHub environment
204
- supplies the final human gate.
207
+ or creating a tag does not authorize npm publication. The protected GitHub deployment
208
+ review supplies the single human authorization for the exact displayed artifact.
package/docs/roadmap.md CHANGED
@@ -1,8 +1,13 @@
1
1
  # Next steps
2
2
 
3
- Rehearsal supports guided Supabase and ordinary PostgreSQL migration rehearsals. The
4
- current development track removes the need for consumer-owned Rehearsal engines while
5
- keeping application meaning and privacy decisions project-owned.
3
+ Rehearsal core **1.0.0 is available on
4
+ [npm](https://www.npmjs.com/package/@rehearsal-db/core)** for guided Supabase and
5
+ ordinary PostgreSQL migration rehearsals. The [free VS Code Starter preview](vscode.md)
6
+ adds a visual workbench. Neither requires a purchase or account.
7
+
8
+ The standalone workflow keeps the rehearsal engine in the package while application
9
+ meaning and privacy decisions remain project-owned. The sequence below explains its
10
+ dependencies, not a list of features withheld from the published release.
6
11
 
7
12
  ## Standalone workflow
8
13
 
package/docs/stability.md CHANGED
@@ -1,7 +1,10 @@
1
1
  # Stability and the first stable release
2
2
 
3
- Rehearsal leaves beta when the workflow it already promises is dependable. Stable
4
- `1.0.0` does not require every planned database, desktop interface, or paid feature.
3
+ Rehearsal core **1.0.0 is published** on
4
+ [npm](https://www.npmjs.com/package/@rehearsal-db/core). This page defines its
5
+ compatibility promise and the verification policy for releases; it is not an
6
+ unfinished launch checklist. Stable core does not require every planned database,
7
+ editor interface, or paid feature.
5
8
 
6
9
  ## What becomes a compatibility promise
7
10
 
@@ -63,8 +66,9 @@ ready. The sequence below is policy, not a claim that its checks have passed.
63
66
  do not relabel old or unavailable manual checks as new results. No minimum number
64
67
  of calendar days replaces these checks.
65
68
  6. Publish `1.0.0` only when no blocking issue remains and the exact tarball has passed
66
- the required release checks, consumer acceptance, exact-artifact authorization and
67
- protected human publication approval.
69
+ the required release checks and consumer acceptance. The protected GitHub npm
70
+ review is the single human authorization for its displayed exact version and
71
+ checksum; no separate chat approval or pasted phrase is required.
68
72
  7. Independently verify registry bytes, provenance, signatures and channels, then
69
73
  confirm the published package in the real consumer. Promotion is complete only
70
74
  when the published artifact matches the tested tarball and these checks pass.
@@ -68,7 +68,9 @@ owner-only startup receipt. This cannot stop a manually started engine.
68
68
  When a container stays in `starting` or becomes `unhealthy`, Rehearsal reports a runtime
69
69
  dependency failure rather than a migration failure. The safe diagnostic includes Docker
70
70
  CPU, memory, and container counts; Colima also includes available VM memory when it can
71
- be read. Stop unrelated local stacks or increase the engine's resources before retrying.
71
+ be read. These measurements alone do not establish a capacity problem. Review the
72
+ reported startup evidence first; for a proven resource shortage, stop only stacks you
73
+ own or increase the engine's resources before retrying.
72
74
  Rehearsal never changes engine settings or bypasses service health checks.
73
75
 
74
76
  Supabase startup failures retain a bounded summary of recognized provider evidence,
@@ -135,7 +137,7 @@ docker pull postgres:17-alpine
135
137
  npx rehearsal doctor
136
138
  ```
137
139
 
138
- ## A port is already in use
140
+ ## A port is already in use or cannot be bound
139
141
 
140
142
  Rerun `rehearsal setup` to select a different available block. Setup checks both active
141
143
  listeners and whether every selected port can be bound, then checks again before writing.
@@ -143,6 +145,56 @@ For an existing configuration, choose unique non-privileged ports and mirror the
143
145
  dedicated Supabase config when using Supabase. Do not stop an unrelated database to make
144
146
  defaults fit.
145
147
 
148
+ `port_in_use` reports an occupied bind; `port_unavailable` reports a denied or
149
+ unavailable bind. Neither proves a memory shortage. On Windows/WSL, an excluded TCP
150
+ range or host access policy can prevent binding even when no listener is visible.
151
+ In **Windows PowerShell**, inspect the host without changing it:
152
+
153
+ ```powershell
154
+ netsh interface ipv4 show excludedportrange protocol=tcp
155
+ ```
156
+
157
+ If the configured port (for example the tutorial's `59422`) is excluded, select a
158
+ different available port outside those ranges. For PostgreSQL, review
159
+ `runtime.databasePort` in `rehearsal.config.mjs`. For Supabase, review the configured
160
+ runtime ports and matching dedicated Supabase configuration together. Keep loopback
161
+ binding. Do not delete reservations, disable host security, prune resources or stop
162
+ someone else's listener to make the default work. Access-denied output is evidence
163
+ of a bind problem, not proof of a particular Windows reservation.
164
+
165
+ Microsoft documents the [read-only excluded-port command](https://learn.microsoft.com/en-us/windows-server/administration/windows-commands/netsh-interface).
166
+ Windows database execution still uses the [WSL 2 compatibility preview](../COMPATIBILITY.md#operating-systems-and-execution-location), not native Windows database support.
167
+
168
+ ## A candidate migration failed, but SQL and provider output are withheld
169
+
170
+ Rehearsal keeps SQL, row values, constraint names and raw provider output private.
171
+ When the provider supplies a recognized SQLSTATE envelope, it reports that code plus
172
+ a fixed explanation and next step. PostgreSQL codes are
173
+ [provider-defined conditions](https://www.postgresql.org/docs/17/errcodes-appendix.html),
174
+ not guesses from the SQL text:
175
+
176
+ | Code | Meaning | Next step |
177
+ | ----------------- | ---------------------- | ----------------------------------------------------------------------------------------- |
178
+ | `42601` | SQL syntax error | Review malformed statements and punctuation. |
179
+ | `23502` | NOT NULL violation | Review NULL values and backfill before enforcing the requirement. |
180
+ | `23503` | Foreign-key violation | Review missing referenced rows and migration ordering. |
181
+ | `23505` | Uniqueness violation | Review duplicates before enforcing uniqueness. |
182
+ | `23514` | CHECK violation | Existing or newly written rows do not satisfy the constraint; review/backfill them. |
183
+ | `42P01` / `42703` | Missing table / column | Review schema qualification and migration ordering; this is not a confirmed syntax error. |
184
+
185
+ Unknown, unsupported, oversized or conflicting evidence remains explicitly unknown;
186
+ it must not be labeled a syntax error from wording alone. JSON failures include the
187
+ versioned `error.context.migrationFailure` projection with provider, classification,
188
+ SQLSTATE, evidence, fixed summary and suggestions. PostgreSQL may identify its exact
189
+ attempted input file, not the actual origin of the failing SQL or a line/column location.
190
+ No automatic rewrite, retry, reset or hosted connection follows a diagnosis.
191
+
192
+ Inspect `rehearsal status` after failure. Owned runtime cleanup and baseline preservation
193
+ are separate facts; a failed operation does not prove SQL rollback or preservation of
194
+ your disposable sandbox edits. A warning that cleanup could not be confirmed requires
195
+ review before retrying. Follow the [break-and-fix tutorial](tutorial.md#5-break-a-migration-on-existing-data)
196
+ to practice safely on synthetic data.
197
+
146
198
  ## Baseline checksum mismatch
147
199
 
148
200
  Do not edit the checksum or manifest. The artifact is no longer the reviewed input.
package/docs/tutorial.md CHANGED
@@ -3,7 +3,7 @@
3
3
  This tutorial runs a complete PostgreSQL rehearsal in a temporary fictional project. It
4
4
  does not use your application, production data, or a hosted database.
5
5
 
6
- Allow about five minutes after downloading the database image. You need Git, Node.js 22,
6
+ Allow about ten minutes after downloading the database image. You need Git, Node.js 22,
7
7
  24, or 26, npm, and a running Docker-compatible engine. Node.js 24 LTS is recommended.
8
8
 
9
9
  ## 1. Prepare Rehearsal
@@ -36,9 +36,14 @@ rehearsal_repo=$PWD
36
36
  tutorial_dir=$(mktemp -d)
37
37
  cp -R tests/fixtures/postgresql-project "$tutorial_dir/app"
38
38
  cd "$tutorial_dir/app"
39
- npm install --ignore-scripts --no-save "$rehearsal_repo"
39
+ npm install --ignore-scripts --no-save --install-links "$rehearsal_repo"
40
40
  ```
41
41
 
42
+ `--install-links` installs a local package copy in this temporary project instead of
43
+ linking to the separate source checkout. Both the CLI and VS Code can use this copy;
44
+ the extension deliberately refuses a package that resolves outside the project or its
45
+ containing Git repository. Installation does not start or change a database.
46
+
42
47
  The temporary project contains:
43
48
 
44
49
  - one historical migration that creates a `widgets` table;
@@ -51,6 +56,12 @@ The fixture uses runtime ID `rehearsal-postgresql-fixture` and PostgreSQL port `
51
56
  Run only one copy at a time, or choose a distinct `runtime.projectId` and free
52
57
  `runtime.databasePort` in `rehearsal.config.mjs` before continuing. Rehearsal will not
53
58
  replace another listener.
59
+ On Windows, run this tutorial inside WSL 2 on its Linux filesystem, with Linux Node
60
+ and Docker integration enabled. A Windows-excluded port can fail even without a
61
+ listener. If `59422` cannot be bound, inspect the Windows host's excluded TCP ranges
62
+ with `netsh interface ipv4 show excludedportrange protocol=tcp` in PowerShell,
63
+ then choose a different available `runtime.databasePort` before starting. Do not remove
64
+ reservations or stop unrelated services. See [port troubleshooting](troubleshooting.md#a-port-is-already-in-use-or-cannot-be-bound).
54
65
  This is a database-only example, not a full application with a browser interface.
55
66
 
56
67
  ## 3. Create the baseline
@@ -77,10 +88,84 @@ Choose **Run a rehearsal**. The guide should show exactly one candidate:
77
88
  Confirm it. Rehearsal creates a loopback-only PostgreSQL container, restores the baseline,
78
89
  applies the candidate, and runs the fixture proof.
79
90
 
80
- Success ends with an application-proof message and suggests exercising the local
81
- application before verification.
91
+ Success ends with the fixture's project-proof message. Here, the configured proof
92
+ checks the migrated database; it does not start a browser application. The rehearsal
93
+ command has finished even though its database can remain running. Continue with the
94
+ deliberate failure below, or use `rehearsal verify` to check the runtime.
95
+
96
+ ## 5. Break a migration on existing data
97
+
98
+ This is the useful failure: the SQL is valid, but the synthetic row's new `description`
99
+ is NULL. Making that column required would work on an empty table and fail on this row.
100
+
101
+ Exit the guide. From the temporary app directory, copy the deliberately unsafe example
102
+ into a **new, unapplied** candidate:
103
+
104
+ ```bash
105
+ cp demo/require-description.sql database/migrations/20260101000200_require_widget_description.sql
106
+ npx --no-install rehearsal
107
+ ```
108
+
109
+ Choose **Run a rehearsal** again. Review the two candidates, including the new
110
+ `20260101000200_require_widget_description.sql`, and confirm the exact plan.
111
+ The expected result is a failure, not a successful rehearsal:
112
+
113
+ ```text
114
+ Migration SQLSTATE: 23502.
115
+ Rows do not satisfy a NOT NULL requirement.
116
+ ```
117
+
118
+ The safe explanation recommends reviewing NULL values and backfilling incompatible
119
+ rows. SQL and provider row details remain private. A constraint failure is **not** a
120
+ syntax error: PostgreSQL reported that the data violates the requirement.
121
+
122
+ Rehearsal must not report the failed runtime as trusted. Its owned failure cleanup may
123
+ remove the disposable runtime; a cleanup warning means resources may remain. The
124
+ immutable baseline remains available. Do not infer a transaction rollback or preserved
125
+ sandbox edits from a failure message alone. No production database is involved.
126
+
127
+ ## 6. Fix it, review again, and pass
128
+
129
+ Exit the guide. Replace **only this new, never-successfully-applied tutorial candidate**
130
+ with its data-preserving fix:
131
+
132
+ ```bash
133
+ cp demo/backfill-and-require-description.sql database/migrations/20260101000200_require_widget_description.sql
134
+ npx --no-install rehearsal
135
+ ```
136
+
137
+ The fix first fills missing descriptions with a synthetic value, then enforces NOT NULL.
138
+ Choose **Run a rehearsal**, review the changed candidate and its **new digest**, and
139
+ confirm again. Rehearsal restores the same baseline and applies the corrected plan.
140
+ The application proof should now pass. Do not reuse an earlier confirmation or alter a
141
+ historical migration that was already deployed; real deployed history needs a forward
142
+ migration instead.
143
+
144
+ ## 7. Continue in VS Code, or verify from the terminal
145
+
146
+ To continue in the editor, leave the guide, open this temporary `app` folder in VS Code,
147
+ and install [Rehearsal DB](vscode.md). On Windows, open the folder through **Remote -
148
+ WSL**, not in a native Windows extension host. Trust only this project after reviewing
149
+ its files, then choose **Rehearsal: Open Dashboard**. Refresh if the dashboard was
150
+ already open. Opening or refreshing the dashboard performs read-only inspection; it
151
+ does not rerun the rehearsal or reset its database.
152
+
153
+ If an earlier tutorial install reports that the package resolves outside its repository,
154
+ run the following from the same temporary `app` directory, using the source checkout
155
+ you built in step 1, then refresh the dashboard:
156
+
157
+ ```bash
158
+ npm install --ignore-scripts --no-save --install-links "$rehearsal_repo"
159
+ ```
160
+
161
+ This replaces the external package link with a project-local copy. Do not edit
162
+ Rehearsal's manifest or CLI paths to bypass the check. The baseline, project
163
+ configuration, privacy key and database do not need to be reset. If the original shell
164
+ was closed, set `rehearsal_repo` to the absolute path of that reviewed source checkout
165
+ first. A copy does not track later source edits; rebuild and explicitly reinstall it
166
+ when testing a changed checkout.
82
167
 
83
- ## 5. Try the runtime commands
168
+ ## 8. Verify and clean up
84
169
 
85
170
  Exit the guide, then run:
86
171
 
@@ -97,9 +182,9 @@ directory remains on disk and can be deleted when you no longer need it.
97
182
 
98
183
  ## What you proved
99
184
 
100
- You used the same packaged CLI a normal project installs. Rehearsal verified the baseline,
101
- approved an exact migration, ran it in a disposable database, tested the result, and
102
- cleaned up only its own runtime.
185
+ You saw valid SQL fail against existing data, used a safe database explanation to fix
186
+ the unapplied migration, reviewed the changed plan, and proved the correction against
187
+ the same baseline. Rehearsal verified the result and cleaned up only its own runtime.
103
188
 
104
189
  Next, follow [Getting started](getting-started.md) in your own project. Start with synthetic
105
190
  rows until the workflow and application proof are reliable.