@rehearsal-db/core 0.1.0-beta.1 → 0.1.0-beta.3
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 +55 -1
- package/README.md +30 -6
- package/docs/commands.md +25 -2
- package/docs/configuration.md +3 -1
- package/docs/getting-started.md +42 -13
- package/docs/production-source.md +1 -1
- package/docs/releasing.md +17 -36
- package/docs/sanitization.md +10 -0
- package/docs/troubleshooting.md +18 -2
- package/package.json +1 -1
- package/scripts/lib/rehearsal/baseline_builder.mjs +11 -6
- package/scripts/lib/rehearsal/baseline_preparation.mjs +201 -0
- package/scripts/lib/rehearsal/configuration.d.mts +14 -1
- package/scripts/lib/rehearsal/configuration.mjs +20 -10
- package/scripts/lib/rehearsal/diagnostics.mjs +7 -3
- package/scripts/lib/rehearsal/human_output.mjs +4 -0
- package/scripts/lib/rehearsal/plan.mjs +25 -2
- package/scripts/lib/rehearsal/sanitization_policy.mjs +110 -0
- package/scripts/lib/rehearsal/setup.mjs +347 -0
- package/scripts/operations/database/manage_rehearsal_database.mjs +12 -6
- package/scripts/operations/rehearsal/rehearsal_cli.mjs +692 -16
package/CHANGELOG.md
CHANGED
|
@@ -5,6 +5,58 @@ a Changelog, and versions will follow Semantic Versioning after the package exis
|
|
|
5
5
|
|
|
6
6
|
## Unreleased
|
|
7
7
|
|
|
8
|
+
## [0.1.0-beta.3] - 2026-10-01
|
|
9
|
+
|
|
10
|
+
### Added
|
|
11
|
+
|
|
12
|
+
- A state-aware interactive home screen that guides setup, baseline preparation,
|
|
13
|
+
migration review, runtime management, verification, and cleanup without requiring
|
|
14
|
+
users to memorize commands.
|
|
15
|
+
- A safe `setup` workflow that previews and creates a dedicated local Supabase config,
|
|
16
|
+
chooses an available port block, updates protective ignore rules, and summarizes
|
|
17
|
+
readiness without overwriting project files.
|
|
18
|
+
- A schema-only `baseline prepare` workflow that generates a fail-closed policy draft
|
|
19
|
+
with explicit `REVIEW REQUIRED` decisions and never prints source row values.
|
|
20
|
+
- Interactive confirmation of the exact candidate migration set plus friendly progress
|
|
21
|
+
and timing while a rehearsal runs.
|
|
22
|
+
|
|
23
|
+
### Changed
|
|
24
|
+
|
|
25
|
+
- Human output now recommends the next useful action, uses compact first-run readiness
|
|
26
|
+
summaries, respects `NO_COLOR` and `--plain`, and renders singular counts correctly.
|
|
27
|
+
- Bare `rehearsal` opens the guide only in a terminal and remains noninteractive and
|
|
28
|
+
script-safe when standard input or output is redirected.
|
|
29
|
+
|
|
30
|
+
### Fixed
|
|
31
|
+
|
|
32
|
+
- Setup detects unsupported Node.js versions before writing, ignores ports occupied by
|
|
33
|
+
Docker or SSH forwarding, and rechecks its selected ports immediately before commit.
|
|
34
|
+
- Generated project identifiers are bounded to values accepted by the local runtime.
|
|
35
|
+
|
|
36
|
+
### Security
|
|
37
|
+
|
|
38
|
+
- Reviewed sanitization policy bytes are checksum-bound to the active baseline and are
|
|
39
|
+
revalidated during planning and runtime restore.
|
|
40
|
+
- Draft or incomplete sanitization policies cannot be activated as baselines.
|
|
41
|
+
|
|
42
|
+
## [0.1.0-beta.2] - 2026-09-15
|
|
43
|
+
|
|
44
|
+
### Fixed
|
|
45
|
+
|
|
46
|
+
- Generate `rehearsal.config.mjs` so first-time initialization works in both CommonJS
|
|
47
|
+
and ESM projects instead of failing when a fresh npm project declares CommonJS.
|
|
48
|
+
- Report the exact table and represented-migration counts after creating a synthetic
|
|
49
|
+
baseline instead of rendering missing result fields as `undefined`.
|
|
50
|
+
- Keep the copyable getting-started migration bytes identical to its migration-ledger
|
|
51
|
+
example so the documented runtime replay passes exact-history verification.
|
|
52
|
+
- Install the current prerelease through npm's `beta` tag so new projects do not resolve
|
|
53
|
+
the superseded bootstrap release from npm's historical `latest` tag.
|
|
54
|
+
|
|
55
|
+
### Security
|
|
56
|
+
|
|
57
|
+
- Removed the completed first-package bootstrap credential path. All future publication
|
|
58
|
+
uses the package's trusted GitHub Actions OIDC publisher and cannot read an npm token.
|
|
59
|
+
|
|
8
60
|
## [0.1.0-beta.1] - 2026-09-14
|
|
9
61
|
|
|
10
62
|
### Changed
|
|
@@ -54,6 +106,8 @@ a Changelog, and versions will follow Semantic Versioning after the package exis
|
|
|
54
106
|
publication uses short-lived trusted OIDC, and every release tag must already exist on
|
|
55
107
|
protected `main`.
|
|
56
108
|
|
|
57
|
-
[Unreleased]: https://github.com/Ddupasquier/rehearsal-db/compare/v0.1.0-beta.
|
|
109
|
+
[Unreleased]: https://github.com/Ddupasquier/rehearsal-db/compare/v0.1.0-beta.3...HEAD
|
|
110
|
+
[0.1.0-beta.3]: https://github.com/Ddupasquier/rehearsal-db/compare/v0.1.0-beta.2...v0.1.0-beta.3
|
|
111
|
+
[0.1.0-beta.2]: https://github.com/Ddupasquier/rehearsal-db/compare/v0.1.0-beta.1...v0.1.0-beta.2
|
|
58
112
|
[0.1.0-beta.1]: https://github.com/Ddupasquier/rehearsal-db/releases/tag/v0.1.0-beta.1
|
|
59
113
|
[0.1.0-beta.0]: https://github.com/Ddupasquier/rehearsal-db/releases/tag/v0.1.0-beta.0
|
package/README.md
CHANGED
|
@@ -77,15 +77,20 @@ invariants. Reset restores and reproves the exact starting data.
|
|
|
77
77
|
Install the current beta from npm:
|
|
78
78
|
|
|
79
79
|
```bash
|
|
80
|
-
npm install --save-dev @rehearsal-db/core
|
|
80
|
+
npm install --save-dev @rehearsal-db/core@beta
|
|
81
81
|
```
|
|
82
82
|
|
|
83
83
|
Contributors testing an unreleased change can use `npm link` or install the tarball
|
|
84
84
|
produced by `npm pack` from a local checkout. In a consuming project, the commands are:
|
|
85
85
|
|
|
86
86
|
```bash
|
|
87
|
+
npx rehearsal
|
|
88
|
+
npx rehearsal setup
|
|
89
|
+
npx rehearsal setup --write
|
|
87
90
|
npx rehearsal init
|
|
88
91
|
npx rehearsal init --write
|
|
92
|
+
npx rehearsal baseline prepare --records=<safe.ndjson> --ledger=<ledger.json>
|
|
93
|
+
npx rehearsal baseline prepare --records=<safe.ndjson> --ledger=<ledger.json> --write
|
|
89
94
|
npx rehearsal baseline create --records=<safe.ndjson> --ledger=<ledger.json>
|
|
90
95
|
npx rehearsal doctor
|
|
91
96
|
npx rehearsal explain
|
|
@@ -102,13 +107,32 @@ npx rehearsal stop
|
|
|
102
107
|
npx rehearsal discard
|
|
103
108
|
```
|
|
104
109
|
|
|
105
|
-
`
|
|
106
|
-
|
|
107
|
-
|
|
110
|
+
Running `npx rehearsal` in a terminal opens a state-aware guide that shows completed
|
|
111
|
+
setup steps and recommends available actions. The explicit commands remain the stable
|
|
112
|
+
interface for automation and CI.
|
|
113
|
+
|
|
114
|
+
`setup` previews a conservative first-run scaffold: the Rehearsal configuration, a
|
|
115
|
+
dedicated local-only Supabase configuration on an available port block, and protective
|
|
116
|
+
`.gitignore` entries. It writes only with `--write`, never overwrites project files, and
|
|
117
|
+
does not copy enabled external providers from the application's Supabase configuration.
|
|
118
|
+
After writing, it runs the same readiness checks as `doctor` and shows the remaining
|
|
119
|
+
project-owned inputs. Use `init` when you want to create only the configuration file
|
|
120
|
+
manually.
|
|
121
|
+
|
|
122
|
+
`baseline prepare` inspects only the shape of explicit local synthetic records and writes
|
|
123
|
+
a fail-closed sanitization-policy draft. Every column remains `REVIEW REQUIRED` until a
|
|
124
|
+
human classifies its sanitization action, generated/identity behavior, and foreign key.
|
|
125
|
+
Drafts cannot be activated, and a reviewed policy is checksum-bound to its baseline.
|
|
126
|
+
|
|
127
|
+
`init` previews a type-aware ESM `rehearsal.config.mjs`; it writes only with `--write`
|
|
128
|
+
and never overwrites an existing file. The explicit `.mjs` extension makes the generated
|
|
129
|
+
configuration executable in both CommonJS and ESM projects. Review all detected values.
|
|
130
|
+
Rehearsal intentionally does not detect, copy, or enable a hosted project.
|
|
108
131
|
|
|
109
132
|
`doctor` must end with `READY` before execution. `explain` and `run --dry-run` use the
|
|
110
|
-
same immutable planner and perform no state-changing operations.
|
|
111
|
-
|
|
133
|
+
same immutable planner and perform no state-changing operations. In a terminal,
|
|
134
|
+
`rehearsal run` displays and confirms the exact candidate set before touching the local
|
|
135
|
+
runtime. Automation supplies the digest explicitly:
|
|
112
136
|
|
|
113
137
|
```bash
|
|
114
138
|
npx rehearsal run --confirm-candidates=<sha256>
|
package/docs/commands.md
CHANGED
|
@@ -6,8 +6,13 @@ values or credentials.
|
|
|
6
6
|
|
|
7
7
|
| Command | Mutates local state | Purpose |
|
|
8
8
|
| ------------------------------------------------------------ | ------------------- | --------------------------------------------------------- |
|
|
9
|
+
| `rehearsal` or `rehearsal guide` | No by default | Open the guided, state-aware interactive home screen. |
|
|
10
|
+
| `rehearsal setup` | No | Preview safe config, local runtime, and ignore files. |
|
|
11
|
+
| `rehearsal setup --write` | Project files | Create the previewed first-run scaffolding. |
|
|
9
12
|
| `rehearsal init` | No | Preview safe starter configuration. |
|
|
10
13
|
| `rehearsal init --write` | Config only | Create config without overwriting. |
|
|
14
|
+
| `rehearsal baseline prepare --records= --ledger=` | No | Preview a fail-closed policy draft from local shape. |
|
|
15
|
+
| `rehearsal baseline prepare --records= --ledger= --write` | Policy only | Write the draft without exposing row values. |
|
|
11
16
|
| `rehearsal baseline create --records=<path> --ledger=<path>` | Artifact only | Activate a baseline from explicit safe local inputs. |
|
|
12
17
|
| `rehearsal doctor` | No | Check dependencies, inputs, and safety barriers. |
|
|
13
18
|
| `rehearsal explain` | No | Print the immutable execution plan. |
|
|
@@ -24,12 +29,30 @@ values or credentials.
|
|
|
24
29
|
| `rehearsal stop` | Runtime only | Stop this project's local services. |
|
|
25
30
|
| `rehearsal discard` | Yes, local only | Remove only this project's disposable runtime and volume. |
|
|
26
31
|
|
|
27
|
-
`run`
|
|
28
|
-
|
|
32
|
+
In an interactive terminal, `run` and `migrate` display the candidate files and ask for
|
|
33
|
+
confirmation before touching the runtime. In automation, they require the digest from
|
|
34
|
+
the current candidate set. Any added, removed, reordered, or edited migration changes
|
|
35
|
+
the digest and invalidates either form of confirmation.
|
|
29
36
|
|
|
30
37
|
`baseline create` never extracts data. The NDJSON and migration-ledger files must already
|
|
31
38
|
exist inside the project and be safe to retain. Add `--assets=<manifest.json>` to include
|
|
32
39
|
bounded local Storage bytes; every manifest `file` must also remain inside the project.
|
|
40
|
+
The guided home screen can ask for these paths so they do not need to be supplied as
|
|
41
|
+
flags.
|
|
42
|
+
|
|
43
|
+
`baseline prepare` reads only table and column names from the NDJSON records; row values
|
|
44
|
+
are never included in its result. Its generated policy deliberately marks every column
|
|
45
|
+
decision `REVIEW REQUIRED` and cannot be activated until a human completes the metadata
|
|
46
|
+
and removes the `draft` marker. Rehearsal binds the reviewed policy checksum to the
|
|
47
|
+
baseline and rejects later policy changes during planning and restore.
|
|
33
48
|
|
|
34
49
|
Automation should use `--json` and inspect both exit status and the versioned envelope.
|
|
35
50
|
Exit-code meanings are documented in the root README. Scripts must not parse human text.
|
|
51
|
+
When standard input or output is not an interactive terminal, bare `rehearsal` prints
|
|
52
|
+
help instead of prompting. Use `--plain` to disable decorative terminal styling.
|
|
53
|
+
|
|
54
|
+
`setup` chooses an available local port block and generates a conservative Supabase
|
|
55
|
+
configuration with hosted access and optional networked services disabled. It does not
|
|
56
|
+
overwrite an existing Rehearsal config, dedicated Supabase config, or concurrently
|
|
57
|
+
changed `.gitignore`. After writing, it includes a Doctor readiness summary. `init`
|
|
58
|
+
remains available for config-only/manual onboarding.
|
package/docs/configuration.md
CHANGED
|
@@ -1,6 +1,8 @@
|
|
|
1
1
|
# Configuration reference
|
|
2
2
|
|
|
3
|
-
`rehearsal.config.
|
|
3
|
+
`rehearsal.config.mjs` is executable configuration with a strict versioned schema. The
|
|
4
|
+
initializer uses an explicit ESM extension so the same generated file works in CommonJS
|
|
5
|
+
and ESM projects.
|
|
4
6
|
Unknown fields and unknown schema versions are errors, not warnings.
|
|
5
7
|
|
|
6
8
|
```ts
|
package/docs/getting-started.md
CHANGED
|
@@ -34,18 +34,30 @@ its labeled local runtime. It does not need a hosted Supabase project or credent
|
|
|
34
34
|
|
|
35
35
|
## 1. Install and initialize
|
|
36
36
|
|
|
37
|
+
Confirm this shell is running the supported Node.js major before installing:
|
|
38
|
+
|
|
39
|
+
```bash
|
|
40
|
+
node --version # v24.x
|
|
41
|
+
```
|
|
42
|
+
|
|
37
43
|
```bash
|
|
38
|
-
npm install --save-dev @rehearsal-db/core
|
|
39
|
-
npx rehearsal
|
|
44
|
+
npm install --save-dev @rehearsal-db/core@beta
|
|
45
|
+
npx rehearsal
|
|
40
46
|
```
|
|
41
47
|
|
|
42
|
-
|
|
48
|
+
Choose **Set up Rehearsal** in the guide. It previews a versioned configuration, a
|
|
49
|
+
dedicated local-only Supabase configuration using available ports, and protective
|
|
50
|
+
`.gitignore` entries before asking permission to write.
|
|
51
|
+
|
|
52
|
+
The same flow is available noninteractively as an explicit preview and write:
|
|
43
53
|
|
|
44
54
|
```bash
|
|
45
|
-
npx rehearsal
|
|
55
|
+
npx rehearsal setup
|
|
56
|
+
npx rehearsal setup --write
|
|
46
57
|
```
|
|
47
58
|
|
|
48
|
-
Rehearsal never overwrites an existing configuration.
|
|
59
|
+
Rehearsal never overwrites an existing configuration. For config-only/manual setup, use
|
|
60
|
+
`npx rehearsal init` followed by `npx rehearsal init --write`.
|
|
49
61
|
|
|
50
62
|
The generated configuration is intentionally incomplete until you review its ports,
|
|
51
63
|
project ID, application commands, and project-owned input paths. Do not run `doctor`
|
|
@@ -53,14 +65,14 @@ until the next section's files exist.
|
|
|
53
65
|
|
|
54
66
|
## 2. Add the project-owned inputs
|
|
55
67
|
|
|
56
|
-
|
|
68
|
+
Review or create the project-owned inputs named by `rehearsal.config.mjs`:
|
|
57
69
|
|
|
58
|
-
-
|
|
70
|
+
- the dedicated local Supabase `config.toml` (`setup` creates a conservative one);
|
|
59
71
|
- a sanitization policy describing every exported field;
|
|
60
72
|
- an active baseline below `.rehearsal/`;
|
|
61
73
|
- an application proof command that exits nonzero when the restored app is wrong.
|
|
62
74
|
|
|
63
|
-
|
|
75
|
+
If you used config-only `init`, also create the dedicated Supabase config manually:
|
|
64
76
|
|
|
65
77
|
```bash
|
|
66
78
|
mkdir -p infrastructure/rehearsal/supabase infrastructure/rehearsal rehearsal
|
|
@@ -68,7 +80,7 @@ cp supabase/config.toml infrastructure/rehearsal/supabase/config.toml
|
|
|
68
80
|
```
|
|
69
81
|
|
|
70
82
|
Edit the copied Supabase config. Give it the same unique `project_id`, API port, database
|
|
71
|
-
port, and Studio port used by `rehearsal.config.
|
|
83
|
+
port, and Studio port used by `rehearsal.config.mjs`. Disable services your proof does
|
|
72
84
|
not need. This must remain an unlinked local config; never run `supabase link` from it.
|
|
73
85
|
|
|
74
86
|
Also replace the generated `application.startCommand`, `application.proofCommand`, and
|
|
@@ -79,13 +91,29 @@ Start with synthetic rows shaped like your schema. Do not start onboarding with
|
|
|
79
91
|
production data. The following SQL, policy, row, and ledger form one matched example;
|
|
80
92
|
do not mix them with differently shaped snippets.
|
|
81
93
|
|
|
94
|
+
If you already have the safe NDJSON rows and migration ledger, Rehearsal can enumerate
|
|
95
|
+
their table and column shape into a fail-closed policy draft without printing values:
|
|
96
|
+
|
|
97
|
+
```bash
|
|
98
|
+
npx rehearsal baseline prepare \
|
|
99
|
+
--records=rehearsal/synthetic-data.ndjson \
|
|
100
|
+
--ledger=rehearsal/migration-ledger.json
|
|
101
|
+
npx rehearsal baseline prepare \
|
|
102
|
+
--records=rehearsal/synthetic-data.ndjson \
|
|
103
|
+
--ledger=rehearsal/migration-ledger.json \
|
|
104
|
+
--write
|
|
105
|
+
```
|
|
106
|
+
|
|
107
|
+
Review every `REVIEW REQUIRED` field, replace it with correct metadata, and remove
|
|
108
|
+
`"draft": true` only after that review. Rehearsal refuses to activate a draft.
|
|
109
|
+
|
|
82
110
|
Historical migration `supabase/migrations/20260101000000_create_widgets.sql`:
|
|
83
111
|
|
|
84
112
|
```sql
|
|
85
113
|
create table public.widgets (
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
114
|
+
id bigint generated by default as identity primary key,
|
|
115
|
+
name text not null,
|
|
116
|
+
created_at timestamptz not null default now()
|
|
89
117
|
);
|
|
90
118
|
|
|
91
119
|
insert into storage.buckets (id, name, public)
|
|
@@ -238,7 +266,8 @@ stops only this project's runtime.
|
|
|
238
266
|
|
|
239
267
|
## Generated files
|
|
240
268
|
|
|
241
|
-
- `rehearsal.config.
|
|
269
|
+
- `rehearsal.config.mjs` is written only by `init --write`. Its explicit ESM extension
|
|
270
|
+
works whether the consuming project's `package.json` uses CommonJS or ESM.
|
|
242
271
|
- `.rehearsal/generations/<id>/` contains one immutable baseline generation.
|
|
243
272
|
- `.rehearsal/current` selects the active generation atomically.
|
|
244
273
|
- `.rehearsal/runtime/` contains the disposable local Supabase project and receipts.
|
|
@@ -22,7 +22,7 @@ never row bodies.
|
|
|
22
22
|
|
|
23
23
|
## What not to do
|
|
24
24
|
|
|
25
|
-
- Do not point `rehearsal.config.
|
|
25
|
+
- Do not point `rehearsal.config.mjs` at a hosted URL.
|
|
26
26
|
- Do not put a production connection string in `.rehearsal/runtime.env`.
|
|
27
27
|
- Do not grant table-wide access merely because a view is inconvenient.
|
|
28
28
|
- Do not commit sanitized baselines; sanitized data is still data.
|
package/docs/releasing.md
CHANGED
|
@@ -5,48 +5,27 @@ environment. The workflow builds and hashes the candidate before the environment
|
|
|
5
5
|
approval gate, then publishes those exact bytes with npm provenance. A local working
|
|
6
6
|
tree is never the release source.
|
|
7
7
|
|
|
8
|
-
The initial publishable `0.1.0-beta.1` release branch is the first change allowed to set
|
|
9
|
-
`"private": false`. Publication still requires the exact protected-main tag, prerelease
|
|
10
|
-
flag, artifact checks, and protected `npm` environment gate described below.
|
|
11
|
-
|
|
12
8
|
`0.1.0-beta.0` was prepared under the unavailable `@rehearsal` npm scope and was never
|
|
13
9
|
published. `0.1.0-beta.1` supersedes that candidate under `@rehearsal-db/core` without
|
|
14
10
|
rewriting the earlier Git tag or GitHub prerelease.
|
|
15
11
|
|
|
16
|
-
##
|
|
12
|
+
## Trusted publication boundary
|
|
17
13
|
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
a
|
|
14
|
+
`@rehearsal-db/core` trusts only the GitHub Actions publisher for repository
|
|
15
|
+
`Ddupasquier/rehearsal-db`, workflow `publish.yml`, and environment `npm`. The publish job
|
|
16
|
+
requests a short-lived GitHub OIDC identity after the protected environment approval;
|
|
17
|
+
it does not read an npm token or retain a registry credential. Package publishing access
|
|
18
|
+
requires 2FA and disallows bypass tokens.
|
|
21
19
|
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
publish job waits at the protected environment and cannot run yet.
|
|
28
|
-
3. The owner downloads or inspects that prepared artifact, confirms its version and
|
|
29
|
-
checksum, and explicitly authorizes those exact bytes.
|
|
30
|
-
4. Only then, the owner creates a short-lived granular npm token with read/write access
|
|
31
|
-
limited to the `@rehearsal-db` scope and **Bypass 2FA** enabled. npm requires that bypass
|
|
32
|
-
for a non-interactive first publish; the environment approval remains the human
|
|
33
|
-
release gate. Store the token only as the `NPM_TOKEN` secret in the protected GitHub
|
|
34
|
-
`npm` environment.
|
|
35
|
-
5. The owner approves the waiting `npm` deployment. GitHub Actions publishes the exact
|
|
36
|
-
uploaded tarball with provenance. The workflow
|
|
37
|
-
refuses to use the bootstrap secret for any version other than `0.1.0-beta.1`.
|
|
38
|
-
6. Immediately after the registry verification passes, the owner deletes the GitHub
|
|
39
|
-
environment secret and revokes the temporary npm token.
|
|
40
|
-
7. From the new package's npm settings, configure the trusted GitHub Actions publisher
|
|
41
|
-
for repository `Ddupasquier/rehearsal-db`, workflow `publish.yml`, and environment
|
|
42
|
-
`npm`. Allow direct `npm publish` for this workflow because the protected GitHub
|
|
43
|
-
environment supplies the human gate. A later switch to npm staged publication must
|
|
44
|
-
change and prove the workflow before narrowing the trusted publisher permission.
|
|
45
|
-
8. Set package publishing access to require 2FA and disallow traditional tokens.
|
|
20
|
+
The initial `0.1.0-beta.1` package creation required a one-time bootstrap credential
|
|
21
|
+
because npm cannot configure a trusted publisher before a package exists. That
|
|
22
|
+
credential is not part of the maintained release architecture: it was deleted from the
|
|
23
|
+
GitHub environment after publication, must remain revoked at npm, and cannot be consumed
|
|
24
|
+
by this workflow.
|
|
46
25
|
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
26
|
+
Direct `npm publish` is allowed only for this trusted publisher because the protected
|
|
27
|
+
GitHub `npm` environment supplies the human gate. A later switch to npm staged
|
|
28
|
+
publication must change and prove the workflow before narrowing that permission.
|
|
50
29
|
|
|
51
30
|
## Every release candidate
|
|
52
31
|
|
|
@@ -66,7 +45,9 @@ versions.
|
|
|
66
45
|
the approved version and checksum.
|
|
67
46
|
10. Verify public visibility, ownership, provenance, registry SHA-1, README rendering,
|
|
68
47
|
exact-version clean installation, CLI execution, signatures, and the unrelated
|
|
69
|
-
installed Docker fixture.
|
|
48
|
+
installed Docker fixture. Allow up to six minutes for a first package to propagate
|
|
49
|
+
through the public registry before classifying a missing packument as a release
|
|
50
|
+
failure.
|
|
70
51
|
11. Replace consuming projects' temporary Git/archive references only on their own
|
|
71
52
|
protected integration branches and rerun their complete verification.
|
|
72
53
|
|
package/docs/sanitization.md
CHANGED
|
@@ -13,6 +13,12 @@ Every exported field should receive one action:
|
|
|
13
13
|
|
|
14
14
|
Fail if a new column is unclassified. Do not default unknown fields to `KEEP`.
|
|
15
15
|
|
|
16
|
+
For runtime restore, each included column must also classify whether it is generated,
|
|
17
|
+
whether it is an identity column, and its foreign-key target or explicit absence. Run
|
|
18
|
+
`rehearsal baseline prepare` to create a shape-only draft from synthetic NDJSON. The
|
|
19
|
+
draft uses `REVIEW REQUIRED` placeholders and cannot be activated until they are
|
|
20
|
+
replaced and the `draft` marker is removed.
|
|
21
|
+
|
|
16
22
|
The package exports `validateSanitizationCoverage` and
|
|
17
23
|
`applySanitizationAction` as generic primitives:
|
|
18
24
|
|
|
@@ -67,3 +73,7 @@ Before activation, verify:
|
|
|
67
73
|
|
|
68
74
|
Completeness is not correctness. Human review of the policy and export boundary remains
|
|
69
75
|
mandatory before any real source is introduced.
|
|
76
|
+
|
|
77
|
+
The exact reviewed policy bytes are checksum-bound to the active baseline. Planning,
|
|
78
|
+
candidate inspection, and runtime restore refuse to continue if that file later changes;
|
|
79
|
+
build a new reviewed baseline instead of editing the active policy in place.
|
package/docs/troubleshooting.md
CHANGED
|
@@ -1,5 +1,19 @@
|
|
|
1
1
|
# Troubleshooting
|
|
2
2
|
|
|
3
|
+
## Setup says Node.js 24 is required
|
|
4
|
+
|
|
5
|
+
Rehearsal intentionally supports one maintained Node.js major in its first beta. Switch
|
|
6
|
+
the current shell before installing or running it. With nvm:
|
|
7
|
+
|
|
8
|
+
```bash
|
|
9
|
+
nvm install 24
|
|
10
|
+
nvm use 24
|
|
11
|
+
node --version
|
|
12
|
+
```
|
|
13
|
+
|
|
14
|
+
Then reinstall Rehearsal in the consuming project. The guided CLI checks this before it
|
|
15
|
+
writes setup files.
|
|
16
|
+
|
|
3
17
|
## Doctor says Docker is unavailable
|
|
4
18
|
|
|
5
19
|
Start Docker Desktop or Colima, confirm `docker info`, then rerun `rehearsal doctor`.
|
|
@@ -7,8 +21,10 @@ Restarting the computer is rarely necessary.
|
|
|
7
21
|
|
|
8
22
|
## A port is already in use
|
|
9
23
|
|
|
10
|
-
|
|
11
|
-
|
|
24
|
+
Rerun `rehearsal setup` to select a different available block. Setup checks both active
|
|
25
|
+
listeners and whether every selected port can be bound, then checks again before writing.
|
|
26
|
+
For an existing configuration, choose unique non-privileged ports and mirror them in the
|
|
27
|
+
dedicated Supabase config. Do not stop an unrelated database to make defaults fit.
|
|
12
28
|
|
|
13
29
|
## Baseline checksum mismatch
|
|
14
30
|
|
package/package.json
CHANGED
|
@@ -19,6 +19,7 @@ import {
|
|
|
19
19
|
createMigrationReplayReceipt,
|
|
20
20
|
readMigrationSourceBundle,
|
|
21
21
|
} from "./migration_history.mjs";
|
|
22
|
+
import { validateRuntimeSanitizationPolicy } from "./sanitization_policy.mjs";
|
|
22
23
|
|
|
23
24
|
const resolveProjectInput = (projectRoot, value, label) => {
|
|
24
25
|
if (typeof value !== "string" || value.trim() === "") {
|
|
@@ -103,10 +104,9 @@ export const createSyntheticBaselineFromFiles = async ({
|
|
|
103
104
|
})),
|
|
104
105
|
)
|
|
105
106
|
: [];
|
|
106
|
-
const policy =
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
}
|
|
107
|
+
const policy = validateRuntimeSanitizationPolicy(
|
|
108
|
+
JSON.parse(policyBytes.toString("utf8")),
|
|
109
|
+
);
|
|
110
110
|
const expectedTables = policy.tables
|
|
111
111
|
.filter((table) => table.sourceRows !== "EXCLUDE")
|
|
112
112
|
.map((table) => table.name);
|
|
@@ -117,6 +117,11 @@ export const createSyntheticBaselineFromFiles = async ({
|
|
|
117
117
|
JSON.parse(ledgerBytes.toString("utf8")),
|
|
118
118
|
"Synthetic migration ledger",
|
|
119
119
|
);
|
|
120
|
+
if (policy.migrationCutoff !== sourceMigrationHistory.at(-1).version) {
|
|
121
|
+
throw new Error(
|
|
122
|
+
`The sanitization policy cutoff ${policy.migrationCutoff} does not match migration ledger cutoff ${sourceMigrationHistory.at(-1).version}.`,
|
|
123
|
+
);
|
|
124
|
+
}
|
|
120
125
|
const migrationFiles = await readMigrationSourceBundle({
|
|
121
126
|
directory: new URL(
|
|
122
127
|
"./",
|
|
@@ -148,8 +153,8 @@ export const createSyntheticBaselineFromFiles = async ({
|
|
|
148
153
|
return {
|
|
149
154
|
generationId,
|
|
150
155
|
migrationCutoff: baseline.migrationCutoff,
|
|
151
|
-
migrationCount: baseline.
|
|
156
|
+
migrationCount: Object.keys(baseline.migrations).length,
|
|
152
157
|
rowCount: baseline.rowCount,
|
|
153
|
-
tableCount: baseline.
|
|
158
|
+
tableCount: Object.keys(baseline.tableCounts).length,
|
|
154
159
|
};
|
|
155
160
|
};
|