@rehearsal-db/core 1.0.1 → 1.1.0

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 (56) hide show
  1. package/CHANGELOG.md +62 -3
  2. package/COMPATIBILITY.md +10 -4
  3. package/README.md +2 -2
  4. package/dist/package.json +1 -1
  5. package/dist/src/cli/failure_output.d.mts +3 -0
  6. package/dist/src/cli/failure_output.mjs +48 -0
  7. package/dist/src/cli/rehearsal.mjs +3 -2
  8. package/dist/src/cli/runtime_action_handlers.mjs +11 -4
  9. package/dist/src/cli/runtime_commands.mjs +21 -7
  10. package/dist/src/cli/runtime_failure_summary.d.mts +1 -0
  11. package/dist/src/cli/runtime_failure_summary.mjs +30 -4
  12. package/dist/src/project/configuration_contract.d.mts +1 -0
  13. package/dist/src/project/configuration_normalization.mjs +2 -1
  14. package/dist/src/project/configuration_rendering.mjs +3 -2
  15. package/dist/src/project/configuration_resolution.mjs +0 -2
  16. package/dist/src/project/project_detection.d.mts +2 -0
  17. package/dist/src/project/project_detection.mjs +1 -0
  18. package/dist/src/project/runtime_project_identity.d.mts +5 -0
  19. package/dist/src/project/runtime_project_identity.mjs +41 -0
  20. package/dist/src/project/setup.mjs +3 -1
  21. package/dist/src/runtime/migration_failure.d.mts +28 -0
  22. package/dist/src/runtime/migration_failure.mjs +197 -0
  23. package/dist/src/runtime/migration_failure_source.d.mts +16 -0
  24. package/dist/src/runtime/migration_failure_source.mjs +68 -0
  25. package/dist/src/runtime/policy.d.mts +2 -0
  26. package/dist/src/runtime/policy.mjs +13 -1
  27. package/dist/src/runtime/privileges.d.mts +25 -0
  28. package/dist/src/runtime/privileges.mjs +198 -0
  29. package/dist/src/shared/diagnostics.mjs +5 -0
  30. package/dist/src/shared/operation_guard.d.mts +4 -1
  31. package/dist/src/shared/operation_guard.mjs +18 -13
  32. package/dist/src/shared/operation_progress.mjs +35 -1
  33. package/dist/src/shared/operation_progress_storage.d.mts +27 -6
  34. package/dist/src/shared/operation_progress_storage.mjs +65 -9
  35. package/dist/src/targets/port_start_failure.d.mts +15 -0
  36. package/dist/src/targets/port_start_failure.mjs +46 -0
  37. package/dist/src/targets/postgresql.mjs +8 -7
  38. package/dist/src/targets/postgresql_process.d.mts +8 -1
  39. package/dist/src/targets/postgresql_process.mjs +46 -2
  40. package/dist/src/targets/supabase.mjs +1 -0
  41. package/dist/src/targets/supabase_process.mjs +2 -1
  42. package/dist/src/targets/supabase_start_failure.mjs +5 -1
  43. package/docs/README.md +1 -1
  44. package/docs/architecture.md +32 -2
  45. package/docs/commands.md +35 -0
  46. package/docs/configuration.md +19 -4
  47. package/docs/getting-started.md +4 -4
  48. package/docs/releasing.md +4 -2
  49. package/docs/roadmap.md +30 -9
  50. package/docs/runtime-lifecycle.md +5 -4
  51. package/docs/runtime-policies.md +145 -0
  52. package/docs/stability.md +8 -4
  53. package/docs/troubleshooting.md +54 -2
  54. package/docs/tutorial.md +93 -8
  55. package/docs/vscode.md +48 -18
  56. package/package.json +1 -1
@@ -1,4 +1,5 @@
1
1
  /** Summarize provider startup evidence without retaining container logs or secrets. */
