@rehearsal-db/core 0.1.0-beta.7 → 0.1.0-beta.9
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 +77 -1
- package/COMPATIBILITY.md +15 -3
- package/README.md +31 -13
- package/docs/README.md +29 -0
- package/docs/adapters.md +15 -6
- package/docs/architecture.md +58 -0
- package/docs/baselines.md +22 -1
- package/docs/commands.md +81 -14
- package/docs/configuration.md +144 -11
- package/docs/getting-started.md +12 -2
- package/docs/glossary.md +4 -0
- package/docs/production-source.md +176 -33
- package/docs/roadmap.md +30 -28
- package/docs/runtime-policies.md +191 -0
- package/docs/sanitization.md +24 -8
- package/docs/security-model.md +29 -8
- package/docs/standalone-workflow.md +107 -0
- package/docs/troubleshooting.md +8 -0
- package/package.json +25 -22
- package/scripts/runtime/manage_database.mjs +18 -0
- package/src/README.md +17 -0
- package/src/application/session.mjs +313 -0
- package/{scripts/lib/rehearsal/baseline_artifact.mjs → src/baseline/artifact.mjs} +110 -14
- package/{scripts/lib/rehearsal/baseline_builder.mjs → src/baseline/builder.mjs} +8 -4
- package/{scripts/lib/rehearsal/baseline_preparation.mjs → src/baseline/preparation.mjs} +11 -4
- package/src/baseline/privacy_engine.mjs +413 -0
- package/{scripts/lib/rehearsal → src/baseline}/sanitization_policy.mjs +27 -7
- package/{scripts/lib/rehearsal → src/baseline}/schema_snapshot.mjs +1 -1
- package/src/cli/arguments.mjs +120 -0
- package/src/cli/guided.mjs +807 -0
- package/src/cli/rehearsal.mjs +933 -0
- package/src/cli/renderers.mjs +584 -0
- package/src/cli/runtime_commands.mjs +553 -0
- package/src/cli/source_commands.mjs +326 -0
- package/src/cli/terminal.mjs +275 -0
- package/src/identity/claim.mjs +975 -0
- package/src/identity/storage.mjs +165 -0
- package/{scripts/lib/rehearsal → src/project}/configuration.d.mts +34 -0
- package/{scripts/lib/rehearsal → src/project}/configuration.mjs +353 -3
- package/{scripts/lib/rehearsal → src/project}/setup.mjs +1 -1
- package/{scripts/lib/rehearsal → src/project}/support_report.mjs +5 -2
- package/{scripts/lib/rehearsal → src/runtime}/cleanup.mjs +3 -3
- package/{scripts/lib/rehearsal → src/runtime}/plan.mjs +5 -5
- package/src/runtime/policy.mjs +438 -0
- package/{scripts/lib/rehearsal/runtime_restore.mjs → src/runtime/restore.mjs} +40 -25
- package/src/runtime/topology.mjs +177 -0
- package/{scripts/lib/rehearsal → src/shared}/diagnostics.mjs +1 -1
- package/src/shared/operation_guard.mjs +162 -0
- package/{scripts/lib/rehearsal → src/shared}/process_environment.mjs +5 -1
- package/src/source/access.mjs +578 -0
- package/src/source/asset_transfer.mjs +177 -0
- package/src/source/baseline.mjs +446 -0
- package/src/source/postgresql_access.mjs +480 -0
- package/{scripts/lib/runtime/postgresql_runtime.mjs → src/targets/postgresql.mjs} +49 -13
- package/{scripts/lib/runtime/supabase_runtime.mjs → src/targets/supabase.mjs} +54 -16
- package/{scripts/lib/environment/local_supabase.mjs → src/targets/supabase_environment.mjs} +52 -20
- package/{scripts/lib/runtime/runtime_target.mjs → src/targets/target.mjs} +27 -2
- package/scripts/operations/database/manage_rehearsal_database.mjs +0 -11
- package/scripts/operations/rehearsal/rehearsal_cli.mjs +0 -2166
- /package/{scripts/lib/rehearsal → src/baseline}/input_discovery.mjs +0 -0
- /package/{scripts/lib/rehearsal → src/baseline}/policy_review.mjs +0 -0
- /package/{scripts/lib/rehearsal → src/runtime}/migration_history.mjs +0 -0
- /package/{scripts/lib/rehearsal → src/runtime}/service_environment.mjs +0 -0
- /package/{scripts/lib/rehearsal → src/shared}/human_output.mjs +0 -0
|
@@ -0,0 +1,191 @@
|
|
|
1
|
+
# Runtime and identity policies
|
|
2
|
+
|
|
3
|
+
These optional JSON files replace common project-owned Rehearsal adapters. They contain
|
|
4
|
+
declarations only: unknown fields, SQL, JavaScript, and unsupported extensions fail.
|
|
5
|
+
|
|
6
|
+
## Runtime policy
|
|
7
|
+
|
|
8
|
+
Point `runtimePolicy` in `rehearsal.config.mjs` to a reviewed file:
|
|
9
|
+
|
|
10
|
+
```json
|
|
11
|
+
{
|
|
12
|
+
"policyVersion": 1,
|
|
13
|
+
"prerequisites": {
|
|
14
|
+
"schemas": ["extensions"],
|
|
15
|
+
"extensions": [{ "name": "pgcrypto", "schema": "extensions" }]
|
|
16
|
+
},
|
|
17
|
+
"triggers": [
|
|
18
|
+
{
|
|
19
|
+
"name": "profile_after_auth_insert",
|
|
20
|
+
"table": { "schema": "auth", "name": "users" },
|
|
21
|
+
"timing": "after",
|
|
22
|
+
"events": ["insert"],
|
|
23
|
+
"function": { "schema": "public", "name": "handle_new_user" }
|
|
24
|
+
}
|
|
25
|
+
],
|
|
26
|
+
"localRows": [
|
|
27
|
+
{
|
|
28
|
+
"table": { "schema": "public", "name": "runtime_settings" },
|
|
29
|
+
"keyColumns": ["name"],
|
|
30
|
+
"values": { "name": "scheduler_enabled", "value": false }
|
|
31
|
+
},
|
|
32
|
+
{
|
|
33
|
+
"table": { "schema": "public", "name": "app_role_assignments" },
|
|
34
|
+
"keyColumns": ["user_id"],
|
|
35
|
+
"values": {
|
|
36
|
+
"user_id": "11111111-1111-4111-8111-111111111111",
|
|
37
|
+
"role": "owner"
|
|
38
|
+
},
|
|
39
|
+
"identityAssociation": {
|
|
40
|
+
"identity": "approved-owner",
|
|
41
|
+
"column": "user_id"
|
|
42
|
+
}
|
|
43
|
+
}
|
|
44
|
+
],
|
|
45
|
+
"expectations": [
|
|
46
|
+
{
|
|
47
|
+
"table": { "schema": "public", "name": "profiles" },
|
|
48
|
+
"rowLevelSecurity": true,
|
|
49
|
+
"columns": [{ "name": "id", "generated": false, "identity": false }],
|
|
50
|
+
"foreignKeys": [],
|
|
51
|
+
"policies": []
|
|
52
|
+
}
|
|
53
|
+
]
|
|
54
|
+
}
|
|
55
|
+
```
|
|
56
|
+
|
|
57
|
+
Restore order is fixed: Rehearsal creates named schemas and allowlisted extensions
|
|
58
|
+
before dependent schema objects, adds declared triggers after their tables and functions
|
|
59
|
+
exist, then inserts local-only rows after baseline data. Application schema remains in
|
|
60
|
+
immutable migrations or the verified schema snapshot. Verification checks extensions,
|
|
61
|
+
triggers, local-only rows, columns, generated/identity behavior, foreign keys, named RLS
|
|
62
|
+
policies, RLS state, and unvalidated constraints.
|
|
63
|
+
|
|
64
|
+
Use `identityAssociation` when a local seed is intentionally transferred by a named
|
|
65
|
+
identity policy. Verification accepts the configured placeholder before association and
|
|
66
|
+
the exact recorded local identity afterward. Rehearsal stores that mapping only in its
|
|
67
|
+
local internal schema; it does not duplicate the old role or weaken the row check.
|
|
68
|
+
|
|
69
|
+
## Identity policy
|
|
70
|
+
|
|
71
|
+
The identity policy links one verified local Supabase identity to a copied pseudonymous
|
|
72
|
+
graph without an application callback patch:
|
|
73
|
+
|
|
74
|
+
```json
|
|
75
|
+
{
|
|
76
|
+
"identityVersion": 1,
|
|
77
|
+
"identities": [
|
|
78
|
+
{
|
|
79
|
+
"name": "approved-owner",
|
|
80
|
+
"provider": "google",
|
|
81
|
+
"emailEnvironmentVariable": "REHEARSAL_APPROVED_OWNER_EMAIL",
|
|
82
|
+
"approvedEmailSha256": "<sha256 of the lowercase approved email>",
|
|
83
|
+
"placeholderUserId": "11111111-1111-4111-8111-111111111111",
|
|
84
|
+
"references": [
|
|
85
|
+
{
|
|
86
|
+
"schema": "public",
|
|
87
|
+
"table": "profiles",
|
|
88
|
+
"column": "user_id",
|
|
89
|
+
"required": true
|
|
90
|
+
},
|
|
91
|
+
{
|
|
92
|
+
"schema": "public",
|
|
93
|
+
"table": "app_role_assignments",
|
|
94
|
+
"column": "user_id",
|
|
95
|
+
"required": true
|
|
96
|
+
},
|
|
97
|
+
{
|
|
98
|
+
"schema": "public",
|
|
99
|
+
"table": "food_compatibility_feedback",
|
|
100
|
+
"column": "reviewed_by",
|
|
101
|
+
"required": true,
|
|
102
|
+
"strategy": "preserve-audit"
|
|
103
|
+
}
|
|
104
|
+
],
|
|
105
|
+
"jsonReferences": [
|
|
106
|
+
{
|
|
107
|
+
"schema": "public",
|
|
108
|
+
"table": "events",
|
|
109
|
+
"column": "payload",
|
|
110
|
+
"path": ["actor_id"]
|
|
111
|
+
}
|
|
112
|
+
],
|
|
113
|
+
"signupDefaults": [
|
|
114
|
+
{
|
|
115
|
+
"table": { "schema": "public", "table": "profiles" },
|
|
116
|
+
"identityColumn": "user_id",
|
|
117
|
+
"ignoredColumns": ["created_at", "updated_at"],
|
|
118
|
+
"values": {
|
|
119
|
+
"display_name": {
|
|
120
|
+
"kind": "pattern",
|
|
121
|
+
"pattern": "^User[0-9]{14}$"
|
|
122
|
+
},
|
|
123
|
+
"avatar_path": null
|
|
124
|
+
}
|
|
125
|
+
}
|
|
126
|
+
],
|
|
127
|
+
"pathReferences": [
|
|
128
|
+
{
|
|
129
|
+
"schema": "public",
|
|
130
|
+
"table": "profiles",
|
|
131
|
+
"column": "avatar_path",
|
|
132
|
+
"valueType": "text"
|
|
133
|
+
}
|
|
134
|
+
],
|
|
135
|
+
"assets": [
|
|
136
|
+
{
|
|
137
|
+
"bucket": "avatars",
|
|
138
|
+
"prefix": "11111111-1111-4111-8111-111111111111/",
|
|
139
|
+
"rewritePath": true
|
|
140
|
+
}
|
|
141
|
+
],
|
|
142
|
+
"claims": { "rehearsal_owner": true },
|
|
143
|
+
"tokenHook": {
|
|
144
|
+
"function": {
|
|
145
|
+
"schema": "public",
|
|
146
|
+
"name": "custom_access_token_hook"
|
|
147
|
+
},
|
|
148
|
+
"expectedClaims": { "app_role": "developer" }
|
|
149
|
+
}
|
|
150
|
+
}
|
|
151
|
+
]
|
|
152
|
+
}
|
|
153
|
+
```
|
|
154
|
+
|
|
155
|
+
The email stays in an environment variable; only its reviewed hash is committed. After
|
|
156
|
+
ordinary local sign-in creates the account, preview and confirm the association:
|
|
157
|
+
|
|
158
|
+
```bash
|
|
159
|
+
npx rehearsal identity plan --identity=approved-owner
|
|
160
|
+
npx rehearsal identity claim --identity=approved-owner \
|
|
161
|
+
--confirm-identity=<full-sha256>
|
|
162
|
+
```
|
|
163
|
+
|
|
164
|
+
Rehearsal requires exactly one verified matching local provider identity. Every
|
|
165
|
+
`required` reference must exist after transfer. Declare application role tables as
|
|
166
|
+
references; `claims` alone is not a replacement for a database-backed token hook.
|
|
167
|
+
|
|
168
|
+
References use `"strategy": "transfer"` by default. Use `"preserve-audit"` only for
|
|
169
|
+
immutable historical authorship, such as a completed review. Rehearsal leaves that row
|
|
170
|
+
and its synthetic Auth actor unchanged, but still transfers the active profile, roles,
|
|
171
|
+
and other declared data. Undeclared references still stop the claim.
|
|
172
|
+
|
|
173
|
+
`signupDefaults` resolves a copied-profile collision only when the local row's complete
|
|
174
|
+
non-ignored shape matches. List every remaining column. Use ignored columns only for
|
|
175
|
+
server-managed values such as timestamps. An edited value, extra column, ambiguous row,
|
|
176
|
+
or unrelated local application data rolls back the entire claim.
|
|
177
|
+
|
|
178
|
+
`rewritePath` copies approved Storage objects through the local Supabase Storage API,
|
|
179
|
+
verifies the destination bytes, updates the declared database paths, and then removes
|
|
180
|
+
the old objects. A database failure removes the new copies and leaves the originals
|
|
181
|
+
usable. Restored objects may begin with either the placeholder owner or no owner;
|
|
182
|
+
another owner is refused. `pathReferences` updates matching text or JSONB pointers. A configured
|
|
183
|
+
`tokenHook` must return the declared claim subset before commit. The browser must then
|
|
184
|
+
refresh its session or sign in again because Rehearsal cannot rewrite an issued JWT.
|
|
185
|
+
|
|
186
|
+
The transaction does not import production passwords, sessions, refresh tokens,
|
|
187
|
+
cookies, MFA secrets, or provider credentials. Local MFA and authorization rules remain
|
|
188
|
+
real.
|
|
189
|
+
|
|
190
|
+
A synthetic test can prove the plumbing and refusal controls. Claim that Google account
|
|
191
|
+
selection or callback behavior works only after directly observing that real flow.
|
package/docs/sanitization.md
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
# Sanitization policy
|
|
2
2
|
|
|
3
|
-
Rehearsal
|
|
4
|
-
|
|
3
|
+
Rehearsal never decides what your application may copy. The project owner reviews an
|
|
4
|
+
exhaustive policy; the package validates and executes the supported recipes.
|
|
5
5
|
|
|
6
6
|
Every exported field should receive one action:
|
|
7
7
|
|
|
@@ -19,6 +19,10 @@ whether it is an identity column, and its foreign-key target or explicit absence
|
|
|
19
19
|
draft uses `REVIEW REQUIRED` placeholders and cannot be activated until they are
|
|
20
20
|
replaced and the `draft` marker is removed.
|
|
21
21
|
|
|
22
|
+
Tables default to the `public` schema. Add `"schema": "app_api"` beside `name`
|
|
23
|
+
for another schema. Schema plus table is the identity, so two schemas may safely contain
|
|
24
|
+
tables with the same name.
|
|
25
|
+
|
|
22
26
|
In an interactive terminal, the guided **Review the script** action works table by table.
|
|
23
27
|
For larger tables, a human can explicitly apply safe defaults (`REPLACE`, `NEVER`
|
|
24
28
|
generated, `NO` identity, and no foreign key), then review only exceptions. Likely
|
|
@@ -28,8 +32,20 @@ labeled as sensitive, every saved field remains classified, and no preset is sil
|
|
|
28
32
|
applied. The reviewer validates the completed policy and refuses to overwrite a draft
|
|
29
33
|
changed during the session.
|
|
30
34
|
|
|
31
|
-
|
|
32
|
-
|
|
35
|
+
Two policy versions exist:
|
|
36
|
+
|
|
37
|
+
- Version 1 describes data that a project has already made safe. It remains supported
|
|
38
|
+
for synthetic/local inputs and existing baselines.
|
|
39
|
+
- Version 2 is required by `baseline refresh`. It adds bounded declarative recipes so
|
|
40
|
+
Rehearsal can sanitize without project callbacks.
|
|
41
|
+
|
|
42
|
+
Version 2 supports keyed UUID, email, text, and integer pseudonyms; explicit constant
|
|
43
|
+
replacement; bounded date shifting; and exhaustively classified JSON objects. Unknown
|
|
44
|
+
tables, columns, nested keys, formats, recipes, or missing fields fail closed. It never
|
|
45
|
+
evaluates JavaScript or SQL from the policy.
|
|
46
|
+
|
|
47
|
+
The package still exports `validateSanitizationCoverage` and
|
|
48
|
+
`applySanitizationAction` for existing version 1 preparation tools:
|
|
33
49
|
|
|
34
50
|
```ts
|
|
35
51
|
import {
|
|
@@ -50,15 +66,15 @@ const safeValue = applySanitizationAction({
|
|
|
50
66
|
```
|
|
51
67
|
|
|
52
68
|
Coverage validation requires a one-to-one table and column match: missing and unknown
|
|
53
|
-
entries both fail.
|
|
54
|
-
|
|
69
|
+
entries both fail. New standalone preparation should use the version 2 engine described
|
|
70
|
+
in [Production source](production-source.md).
|
|
55
71
|
|
|
56
72
|
## Stable identity
|
|
57
73
|
|
|
58
74
|
Use keyed, deterministic pseudonyms when relationships must survive across tables.
|
|
59
|
-
Keep the key outside source control and
|
|
75
|
+
Keep the key under `.rehearsal`, outside source control and the final baseline. The same source ID
|
|
60
76
|
should map consistently within a generation, while the original value cannot be
|
|
61
|
-
recovered from the artifact.
|
|
77
|
+
recovered from the artifact. The manifest records only the key fingerprint.
|
|
62
78
|
|
|
63
79
|
## High-risk fields
|
|
64
80
|
|
package/docs/security-model.md
CHANGED
|
@@ -5,10 +5,10 @@ misconfiguration fail closed before a state-changing operation.
|
|
|
5
5
|
|
|
6
6
|
## Trust boundaries
|
|
7
7
|
|
|
8
|
-
The engine trusts
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
8
|
+
The engine trusts reviewed package code, strict declarations, a verified active baseline,
|
|
9
|
+
and exact migration bytes. It does not trust ambient environment variables, hosted
|
|
10
|
+
project state, unknown fields, changed history, incomplete artifacts, or an unverified
|
|
11
|
+
runtime.
|
|
12
12
|
|
|
13
13
|
## Independent barriers
|
|
14
14
|
|
|
@@ -24,9 +24,20 @@ changed migration history, incomplete artifacts, or an unverified runtime.
|
|
|
24
24
|
- plain PostgreSQL receives a fresh random password per disposable runtime, retained
|
|
25
25
|
only in owner-readable ignored runtime files;
|
|
26
26
|
- successful receipts written only after verification.
|
|
27
|
+
- separate exact-digest approval for source setup, source retirement, and identity claim;
|
|
28
|
+
- short-lived source readers limited to reviewed views/columns and deny checks;
|
|
29
|
+
- bounded read-only extraction with no raw dump or row-value logging;
|
|
30
|
+
- exhaustive privacy policy version 2 with an owner-only local pseudonym key;
|
|
31
|
+
- application children receive only explicit local mappings and stay in an owned process
|
|
32
|
+
group.
|
|
33
|
+
- only one state-changing Rehearsal command may own a project at a time; stale locks are
|
|
34
|
+
recovered after their process exits;
|
|
35
|
+
- a state-changing command fingerprints its installed Rehearsal package and refuses to
|
|
36
|
+
continue if that installation changes while the command is running.
|
|
27
37
|
|
|
28
|
-
No single environment variable or config edit
|
|
29
|
-
|
|
38
|
+
No single environment variable or config edit can redirect runtime commands to
|
|
39
|
+
production. Optional source preparation is a separate boundary and never provides a
|
|
40
|
+
hosted execution mode.
|
|
30
41
|
|
|
31
42
|
## Identity providers
|
|
32
43
|
|
|
@@ -35,10 +46,20 @@ credential names are read from an ignored owner-only file, and the callback must
|
|
|
35
46
|
local Auth. The local account may represent a sanitized production identity, but its
|
|
36
47
|
session and writes remain local.
|
|
37
48
|
|
|
49
|
+
Account association is one local transaction. Rehearsal removes a signup-created row
|
|
50
|
+
only when its complete declared default shape still matches, refuses unrelated local
|
|
51
|
+
application data, verifies required role references and an optional token hook, and can
|
|
52
|
+
copy, byte-check, and retire only declared placeholder-owned Storage paths. Immutable
|
|
53
|
+
audit references may explicitly retain their synthetic historical actor. Rehearsal also
|
|
54
|
+
refuses to rewrite application paths when copied records refer to files that are absent
|
|
55
|
+
from local Storage. Existing browser JWTs still require an ordinary refresh or new
|
|
56
|
+
sign-in.
|
|
57
|
+
|
|
38
58
|
## Remaining responsibilities
|
|
39
59
|
|
|
40
60
|
Rehearsal cannot prove that retained data is lawful, a sanitization rule is ethically
|
|
41
|
-
appropriate, a migration has the intended business meaning, or a
|
|
42
|
-
|
|
61
|
+
appropriate, a migration has the intended business meaning, or a real provider flow was
|
|
62
|
+
observed. Repository owners must review those decisions and protect artifacts. The
|
|
63
|
+
configuration barriers are not an operating-system firewall.
|
|
43
64
|
|
|
44
65
|
Report vulnerabilities using the private process in the root security policy.
|
|
@@ -0,0 +1,107 @@
|
|
|
1
|
+
# Standalone workflow contract
|
|
2
|
+
|
|
3
|
+
Rehearsal's normal commands remain local-only. `run`, `start`, `reset`,
|
|
4
|
+
`migrate`, `verify`, and `cleanup` never receive source credentials and never
|
|
5
|
+
connect to a hosted database.
|
|
6
|
+
|
|
7
|
+
The optional preparation workflow is a separate security boundary. It has
|
|
8
|
+
three deliberately separate phases:
|
|
9
|
+
|
|
10
|
+
1. `source plan` reads declarations and produces a redacted, exact plan.
|
|
11
|
+
2. `source apply` requires the plan digest and source-owner credentials from a
|
|
12
|
+
named environment variable. It creates only the declared, time-limited
|
|
13
|
+
reader and export surface.
|
|
14
|
+
3. `refresh` uses that reader in a read-only repeatable-read transaction, builds
|
|
15
|
+
privately, activates only after verification, resets the local runtime, and applies
|
|
16
|
+
reviewed retention. `baseline refresh` is the lower-level baseline-only form.
|
|
17
|
+
|
|
18
|
+
`source retire` has its own preview and digest. It removes only the exact
|
|
19
|
+
reader and export objects Rehearsal recorded. It never searches for similarly
|
|
20
|
+
named roles or removes unrelated grants.
|
|
21
|
+
|
|
22
|
+
## What belongs in declarations
|
|
23
|
+
|
|
24
|
+
Projects declare application meaning; Rehearsal executes it. Declarations may
|
|
25
|
+
name:
|
|
26
|
+
|
|
27
|
+
- approved source relations and columns;
|
|
28
|
+
- whether rows are approved public data or belong to one explicitly approved
|
|
29
|
+
owner;
|
|
30
|
+
- privacy actions and bounded transformation recipes;
|
|
31
|
+
- licensed or consented Storage buckets and prefixes;
|
|
32
|
+
- schema and extension prerequisites;
|
|
33
|
+
- local identities and reference locations;
|
|
34
|
+
- ordinary application commands and observable proof expectations.
|
|
35
|
+
|
|
36
|
+
Declarations cannot contain JavaScript callbacks, SQL fragments, passwords,
|
|
37
|
+
tokens, production URLs, or automatic consent decisions. Unknown fields,
|
|
38
|
+
tables, columns, recipes, JSON keys, and target identities fail closed.
|
|
39
|
+
|
|
40
|
+
## Credential separation
|
|
41
|
+
|
|
42
|
+
Provisioning, extraction, asset, provider, and local-runtime credentials are
|
|
43
|
+
separate. A declaration contains only the name of an environment variable or
|
|
44
|
+
owner-only secret file. Rehearsal never puts credential values in command-line
|
|
45
|
+
arguments, reports, baselines, receipts, or a launched application.
|
|
46
|
+
|
|
47
|
+
The current workflow creates and verifies its own temporary PostgreSQL reader. An
|
|
48
|
+
externally provisioned reader is not yet accepted because Rehearsal cannot currently
|
|
49
|
+
prove that reader's complete scope and retirement behavior.
|
|
50
|
+
|
|
51
|
+
## Snapshot and privacy guarantees
|
|
52
|
+
|
|
53
|
+
Database schema, migration evidence, and selected rows are read in one
|
|
54
|
+
read-only repeatable-read PostgreSQL transaction. Rehearsal rechecks the source
|
|
55
|
+
identity and migration evidence before commit. Rows stream in bounded batches;
|
|
56
|
+
record bodies never appear in progress or error output.
|
|
57
|
+
|
|
58
|
+
Storage objects do not share the database transaction guarantee. Their inventory records
|
|
59
|
+
size and version metadata; transfer requires that version, verifies the exact byte count,
|
|
60
|
+
and records a SHA-256 in the immutable baseline. Transfer refuses an object that changes,
|
|
61
|
+
exceeds its declared limit, or falls outside an approved bucket and prefix.
|
|
62
|
+
|
|
63
|
+
Privacy policy version 2 is executable without project sanitizer code. It
|
|
64
|
+
supports exact keep, exclusion, keyed pseudonyms, constants, and a small set of
|
|
65
|
+
documented derivations. Policies classify every selected field and supported
|
|
66
|
+
nested JSON key. A new or unknown field blocks refresh until the policy is
|
|
67
|
+
reviewed again.
|
|
68
|
+
|
|
69
|
+
The pseudonym key is an owner-only local secret. It is not stored in the
|
|
70
|
+
baseline or source control. Receipts bind the policy bytes, schema shape,
|
|
71
|
+
source scope, migration evidence, and key fingerprint without storing the key
|
|
72
|
+
or source identifiers.
|
|
73
|
+
|
|
74
|
+
## Restore, identities, and applications
|
|
75
|
+
|
|
76
|
+
Restore performs only supported declarative prerequisites. Application schema
|
|
77
|
+
changes remain immutable migration files; configuration is never an arbitrary
|
|
78
|
+
privileged-SQL escape hatch.
|
|
79
|
+
|
|
80
|
+
Local identities never reuse production sessions, refresh tokens, password
|
|
81
|
+
hashes, provider secrets, or MFA material. An approved provider association is
|
|
82
|
+
performed inside the local runtime and must match the reviewed receipt.
|
|
83
|
+
|
|
84
|
+
Rehearsal launches ordinary project commands with a minimal environment and
|
|
85
|
+
generated local connection files. It verifies every configured dependency
|
|
86
|
+
before launch, owns only the child process group it starts, and does not claim
|
|
87
|
+
to provide an operating-system firewall.
|
|
88
|
+
|
|
89
|
+
Proofs require explicit positives and negatives. A process starting, a non-5xx
|
|
90
|
+
response, an empty 200, a 401, or a 404 cannot satisfy a declared positive.
|
|
91
|
+
Reports distinguish engine readiness, dependency readiness, proof completion,
|
|
92
|
+
and provider behavior that was directly observed by a person.
|
|
93
|
+
|
|
94
|
+
## Failure and upgrade behavior
|
|
95
|
+
|
|
96
|
+
- Failed, interrupted, changed-policy, low-disk, or drifted refreshes leave the
|
|
97
|
+
prior active baseline and any edited runtime untouched.
|
|
98
|
+
- Setup and upgrades preview exact file changes and never overwrite a reviewed
|
|
99
|
+
policy, config, baseline, or local edit silently.
|
|
100
|
+
- Reset, discard, and cleanup operate only on purpose-created Rehearsal
|
|
101
|
+
resources and retain their existing exact-preview protections.
|
|
102
|
+
- Rehearsal does not make legal, consent, licensing, backup, disaster-recovery,
|
|
103
|
+
universal-database, or OS-firewall guarantees.
|
|
104
|
+
|
|
105
|
+
The final acceptance gate uses the exact packed or published artifact in clean
|
|
106
|
+
Supabase and PostgreSQL consumers. Consumer integration code is removed only
|
|
107
|
+
after that replacement is proved and the removal is separately approved.
|
package/docs/troubleshooting.md
CHANGED
|
@@ -114,6 +114,14 @@ rerun doctor and candidates, then execute with the new digest.
|
|
|
114
114
|
Run the project proof directly against the generated local environment. Fix the app,
|
|
115
115
|
adapter, fixture expectation, or migration; do not weaken the proof to obtain a pass.
|
|
116
116
|
|
|
117
|
+
## The local application loads a hosted value from `.env`
|
|
118
|
+
|
|
119
|
+
Rehearsal removes undeclared hosted credentials from the child process environment, but
|
|
120
|
+
frameworks such as Vite may independently read project `.env` files after the process
|
|
121
|
+
starts. Give the configured `startCommand` or framework test mode an explicit safe local
|
|
122
|
+
override for the affected value. Do not delete or rewrite a developer's normal `.env`
|
|
123
|
+
file as part of a rehearsal.
|
|
124
|
+
|
|
117
125
|
## Local authentication fails
|
|
118
126
|
|
|
119
127
|
Confirm the provider is enabled in the dedicated local Supabase config, the allowlisted
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@rehearsal-db/core",
|
|
3
|
-
"version": "0.1.0-beta.
|
|
3
|
+
"version": "0.1.0-beta.9",
|
|
4
4
|
"private": false,
|
|
5
5
|
"description": "Safely rehearse PostgreSQL and Supabase migrations against sanitized, production-shaped data.",
|
|
6
6
|
"repository": {
|
|
@@ -21,27 +21,26 @@
|
|
|
21
21
|
"node": ">=24 <25"
|
|
22
22
|
},
|
|
23
23
|
"bin": {
|
|
24
|
-
"rehearsal": "
|
|
24
|
+
"rehearsal": "src/cli/rehearsal.mjs"
|
|
25
25
|
},
|
|
26
26
|
"exports": {
|
|
27
27
|
".": {
|
|
28
|
-
"types": "./
|
|
29
|
-
"import": "./
|
|
28
|
+
"types": "./src/project/configuration.d.mts",
|
|
29
|
+
"import": "./src/project/configuration.mjs"
|
|
30
30
|
},
|
|
31
|
-
"./baseline": "./
|
|
32
|
-
"./baseline-builder": "./
|
|
33
|
-
"./diagnostics": "./
|
|
34
|
-
"./migrations": "./
|
|
35
|
-
"./process-environment": "./
|
|
36
|
-
"./
|
|
37
|
-
"./
|
|
31
|
+
"./baseline": "./src/baseline/artifact.mjs",
|
|
32
|
+
"./baseline-builder": "./src/baseline/builder.mjs",
|
|
33
|
+
"./diagnostics": "./src/shared/diagnostics.mjs",
|
|
34
|
+
"./migrations": "./src/runtime/migration_history.mjs",
|
|
35
|
+
"./process-environment": "./src/shared/process_environment.mjs",
|
|
36
|
+
"./privacy": "./src/baseline/privacy_engine.mjs",
|
|
37
|
+
"./schema": "./src/baseline/schema_snapshot.mjs",
|
|
38
|
+
"./service-environment": "./src/runtime/service_environment.mjs",
|
|
39
|
+
"./source-access": "./src/source/access.mjs"
|
|
38
40
|
},
|
|
39
41
|
"files": [
|
|
40
|
-
"
|
|
41
|
-
"scripts/
|
|
42
|
-
"scripts/lib/runtime",
|
|
43
|
-
"scripts/operations/database/manage_rehearsal_database.mjs",
|
|
44
|
-
"scripts/operations/rehearsal/rehearsal_cli.mjs",
|
|
42
|
+
"src",
|
|
43
|
+
"scripts/runtime/manage_database.mjs",
|
|
45
44
|
"docs/*.md",
|
|
46
45
|
"README.md",
|
|
47
46
|
"BENCHMARKS.md",
|
|
@@ -53,15 +52,18 @@
|
|
|
53
52
|
],
|
|
54
53
|
"scripts": {
|
|
55
54
|
"test": "vitest run",
|
|
56
|
-
"test:unit": "vitest run tests/
|
|
55
|
+
"test:unit": "vitest run tests/unit",
|
|
56
|
+
"test:integration": "vitest run tests/integration tests/contracts",
|
|
57
57
|
"test:docs": "vitest run tests/contracts/documentationCommands.test.mjs",
|
|
58
|
-
"test:fixture": "node scripts/
|
|
59
|
-
"test:fixture:postgresql": "node scripts/
|
|
58
|
+
"test:fixture": "node scripts/verification/fixtures/supabase.mjs",
|
|
59
|
+
"test:fixture:postgresql": "node scripts/verification/fixtures/postgresql.mjs",
|
|
60
|
+
"test:fixture:dependent": "node scripts/verification/fixtures/dependent.mjs",
|
|
61
|
+
"test:fixture:standalone": "node scripts/verification/fixtures/standalone.mjs",
|
|
60
62
|
"check": "npm run check:syntax && npm run test && npm run format:check && npm run package:audit",
|
|
61
|
-
"check:syntax": "find scripts tests -type f -name '*.mjs' -exec node --check {} +",
|
|
63
|
+
"check:syntax": "find src scripts tests -type f -name '*.mjs' -exec node --check {} +",
|
|
62
64
|
"format": "prettier --write .",
|
|
63
65
|
"format:check": "prettier --check .",
|
|
64
|
-
"package:audit": "node scripts/
|
|
66
|
+
"package:audit": "node scripts/verification/audit_package.mjs"
|
|
65
67
|
},
|
|
66
68
|
"keywords": [
|
|
67
69
|
"postgresql",
|
|
@@ -72,7 +74,8 @@
|
|
|
72
74
|
],
|
|
73
75
|
"license": "MIT",
|
|
74
76
|
"dependencies": {
|
|
75
|
-
"@clack/prompts": "^1.8.1"
|
|
77
|
+
"@clack/prompts": "^1.8.1",
|
|
78
|
+
"pg": "^8.23.1"
|
|
76
79
|
},
|
|
77
80
|
"devDependencies": {
|
|
78
81
|
"@lydell/node-pty": "^1.2.0-beta.15",
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
/**
|
|
3
|
+
* Purpose: Select the configured database runtime and forward the requested
|
|
4
|
+
* lifecycle action to its isolated driver.
|
|
5
|
+
*/
|
|
6
|
+
|
|
7
|
+
import { loadRehearsalConfig } from "../../src/project/configuration.mjs";
|
|
8
|
+
import {
|
|
9
|
+
parseRuntimeInvocation,
|
|
10
|
+
runRuntimeTarget,
|
|
11
|
+
} from "../../src/targets/target.mjs";
|
|
12
|
+
|
|
13
|
+
const invocation = parseRuntimeInvocation();
|
|
14
|
+
const { config } = await loadRehearsalConfig({
|
|
15
|
+
projectRoot: process.cwd(),
|
|
16
|
+
configPath: invocation.configPath,
|
|
17
|
+
});
|
|
18
|
+
await runRuntimeTarget(config.runtime.target);
|
package/src/README.md
ADDED
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
# Source layout
|
|
2
|
+
|
|
3
|
+
Production code is grouped by the responsibility it owns:
|
|
4
|
+
|
|
5
|
+
- `application/` starts and proves the project application.
|
|
6
|
+
- `baseline/` creates, validates, and stores safe baseline artifacts.
|
|
7
|
+
- `cli/` is the human and automation entry point.
|
|
8
|
+
- `identity/` associates copied data with verified local users.
|
|
9
|
+
- `project/` owns configuration, setup, and support reporting.
|
|
10
|
+
- `runtime/` plans, verifies, resets, migrates, and cleans local runtimes.
|
|
11
|
+
- `shared/` contains small target-neutral infrastructure.
|
|
12
|
+
- `source/` controls approved source access and baseline refresh.
|
|
13
|
+
- `targets/` contains the PostgreSQL and Supabase runtime adapters.
|
|
14
|
+
|
|
15
|
+
Place a new module in the domain that owns its policy. Keep database-specific behavior
|
|
16
|
+
behind `targets/`, repository-only checks under `scripts/verification/`, and public
|
|
17
|
+
imports behind the export map in `package.json`.
|