2
+ import { classifyPortStartupFailure, portStartupGuidance, } from "./port_start_failure.mjs";
2
3
  const SERVICE_NAMES = Object.freeze({
3
4
  db: "database",
4
5
  auth: "auth",
@@ -18,7 +19,6 @@ const SERVICE_NAMES = Object.freeze({
18
19
  const REASONS = Object.freeze([
19
20
  ["out_of_memory", /out of memory|oom[- ]killed|memory allocation failed/iu],
20
21
  ["disk_full", /no space left on device|disk quota exceeded/iu],
21
- ["port_in_use", /address already in use|port is already allocated/iu],
22
22
  ["image_architecture", /exec format error/iu],
23
23
  ["image_pull", /failed to pull|pull access denied|manifest unknown/iu],
24
24
  [
@@ -40,6 +40,9 @@ export const summarizeSupabaseStartupFailure = ({ output, status, processErrorCo
40
40
  reasons.add("process_timeout");
41
41
  if (processErrorCode === "ENOBUFS")
42
42
  reasons.add("provider_output_limit");
43
+ const portFailure = classifyPortStartupFailure(bounded);
44
+ if (portFailure)
45
+ reasons.add(portFailure);
43
46
  for (const [code, pattern] of REASONS)
44
47
  if (pattern.test(bounded))
45
48
  reasons.add(code);
@@ -60,6 +63,7 @@ export const summarizeSupabaseStartupFailure = ({ output, status, processErrorCo
60
63
  ...(services.size
61
64
  ? [`Reported service states: ${[...services].slice(0, 16).join(", ")}.`]
62
65
  : []),
66
+ ...(portFailure ? [portStartupGuidance(portFailure, "supabase")] : []),
63
67
  "Provider logs, paths, environment values and connection URLs are omitted. This summary does not establish the underlying cause.",
64
68
  ].join("\n");
65
69
  };
package/docs/README.md CHANGED
@@ -41,7 +41,7 @@ accomplish and follow that path.
41
41
  ## Follow the project
42
42
 
43
43
  - [Roadmap](roadmap.md)
44
- - [Stability and the first stable release](stability.md)
44
+ - [Stability and release verification](stability.md)
45
45
  - [Repository architecture](architecture.md)
46
46
  - [Release process](releasing.md)
47
47
 
@@ -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
@@ -229,6 +229,10 @@ approval sequence.
229
229
 
230
230
  `runtimePolicy` replaces common restore adapters with reviewed schemas, allowlisted
231
231
  extensions, managed triggers, local-only singleton rows, and structural expectations.
232
+ The [runtime policy guide](runtime-policies.md#explicit-data-api-grants) also owns the
233
+ least-privilege Data API migration checklist and core 1.1.0's optional read-only
234
+ required/forbidden privilege declarations. Earlier releases do not accept that new
235
+ declaration. Rehearsal never infers or automatically grants API access.
232
236
  `identityPolicy` declares a hashed verified-email or provider-subject matcher, copied
233
237
  placeholder, safe signup defaults, required role/reference transfers, Storage path
234
238
  rewrites, and token checks. Provider credentials stay in the local Supabase runtime
@@ -300,8 +304,10 @@ Rehearsal stacks.
300
304
  `keep-until-stop` preserves today's interactive behavior, while `stop-after-run` stops
301
305
  the targets after proofs, proof failures, or interruption. `lifecycle.open` uses
302
306
  `keep-until-stop` or `stop-on-application-exit` after the app closes. Every mode stops
303
- only Rehearsal's configured targets, never the shared engine. Ordinary stopping keeps
304
- database and Storage volumes and all sandbox edits; it does not reset or discard them.
307
+ only Rehearsal's configured targets; lifecycle selection does not enable engine shutdown.
308
+ The separately opted-in `stopOwnedColimaWhenIdle` policy above is the only guarded Colima
309
+ shutdown path. Ordinary stopping keeps database and Storage volumes and all sandbox
310
+ edits; it does not reset or discard them.
305
311
  See [Container runtime lifecycle](runtime-lifecycle.md).
306
312
 
307
313
  ### Foreground application idle shutdown
@@ -637,8 +643,17 @@ The VS Code Local Resources manager reviews an exact diff before changing either
637
643
  See [Local Resources](runtime-lifecycle.md#local-resources-manager) for image and volume rules.
638
644
 
639
645
  Use unique, non-privileged ports that do not overlap. `projectId` accepts lowercase
640
- letters, numbers, and hyphens. It labels the local Docker resources so cleanup targets
641
- only this project.
646
+ letters, numbers, and hyphens: 2–40 characters for Supabase, or 2–63 for PostgreSQL.
647
+ It labels the local Docker resources so cleanup targets only this exact project.
648
+ Overlong configured IDs are refused before a provider starts; Rehearsal never truncates
649
+ them or adopts resources using a shortened prefix. Review existing resources before
650
+ changing a configured ID, and use a distinct reviewed identity for a new disposable
651
+ runtime rather than assuming that a renamed config owns old containers or volumes.
652
+
653
+ For new setup only, the generated `<project-name>-rehearsal` ID stays unchanged when it
654
+ fits the selected provider. Longer new IDs use a readable prefix and a deterministic
655
+ hash suffix within that provider's limit. Setup uses the same exact ID in the generated
656
+ Rehearsal config and Supabase TOML. Existing configuration files are never rewritten.
642
657
 
643
658
  Application and readiness URLs must use a different port from the configured database,
644
659
  API, and Studio services. Editing a URL does not rewrite your framework's development
@@ -12,17 +12,17 @@ Separate setup folders are available for
12
12
  [macOS](https://github.com/Ddupasquier/rehearsal-db/tree/main/installers/macos) and
13
13
  [Linux](https://github.com/Ddupasquier/rehearsal-db/tree/main/installers/linux).
14
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;
15
+ Existing Node.js 22, 24 or 26 is required. The default only checks an existing project;
16
16
  installation needs an explicit option and does not start a database. Review the
17
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.1 install requires that version to
18
+ before choosing an install option. An exact core 1.1.0 install requires that version to
19
19
  be published; a checked-in helper is not proof of publication.
20
20
 
21
21
  ### Windows: use a WSL 2 Linux workspace
22
22
 
23
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.
24
+ PowerShell/Command Prompt database runtime. Since core 1.0.1 and extension 0.1.21, that
25
+ boundary is explicit; native Windows version/help/discovery do not authorize runtime work.
26
26
 
27
27
  1. Follow Microsoft's [WSL installation guide](https://learn.microsoft.com/en-us/windows/wsl/install)
28
28
  to prepare a WSL 2 Linux distribution, such as Ubuntu 24.04. Do not use WSL 1.
package/docs/releasing.md CHANGED
@@ -138,7 +138,9 @@ release-source migration.
138
138
  4. When an unfamiliar developer is available, have them follow clean-project onboarding.
139
139
  Correct and retest the first confusing, missing, or wrong instruction. Record when
140
140
  this human observation was unavailable; automated checks must not impersonate it.
141
- 5. Change `private` to `false` only in the reviewed release change.
141
+ 5. Confirm package metadata keeps `private: false` for this public npm package. Any
142
+ metadata change belongs in the reviewed release change; do not toggle visibility
143
+ or package privacy as an incidental publishing step.
142
144
  6. Record the exact tarball filename, SHA-1, SHA-256, allowlisted files, unpacked size,
143
145
  executable, declared runtime dependency inventory, and dependency audit result.
144
146
  7. Review the release change and its exact artifact evidence.
@@ -195,7 +197,7 @@ This is mutual exclusion, not a guaranteed ordered queue: reconcile a superseded
195
197
  pending workflow before deliberately requesting another run.
196
198
 
197
199
  The objective promotion checklist and compatibility boundary live in
198
- [Stability and the first stable release](stability.md).
200
+ [Stability and release verification](stability.md).
199
201
 
200
202
  The trusted publisher allows `npm dist-tag` only so this workflow can maintain those two
201
203
  tags without a stored npm token. A manual workflow run from `main` can repair the correct
package/docs/roadmap.md CHANGED
@@ -1,9 +1,16 @@
1
1
  # Next steps
2
2
 
3
- Rehearsal core **1.0.0 is available on
3
+ Rehearsal core **1.1.0 is available on
4
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.
5
+ ordinary PostgreSQL migration rehearsals. The [free VS Code Starter 0.1.23 preview](vscode.md)
6
+ adds a visual workbench and is distributed through Marketplace and reviewed GitHub
7
+ VSIX releases. Neither requires a purchase or account. Core is MIT-licensed; all
8
+ features included in Starter are free indefinitely for personal or commercial development.
9
+
10
+ Stable core, the editor preview and a future paid Pro offer have separate completion
11
+ boundaries. A downloadable preview does not imply that every native accessibility,
12
+ provider or real-user acceptance observation has been completed. Publication does not
13
+ authorize a new database operation or migrate a running legacy extension.
7
14
 
8
15
  The standalone workflow keeps the rehearsal engine in the package while application
9
16
  meaning and privacy decisions remain project-owned. The sequence below explains its
@@ -30,10 +37,18 @@ Track the full breakdown in
30
37
  For questions or feature requests, use
31
38
  [GitHub issues](https://github.com/Ddupasquier/rehearsal-db/issues).
32
39
 
33
- ## Acceptance still required
40
+ ## Verification and supported-journey work
41
+
42
+ The [release verification policy](stability.md) owns promotion requirements. The
43
+ [Environment Workbench epic](https://github.com/Ddupasquier/rehearsal-db/issues/130)
44
+ and its children track remaining editor acceptance; the issue tracker owns current
45
+ status and pickup order, not this page. Supported-journey compatibility work,
46
+ including the [Supabase grant-preservation review](https://github.com/Ddupasquier/rehearsal-db/issues/199),
47
+ is distinct from adding new database families or paid features.
34
48
 
35
- These are verification requirements, not a live checklist of unfinished releases or
36
- consumer migrations. Record the observed results for each exact candidate separately.
49
+ For each exact candidate, retain the checks already proved and complete the missing
50
+ observations. The following describe evidence boundaries, not a claim that a shipped
51
+ release or consumer upgrade remains unfinished:
37
52
 
38
53
  - Install the exact packed candidate in clean Supabase and PostgreSQL consumers.
39
54
  - Exercise two unrelated synthetic schemas, bounded large data, interruption, drift,
@@ -48,6 +63,12 @@ consumer migrations. Record the observed results for each exact candidate separa
48
63
 
49
64
  ## Later database targets
50
65
 
51
- After the PostgreSQL family is stable in real projects, evaluate individual PostgreSQL
52
- services. MySQL, MongoDB, and unrelated database families require different migration,
53
- restore, and safety behavior and remain out of scope.
66
+ Additional database, runtime, identity-provider and migration-tool integrations require
67
+ their own reviewed capability contracts and independent acceptance. Research or a roadmap
68
+ ticket is not a support claim. MySQL, MongoDB, SQLite and other database families are not
69
+ supported by this PostgreSQL/Supabase release. They remain separate future work rather
70
+ than prerequisites for the current local workflow.
71
+
72
+ The complete CLI and its database/safety capabilities stay free. Optional paid Pro
73
+ workflows, licensing and commercial readiness remain separate owner decisions; this
74
+ roadmap does not approve a paywall, price, billing service or new distribution operation.
@@ -27,8 +27,8 @@ then repeat the command.
27
27
 
28
28
  Setting `autoStartColima: true` is an explicit convenience opt-in. If Docker is
29
29
  unavailable and the `colima` command exists, Rehearsal runs plain `colima start` and
30
- reports it. Rehearsal does not resize Colima and does not stop the shared engine
31
- automatically. Starting Docker can also wake unrelated containers that use Docker's
30
+ reports it. Rehearsal does not resize Colima. Engine shutdown remains off unless the
31
+ separate ownership-guarded policy below is explicitly enabled. Starting Docker can also wake unrelated containers that use Docker's
32
32
  `always` or `unless-stopped` restart policy. Rehearsal changes only the selected
33
33
  Supabase stack to Docker's `no` restart policy after it starts successfully.
34
34
 
@@ -84,8 +84,9 @@ lifecycle: {
84
84
  `run` accepts `keep-until-stop` or `stop-after-run`. `open` accepts
85
85
  `keep-until-stop` or `stop-on-application-exit`. The bounded choices stop every
86
86
  configured Rehearsal target in reverse dependency order after the command finishes,
87
- fails after startup, times out, or is interrupted. They never stop the shared Docker
88
- engine.
87
+ fails after startup, times out, or is interrupted. Lifecycle choices govern targets,
88
+ not engine ownership; they do not enable Colima shutdown. The separate
89
+ `stopOwnedColimaWhenIdle` policy still requires its own opt-in and ownership checks.
89
90
 
90
91
  Stopping is non-destructive: database and Storage volumes, applied migrations, and
91
92
  sandbox edits remain available to `start` or `open`. Only the existing explicit `reset`
@@ -66,6 +66,151 @@ identity policy. Verification accepts the configured placeholder before associat
66
66
  the exact recorded local identity afterward. Rehearsal stores that mapping only in its
67
67
  local internal schema; it does not duplicate the old role or weaken the row check.
68
68
 
69
+ ### Explicit Data API grants
70
+
71
+ Supabase's [official announcement](https://supabase.com/changelog/45329-breaking-change-tables-not-exposed-to-data-and-graphql-api-automatically)
72
+ sets October 30, 2026 for changing existing projects to opt-in exposure of new
73
+ `public` tables. Existing table grants remain; this is not evidence that a particular
74
+ project's setting has already changed. Direct PostgreSQL access is a separate contract.
75
+
76
+ [Grants and RLS](https://supabase.com/docs/guides/api/securing-your-api) answer different
77
+ questions: a grant allows an API role to reach an object; an RLS policy decides which
78
+ rows that role can use. Passing an administrator SQL query or finding an RLS policy
79
+ does not prove that an application's Data API request will work safely.
80
+
81
+ For every new or recreated API table:
82
+
83
+ 1. Review the exposed schemas and the exact operations needed by `anon`,
84
+ `authenticated`, and `service_role`. An internal table does not need API access.
85
+ 2. Put explicit, least-privilege grants and RLS in that table's new migration. Remove
86
+ unwanted inherited defaults for the new object; do not blindly grant anonymous CRUD.
87
+ Check its sequences and callable functions separately, including `PUBLIC EXECUTE`.
88
+ 3. Preserve already-applied migration files. Correct historical objects through a
89
+ separately reviewed forward migration, not by rewriting the baseline's prefix.
90
+ 4. Test an empty setup and the disposable restore/reset/replay path with both permissive
91
+ and revoked automatic defaults. A schema dump alone is not proof of effective ACLs:
92
+ [Supabase's dump guidance](https://supabase.com/docs/reference/cli/supabase-db-dump#supabase-db-dump)
93
+ warns that target default privileges can broaden restored access.
94
+ 5. Independently check SQL grants, RLS and actual allowed/denied Data API requests with
95
+ the application's roles. A successful `service_role` request does not prove ordinary
96
+ authenticated access, and an empty RLS-filtered response is not a grant refusal.
97
+
98
+ For example, a **new read-only authenticated API table**, created by its migration owner,
99
+ can deliberately declare its own boundary:
100
+
101
+ ```sql
102
+ create table public.api_notes (
103
+ id bigint generated by default as identity primary key,
104
+ owner_id uuid not null,
105
+ body text not null
106
+ );
107
+ alter table public.api_notes enable row level security;
108
+ revoke all on table public.api_notes from public, anon, authenticated, service_role;
109
+ revoke all on sequence public.api_notes_id_seq from public, anon, authenticated, service_role;
110
+ grant select on table public.api_notes to authenticated;
111
+ create policy read_own_notes on public.api_notes
112
+ for select to authenticated using ((select auth.uid()) = owner_id);
113
+ ```
114
+
115
+ This example deliberately permits no client inserts, sequence use or service-role
116
+ access. Choose a different reviewed boundary when the application needs those operations.
117
+ Apply such SQL only through your own authorized migration process; Rehearsal does not
118
+ change hosted grants or RLS on your behalf.
119
+
120
+ ### Read-only privilege expectations (core 1.1.0 and newer)
121
+
122
+ Core 1.1.0 adds the following optional declaration. Earlier releases, including
123
+ 1.0.2, do not accept `privileges`; install a published release containing this contract
124
+ before adding it. A project-owned application proof remains necessary for API/RLS behavior.
125
+
126
+ Add `privileges` to the same runtime-policy JSON to check required and forbidden
127
+ **effective** privileges after restore and migration. These checks issue no `GRANT`,
128
+ `REVOKE`, role switch or permission repair. They do not infer grants from RLS.
129
+
130
+ ```json
131
+ {
132
+ "policyVersion": 1,
133
+ "privileges": [
134
+ {
135
+ "kind": "schema",
136
+ "schema": "public",
137
+ "role": "authenticated",
138
+ "required": ["USAGE"],
139
+ "forbidden": ["CREATE"]
140
+ },
141
+ {
142
+ "kind": "table",
143
+ "schema": "public",
144
+ "name": "api_notes",
145
+ "role": "authenticated",
146
+ "required": ["SELECT"],
147
+ "forbidden": [
148
+ "INSERT",
149
+ "UPDATE",
150
+ "DELETE",
151
+ "TRUNCATE",
152
+ "REFERENCES",
153
+ "TRIGGER",
154
+ "MAINTAIN"
155
+ ]
156
+ },
157
+ {
158
+ "kind": "table",
159
+ "schema": "public",
160
+ "name": "api_notes",
161
+ "role": "anon",
162
+ "forbidden": [
163
+ "SELECT",
164
+ "INSERT",
165
+ "UPDATE",
166
+ "DELETE",
167
+ "TRUNCATE",
168
+ "REFERENCES",
169
+ "TRIGGER",
170
+ "MAINTAIN"
171
+ ]
172
+ }
173
+ ]
174
+ }
175
+ ```
176
+
177
+ Existing policy fields and structural/RLS expectations remain independent and compatible.
178
+ Omitting `privileges` preserves the previous behavior; an empty array adds no checks.
179
+ Each nonempty declaration needs at least one required or forbidden privilege. Omitted
180
+ lists mean empty, but explicit `null`, overlapping lists, unknown fields and unsupported
181
+ identifiers or privileges are rejected. At most 1,024 declarations are accepted.
182
+
183
+ | Kind | Object fields | Accepted privileges |
184
+ | ---------- | --------------------------------- | --------------------------------------------------------------------------------------- |
185
+ | `schema` | `schema`; no `name` | `USAGE`, `CREATE` |
186
+ | `table` | `schema`, `name` | `SELECT`, `INSERT`, `UPDATE`, `DELETE`, `TRUNCATE`, `REFERENCES`, `TRIGGER`, `MAINTAIN` |
187
+ | `sequence` | `schema`, `name` | `USAGE`, `SELECT`, `UPDATE` |
188
+ | `function` | `schema`, `name`, `argumentTypes` | `EXECUTE` |
189
+
190
+ Use exact uppercase privilege names and reviewed existing role/object names. Roles must
191
+ exist in `pg_roles`; declare an actual application role to check access inherited from
192
+ `PUBLIC`, not a standalone `PUBLIC` pseudo-role. Function checks cover ordinary functions,
193
+ not procedures, aggregates or window routines. A function declaration must include its
194
+ exact input types (including `INOUT`, excluding output-only arguments) as structured
195
+ catalog names, for example
196
+ `"argumentTypes": [{ "schema": "pg_catalog", "name": "uuid" }]`; `[]` selects a
197
+ zero-argument function. At most 32 arguments are supported. SQL signature strings and
198
+ non-`pg_catalog` argument types are not accepted; use a project-owned proof for unsupported
199
+ signatures rather than changing a function to fit the check.
200
+
201
+ Effective checks include inherited role permissions and grants through `PUBLIC`.
202
+ Required table access means a full-table privilege. Forbidden `SELECT`, `INSERT`,
203
+ `UPDATE` and `REFERENCES` also detect a privilege granted on only one column.
204
+ `MAINTAIN` is checked on PostgreSQL 17 and newer; below 17 it is unavailable, so a required
205
+ check fails and a forbidden check passes. Missing roles, objects, types or exact function
206
+ signatures fail rather than being interpreted as a successful denial.
207
+
208
+ These declarations do not inventory undeclared objects, prove RLS expressions or grant
209
+ options, change Data API exposure settings, or make a live HTTP request. Keep your
210
+ application's positive and negative API proof alongside them, including fresh setup and
211
+ replay coverage. A failed check needs a fresh reviewed migration; it is never an
212
+ automatic privilege escalation or a reason to use hosted administrator credentials.
213
+
69
214
  ## Identity policy
70
215
 
71
216
  The identity policy links one verified local Supabase identity to a copied pseudonymous
package/docs/stability.md CHANGED
@@ -1,11 +1,15 @@
1
- # Stability and the first stable release
1
+ # Stability and release verification
2
2
 
3
- Rehearsal core **1.0.0 is published** on
3
+ Rehearsal core **1.1.0 is published** on
4
4
  [npm](https://www.npmjs.com/package/@rehearsal-db/core). This page defines its
5
5
  compatibility promise and the verification policy for releases; it is not an
6
6
  unfinished launch checklist. Stable core does not require every planned database,
7
7
  editor interface, or paid feature.
8
8
 
9
+ The compatibility promise began with **1.0.0**. The separate
10
+ [VS Code Starter 0.1.23 preview](vscode.md) has its own editor acceptance and does
11
+ not turn a core release into a completed accessibility or provider walkthrough.
12
+
9
13
  ## What becomes a compatibility promise
10
14
 
11
15
  Starting with `1.0.0`, Rehearsal treats these documented surfaces as public:
@@ -65,7 +69,7 @@ ready. The sequence below is policy, not a claim that its checks have passed.
65
69
  corrected candidate. Reuse sufficient unchanged evidence with its original scope;
66
70
  do not relabel old or unavailable manual checks as new results. No minimum number
67
71
  of calendar days replaces these checks.
68
- 6. Publish `1.0.0` only when no blocking issue remains and the exact tarball has passed
72
+ 6. Publish the selected stable version only when no blocking issue remains and the exact tarball has passed
69
73
  the required release checks and consumer acceptance. The protected GitHub npm
70
74
  review is the single human authorization for its displayed exact version and
71
75
  checksum; no separate chat approval or pasted phrase is required.
@@ -94,7 +98,7 @@ baseline. Automatic compatible updates do not cross the 0.x-to-1.x version bound
94
98
  review the changelog and deliberately select the stable version:
95
99
 
96
100
  ```bash
97
- npm install --save-dev --save-exact @rehearsal-db/core@1.0.0
101
+ npm install --save-dev --save-exact @rehearsal-db/core@1.1.0
98
102
  npx --no-install rehearsal --version
99
103
  npx --no-install rehearsal doctor
100
104
  ```
@@ -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.