qubu 0.4.2 → 0.5.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 (61) hide show
  1. package/dist/{canonical-BXUguqfo.mjs → canonical-DMvR9yBe.mjs} +4 -4
  2. package/dist/codegen.d.mts +1 -1
  3. package/dist/codegen.mjs +7 -4
  4. package/dist/{column-hqKr7-1I.mjs → column-DmazTL67.mjs} +15 -2
  5. package/dist/{complete-WYyVozgK.mjs → complete-DP7pliuY.mjs} +6 -6
  6. package/dist/{complete-types-IjEn5VPN.d.mts → complete-types-CY0KbzNw.d.mts} +1 -1
  7. package/dist/core.d.mts +1 -1
  8. package/dist/core.mjs +3 -3
  9. package/dist/diff.d.mts +201 -1
  10. package/dist/diff.mjs +8 -8
  11. package/dist/{index-1DpA3mUh.d.mts → index-C-480HmV.d.mts} +12 -12
  12. package/dist/index.d.mts +2 -2
  13. package/dist/index.mjs +226 -44
  14. package/dist/introspection.d.mts +2 -2
  15. package/dist/introspection.mjs +24 -13
  16. package/dist/mysql.d.mts +2 -2
  17. package/dist/{on-conflict-hfPW0KmQ.mjs → on-conflict-jPsl9l0K.mjs} +6 -3
  18. package/dist/postgres.d.mts +2 -2
  19. package/dist/postgres.mjs +3 -3
  20. package/dist/{registry-BRMLYwDp.mjs → registry-BGqa05et.mjs} +2 -2
  21. package/dist/{relational-BZ3WDPzC.mjs → relational-x3BDVX9e.mjs} +2 -2
  22. package/dist/schema.d.mts +2 -2
  23. package/dist/schema.mjs +5 -5
  24. package/dist/{snapshot-C-W65HEd.mjs → snapshot-BSraiLtH.mjs} +2 -2
  25. package/dist/snapshot.d.mts +4 -4
  26. package/dist/snapshot.mjs +585 -5
  27. package/dist/{source-BcS2AsIg.mjs → source-C4Vmu5bb.mjs} +1 -1
  28. package/dist/{sqlite-Cg0nwYEH.mjs → sqlite-CsIUtZ2Q.mjs} +6 -6
  29. package/dist/sqlite.d.mts +30 -3
  30. package/dist/sqlite.mjs +28 -2
  31. package/dist/{table-Bp5irMSj.mjs → table-DLQ7YWth.mjs} +2 -2
  32. package/dist/{types-BK1COGZe.d.mts → types-C0VkiwpR.d.mts} +146 -41
  33. package/dist/{types-JSZHpUEj.d.mts → types-CTCqtFlS.d.mts} +1 -1
  34. package/dist/{types-JM3FcAnX.mjs → types-CTENnDh9.mjs} +2 -2
  35. package/dist/{value-Bi71Agyf.mjs → value-BEEj_Ayd.mjs} +1 -1
  36. package/dist/vite/ambient.d.ts +6 -0
  37. package/docs/config.json +1 -0
  38. package/docs/dialects-and-execution.md +47 -0
  39. package/docs/guides/drizzle.md +2 -1
  40. package/docs/index.md +6 -2
  41. package/docs/migrations/adapters.md +70 -0
  42. package/docs/migrations/artifacts-and-policy.md +123 -0
  43. package/docs/migrations/index.md +46 -0
  44. package/docs/migrations/lotta-adoption.md +50 -0
  45. package/docs/migrations/operations.md +133 -0
  46. package/docs/migrations/recovery.md +121 -0
  47. package/docs/reference/introspection-support.md +1 -1
  48. package/docs/reference/supported-surface.md +59 -44
  49. package/docs/schema/catalog-model.md +1 -1
  50. package/docs/schema/columns-and-writes.md +14 -0
  51. package/docs/schema/ddl-emission.md +15 -10
  52. package/docs/schema/introspection.md +4 -3
  53. package/docs/schema/migration-plans.md +6 -6
  54. package/docs/schema/snapshots.md +2 -2
  55. package/package.json +5 -14
  56. package/dist/ddl.d.mts +0 -118
  57. package/dist/ddl.mjs +0 -1119
  58. package/dist/index-CPvfEheG.d.mts +0 -202
  59. package/dist/migration.d.mts +0 -214
  60. package/dist/migration.mjs +0 -1160
  61. package/dist/mysql-B_cYzzX2.mjs +0 -585
@@ -1,31 +1,41 @@
1
1
  # Supported features
2
2
 
3
- > Choose a public package entrypoint, check what Qubu handles, and keep database work on the application side of each adapter.
3
+ > Choose a public package entrypoint and keep application policy separate from portable migration and driver-owned capabilities.
4
4
 
5
5
  ## Package entrypoints
6
6
 
7
- | Import | Kind | Use it for |
8
- | ------------------------ | ---------------- | ---------------------------------------------------------------------------------------------------------------- |
9
- | `qubu` | Runtime | Ordinary query and schema definitions, reads, writes, SQL templates, rendering, EXPLAIN, and execution contracts |
10
- | `qubu/core` | Runtime | Fragment and rendering primitives, dialect construction, SQL types, and extension constructors |
11
- | `qubu/codegen` | Runtime | Deterministic machine-owned TypeScript schemas from complete, non-lossy introspection |
12
- | `qubu/ddl` | Runtime | DDL preflight and deterministic PostgreSQL, SQLite, or MySQL emission from a migration plan |
13
- | `qubu/diff` | Runtime | Canonical Snapshot v1 or v2 comparison, rename hints, suggestions, and safety diagnostics |
14
- | `qubu/introspection` | Runtime | Catalog readers, normalized catalogs, and mapping to Snapshot v1 or v2 |
15
- | `qubu/migration` | Runtime | Pure migration planning with dependencies, decisions, preconditions, and explicit custom SQL |
16
- | `qubu/mysql` | Runtime | The MySQL query dialect policy |
17
- | `qubu/postgres` | Runtime | PostgreSQL query dialect helpers such as `postgresDialect()` and `ilike()` |
18
- | `qubu/schema` | Runtime | Advanced schema metadata, storage and constraint models, source models, and schema-expression extensions |
19
- | `qubu/snapshot` | Runtime | Canonical Snapshot v1 and v2 traversal, encoding, decoding, diagnostics, and digests |
20
- | `qubu/sqlite` | Runtime | The SQLite query dialect policy |
21
- | `qubu/vite` | Runtime | The optional `qubu()` Vite compiler hint |
22
- | `qubu/package.json` | JSON | The published package manifest |
23
- | `@qubu/drizzle` | Runtime | Shared Drizzle conversion errors and dialect types |
24
- | `@qubu/drizzle/mysql` | Runtime | Runtime conversion from Qubu schemas to MySQL Drizzle tables |
25
- | `@qubu/drizzle/postgres` | Runtime | Runtime conversion from Qubu schemas to PostgreSQL Drizzle tables |
26
- | `@qubu/drizzle/sqlite` | Runtime | Runtime conversion from Qubu schemas to SQLite Drizzle tables |
27
- | `@qubu/better-auth` | Runtime | Better Auth schema derivation and native PostgreSQL, MySQL, and SQLite adapter behavior |
28
- | `qubu/globals` | TypeScript types | Opt-in ambient declarations for directive-bearing modules |
7
+ | Import | Kind | Use it for |
8
+ | -------------------------- | ---------------- | ---------------------------------------------------------------------------------------------------------------- |
9
+ | `qubu` | Runtime | Ordinary query and schema definitions, reads, writes, SQL templates, rendering, EXPLAIN, and execution contracts |
10
+ | `qubu/core` | Runtime | Fragment and rendering primitives, dialect construction, SQL types, and extension constructors |
11
+ | `qubu/codegen` | Runtime | Deterministic machine-owned TypeScript schemas from complete, non-lossy introspection |
12
+ | `qubu/diff` | Runtime | Canonical Snapshot v1 or v2 comparison, rename hints, suggestions, and safety diagnostics |
13
+ | `qubu/introspection` | Runtime | Catalog readers, normalized catalogs, and mapping to Snapshot v1 or v2 |
14
+ | `qubu/mysql` | Runtime | The MySQL query dialect policy |
15
+ | `qubu/postgres` | Runtime | PostgreSQL query dialect helpers such as `postgresDialect()` and `ilike()` |
16
+ | `qubu/schema` | Runtime | Advanced schema metadata, storage and constraint models, source models, and schema-expression extensions |
17
+ | `qubu/snapshot` | Runtime | Canonical Snapshot v1 and v2 traversal, encoding, decoding, diagnostics, and fingerprints |
18
+ | `qubu/sqlite` | Runtime | The SQLite query dialect policy and native SQLite column factories |
19
+ | `qubu/vite` | Runtime | The optional `qubu()` Vite compiler hint |
20
+ | `qubu/package.json` | JSON | The published package manifest |
21
+ | `@qubu/migrate` | Runtime | Migration compiler format identity and shared plan types |
22
+ | `@qubu/migrate/plan` | Runtime | Pure migration planning with dependencies, decisions, preconditions, and explicit custom SQL |
23
+ | `@qubu/migrate/ddl` | Runtime | DDL preflight and deterministic PostgreSQL, SQLite, or MySQL emission from a migration plan |
24
+ | `@qubu/migrate/artifact` | Runtime | Versioned programs, strict artifacts and baselines, canonical encoding, and SHA-256 integrity |
25
+ | `@qubu/migrate/repository` | Runtime | Strict full-chain and journal-prefix verification |
26
+ | `@qubu/migrate/journal` | Runtime | Storage-neutral journal records, transitions, validation, and reference storage |
27
+ | `@qubu/migrate/executor` | Runtime | Portable execution, structured errors, checkpointing, and explicit reconciliation |
28
+ | `@qubu/migrate/baseline` | Runtime | Strict live baseline verification and physical managed-schema comparison |
29
+ | `@qubu/migrate/status` | Runtime | Pending chain, managed drift, unmanaged objects, interrupted attempts, and incompatible requirements |
30
+ | `@qubu/migrate/bootstrap` | Runtime | Fresh SQLite schema planning through the normal diff, plan, and program compiler |
31
+ | `@qubu/migrate/testing` | Runtime | Deterministic fake adapters, fault boundaries, and adapter conformance checks |
32
+ | `@qubu/cli` | Runtime and CLI | `@alloc/cmd-ts` commands, typed config, filesystem repositories, stable output, and exit codes |
33
+ | `@qubu/drizzle` | Runtime | Shared Drizzle conversion errors and dialect types |
34
+ | `@qubu/drizzle/mysql` | Runtime | Runtime conversion from Qubu schemas to MySQL Drizzle tables |
35
+ | `@qubu/drizzle/postgres` | Runtime | Runtime conversion from Qubu schemas to PostgreSQL Drizzle tables |
36
+ | `@qubu/drizzle/sqlite` | Runtime | Runtime conversion from Qubu schemas to SQLite Drizzle tables |
37
+ | `@qubu/better-auth` | Runtime | Better Auth schema derivation and native PostgreSQL, MySQL, and SQLite adapter behavior |
38
+ | `qubu/globals` | TypeScript types | Opt-in ambient declarations for directive-bearing modules |
29
39
 
30
40
  The package validator checks every declared entrypoint in each packed workspace
31
41
  package. Concrete dialect constructors live on their database subpaths. The
@@ -45,30 +55,32 @@ entrypoint table.
45
55
 
46
56
  ## Capability map
47
57
 
48
- | Area | Supported building blocks |
49
- | ------------------ | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
50
- | Schema values | `table`, immutable `schema` registries with namespaces, portable and dialect-native column storage descriptors, canonical default and generated-column metadata, identity descriptors, named primary, candidate-key, nullable unique, foreign-key, and check constraints, physical object names, included-column indexes, typed dialect extensions, and typed column helpers |
51
- | Read queries | Named projections, spreadable source columns, aliases, joins, typed custom and LATERAL `FROM` sources, correlated subqueries, `WHERE`, grouping with declared-key proofs, `HAVING`, ordering, window expressions, distinctness, pagination, row locking, ordinary and recursive CTEs, subqueries, and set operations |
52
- | Expressions | Comparison, boolean, arithmetic, null, range, membership, aggregate, window, string, JSON scalar reads, definition-backed and raw casts, cases, parameterized SQL templates, custom expressions, and branded deterministic schema expressions |
53
- | SQL type metadata | Portable domains and capabilities, physical column storage descriptors, `SqlTypeOf`, projected SQL type maps, `SourceLike` and `TableLike` field constraints, contextual literals, typed extension values, calls, and casts, plus a permissive `SqlUnknown` fallback |
54
- | Write queries | `INSERT` values, defaults, and selects; `UPDATE`; `DELETE`; typed assignments; `RETURNING`; and explicit unrestricted-write opt-in |
55
- | Rendering | Standard, PostgreSQL, SQLite, MySQL, and user-created policies for identifiers, placeholders, pagination, row locking, JSON, logical cast targets, schema literals, and EXPLAIN options |
56
- | Execution boundary | `QueryAdapter`, opt-in `ExplainableQueryAdapter`, `StreamingQueryAdapter`, and `TransactionalQueryAdapter` capabilities, bound clients from `qubu()`, structured results from `execute()` or `db.execute()`, row-only results from `executeRows()` or `db.rows()`, typed read streams from `stream()` or `db.stream()`, and adapter-decoded plan rows from `explain()` or `db.explain()` |
57
- | Snapshots | Pure Snapshot v1 and v2 creation, canonical encoding and strict decoding, immutable data, diagnostics, and content digests |
58
- | Introspection | PostgreSQL, SQLite, and MySQL catalog readers for one selected namespace, normalized catalog data, structured diagnostics, and strict or explicit lossy snapshot mapping |
59
- | Snapshot diffing | Pure Snapshot v1 and v2 comparison, explicit rename evidence, non-authoritative suggestions, and safety diagnostics |
60
- | Migration planning | Pure, dialect-neutral plans with stable ordering, dependency edges, preconditions, explicit review decisions, and tagged custom SQL |
61
- | DDL emission | Preflight plus deterministic PostgreSQL, SQLite, and MySQL statements from an approved `MigrationPlan` and matching `SchemaDialect` |
62
- | Build tooling | The optional Vite directive transform and its matching TypeScript ambient declarations |
63
- | Drizzle conversion | Optional, dialect-specific runtime conversion from Qubu schema registries to Drizzle tables |
64
- | Source generation | Pure Snapshot v1 table source printing, deterministic camelCase IDs, exact physical metadata, controlled type mappings, and structured failure diagnostics |
58
+ | Area | Supported building blocks |
59
+ | -------------------- | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
60
+ | Schema values | `table`, immutable `schema` registries with namespaces, portable and dialect-native column storage descriptors, canonical default and generated-column metadata, identity descriptors, named primary, candidate-key, nullable unique, foreign-key, and check constraints, physical object names, included-column indexes, typed dialect extensions, and typed column helpers |
61
+ | Read queries | Named projections, spreadable source columns, aliases, joins, typed custom and LATERAL `FROM` sources, correlated subqueries, `WHERE`, grouping with declared-key proofs, `HAVING`, ordering, window expressions, distinctness, pagination, row locking, ordinary and recursive CTEs, subqueries, and set operations |
62
+ | Expressions | Comparison, boolean, arithmetic, null, range, membership, aggregate, window, string, JSON scalar reads, definition-backed and raw casts, cases, parameterized SQL templates, custom expressions, and branded deterministic schema expressions |
63
+ | SQL type metadata | Portable domains and capabilities, physical column storage descriptors, `SqlTypeOf`, projected SQL type maps, `SourceLike` and `TableLike` field constraints, contextual literals, typed extension values, calls, and casts, plus a permissive `SqlUnknown` fallback |
64
+ | Write queries | `INSERT` values, defaults, and selects; `UPDATE`; `DELETE`; typed assignments; `RETURNING`; and explicit unrestricted-write opt-in |
65
+ | Rendering | Standard, PostgreSQL, SQLite, MySQL, and user-created policies for identifiers, placeholders, pagination, row locking, JSON, logical cast targets, schema literals, and EXPLAIN options |
66
+ | Execution boundary | `QueryAdapter`, opt-in `ExplainableQueryAdapter`, `StreamingQueryAdapter`, and `TransactionalQueryAdapter` capabilities, bound clients from `qubu()`, structured results from `execute()` or `db.execute()`, row-only results from `executeRows()` or `db.rows()`, typed read streams from `stream()` or `db.stream()`, and adapter-decoded plan rows from `explain()` or `db.explain()` |
67
+ | Snapshots | Pure Snapshot v1 and v2 creation, canonical encoding and strict decoding, immutable data, diagnostics, and FNV change-detection fingerprints |
68
+ | Introspection | PostgreSQL, SQLite, and MySQL catalog readers for one selected namespace, normalized catalog data, structured diagnostics, and strict or explicit lossy snapshot mapping |
69
+ | Snapshot diffing | Pure Snapshot v1 and v2 comparison, explicit rename evidence, non-authoritative suggestions, and safety diagnostics |
70
+ | Migration planning | Pure, dialect-neutral plans with stable ordering, dependency edges, preconditions, explicit review decisions, and tagged custom SQL |
71
+ | DDL emission | Preflight plus deterministic PostgreSQL, SQLite, and MySQL statements from an approved `MigrationPlan` and matching `SchemaDialect` |
72
+ | Migration operations | Strict artifacts and baselines, authoritative programs, repository and journal validation, adapter capability preflight, execution, status/drift, reconciliation, and SQLite bootstrap |
73
+ | Build tooling | The optional Vite directive transform and its matching TypeScript ambient declarations |
74
+ | Drizzle conversion | Optional, dialect-specific runtime conversion from Qubu schema registries to Drizzle tables |
75
+ | Source generation | Pure Snapshot v1 table source printing, deterministic camelCase IDs, exact physical metadata, controlled type mappings, and structured failure diagnostics |
65
76
 
66
77
  ## Ownership boundary
67
78
 
68
79
  Snapshot creation, diffing, migration planning, and DDL emission are pure.
69
80
  `execute()`, clients, and catalog readers can reach a driver only through
70
- interfaces the application provides. Qubu can emit DDL, but it never applies
71
- that DDL to a database.
81
+ interfaces the application provides. `@qubu/migrate` can orchestrate a sealed
82
+ program only through a migration adapter's pinned session and advertised
83
+ capabilities; `@qubu/cli` is the Node.js filesystem/process boundary.
72
84
 
73
85
  | Boundary | Qubu side | Application side |
74
86
  | ------------------------ | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
@@ -76,13 +88,16 @@ that DDL to a database.
76
88
  | Query execution | Binds an adapter with `qubu()` when requested; passes rendered statements and result shapes to execution adapters; applies registered logical field decoders to buffered or streamed object rows; scopes transaction callbacks; returns typed results, plans, rows, or streams | Owns the adapter, driver, connections, pools, cursors, stream cleanup, transactions, savepoints, retries, parameter encoding, proprietary row normalization, decoder policy, plan-row decoding, backpressure, cancellation, driver error translation, and database lifecycle |
77
89
  | Catalog introspection | Selects fixed parameterized catalog queries, normalizes rows, and maps catalog data to snapshots | Supplies `CatalogConnection`, credentials, already-decoded catalog rows, logging, and connection lifecycle |
78
90
  | Schema source generation | Prints deterministic TypeScript from complete, non-lossy Snapshot v1 introspection without writing files | Owns generated-file writes, replacement policy, hand-edit merging, and CLI integration |
79
- | Schema changes | Creates snapshots, compares them, builds deterministic migration plans, and emits DDL from approved plans with preflight diagnostics | Reviews decisions, executes or rolls back statements, acquires locks, manages transactions and migration journals, and owns database lifecycle |
91
+ | Schema compilation | Creates snapshots, compares them, builds deterministic migration plans, previews DDL, and compiles authoritative versioned programs | Defines the target snapshot, operation approvals, custom programs, renderer/server constraints, and artifact provenance |
92
+ | Migration operations | Verifies complete artifact and journal chains; orchestrates pinned sessions, leases, locks, transactions, checkpoints, head CAS, status, baselines, bootstrap, and explicit reconciliation through adapter contracts | Owns credentials, environment selection, adapter construction, rollout timing, deployment-provider coordination, recovery proof, legacy cutover, and database lifecycle |
80
93
 
81
94
  Start with [Dialects and execution](../dialects-and-execution.md) for the query
82
95
  adapter contract. The schema path is documented in [Canonical schema
83
96
  snapshots](../schema/snapshots.md), [Snapshot diffing](../schema/diff.md),
84
97
  [Migration plans](../schema/migration-plans.md), and [DDL
85
- emission](../schema/ddl-emission.md).
98
+ emission](../schema/ddl-emission.md). Continue with [Migration
99
+ operations](../migrations/index.md) for artifacts, adapters, CLI use, and
100
+ recovery.
86
101
 
87
102
  ## SQL safety boundaries
88
103
 
@@ -46,7 +46,7 @@ Snapshot v2 uses the same `qubu-schema` envelope with `version: 2`. Its
46
46
  namespace, capability facts, object-family arrays, cross-object references,
47
47
  provenance, typed dialect extensions, and deferred/opaque boundaries are
48
48
  strictly validated. Arrays are ordered by logical ID (with ordinal sequences
49
- and index terms ordered by their semantic position), and the digest is computed
49
+ and index terms ordered by their semantic position), and the fingerprint is computed
50
50
  from the deterministic encoding.
51
51
 
52
52
  Snapshot v1 remains a separate strict format. `decodeSchemaSnapshot` still
@@ -69,6 +69,20 @@ Contradictory flags fail with a structured `ColumnBehaviorError`. Use
69
69
  `externalDefault()` or `externalGeneratedColumn()` when another schema authority
70
70
  owns the missing detail.
71
71
 
72
+ Use `defaultFn` when Qubu should supply an omitted insert value at runtime:
73
+
74
+ ```ts
75
+ const sessions = table("sessions", {
76
+ token: text({ defaultFn: () => crypto.randomUUID() }),
77
+ })
78
+ ```
79
+
80
+ Runtime defaults make the insert key optional and run once for each omitted
81
+ row value. They remain live column behavior: snapshots and emitted DDL do not
82
+ record a database default. A column may declare both `default` and `defaultFn`;
83
+ Qubu writes use the runtime value while the database default remains available
84
+ to other clients.
85
+
72
86
  Dialect-owned identity details stay on the identity descriptor. SQLite's
73
87
  autoIncrement requires an exact INTEGER rowid alias that is the sole column of
74
88
  a primary key. MySQL's AUTO_INCREMENT is a column-level identity extension, and
@@ -1,14 +1,14 @@
1
1
  # DDL emission
2
2
 
3
- > Turn an approved migration plan into deterministic SQL while keeping database execution outside Qubu.
3
+ > Preview deterministic SQL from a migration plan without confusing preview policy with a sealed executable program.
4
4
 
5
- The `qubu/ddl` entrypoint accepts only a `MigrationPlan` and a `SchemaDialect`.
5
+ The `@qubu/migrate/ddl` entrypoint accepts only a `MigrationPlan` and a `SchemaDialect`.
6
6
  It does not read a catalog, open a connection, start a transaction, or write a
7
7
  migration journal. Preflight runs before rendering, so a blocked or incompatible
8
8
  plan returns diagnostics and no SQL.
9
9
 
10
10
  ```ts
11
- import { emitMigrationPlan } from "qubu/ddl"
11
+ import { emitMigrationPlan } from "@qubu/migrate/ddl"
12
12
  import { postgresSchemaDialect } from "qubu/snapshot"
13
13
 
14
14
  const result = emitMigrationPlan(plan, postgresSchemaDialect)
@@ -22,9 +22,8 @@ for (const statement of result.statements) {
22
22
  }
23
23
  ```
24
24
 
25
- `statements` is the stable handoff for an application-owned executor. Each
26
- statement carries its operation ID, topological position, SQL text, and an
27
- ordered parameter list.
25
+ `statements` is a deterministic preview surface. Each statement carries its
26
+ operation ID, topological position, SQL text, and an ordered parameter list.
28
27
  Schema literals and expressions are parameter-free by contract. `sql` joins
29
28
  the statements with a newline and adds a semicolon for migration-file writers.
30
29
 
@@ -32,10 +31,11 @@ the statements with a newline and adds a semicolon for migration-file writers.
32
31
 
33
32
  The emitter rejects a plan with `ready: false`, `decision-required` operations,
34
33
  unknown or lossy facts, unsupported safety, or destructive changes unless the
35
- caller supplies the matching explicit option. `allowUnsafe` is available for a
36
- reviewed integration that owns all of those decisions, but it does not make an
37
- opaque object renderable. Opaque and deferred catalog records always need an
38
- explicit tagged `custom-sql` operation.
34
+ caller supplies the matching explicit option. `allowUnsafe` is available for
35
+ preview integrations, but it is not accepted as an artifact approval and does
36
+ not make an opaque object renderable. Opaque and deferred catalog records need
37
+ an explicit tagged `custom-sql` operation for preview and an operation-scoped
38
+ custom program for sealed execution.
39
39
 
40
40
  Lock and transaction requirements describe what a later executor must provide.
41
41
  Pass `lock` or `transaction` to preflight those requirements against the
@@ -73,3 +73,8 @@ an inline constraint declaration or an explicit rebuild/custom-SQL operation.
73
73
 
74
74
  Custom SQL stays opaque and appears at its plan position. The emitter does not
75
75
  inspect it for object names or infer SQL from an opaque catalog record.
76
+
77
+ For execution, lower the plan with `compileMigrationProgram()` from
78
+ `@qubu/migrate/artifact`. The versioned program—not the aggregate `sql`
79
+ string—is authoritative. See [Artifacts and approval
80
+ policy](../migrations/artifacts-and-policy.md).
@@ -5,8 +5,8 @@
5
5
  Database introspection is an optional capability exported from
6
6
  `qubu/introspection`. It discovers database facts; it does not recreate the
7
7
  original TypeScript declarations. Planning and DDL emission use the separate
8
- `qubu/migration` and `qubu/ddl` entrypoints, while migration execution remains
9
- application-owned. The separate
8
+ `@qubu/migrate/plan` and `@qubu/migrate/ddl` entrypoints, while migration
9
+ execution remains application-owned. The separate
10
10
  `qubu/codegen` entrypoint can create a new machine-owned schema module from a
11
11
  complete Snapshot v1 result.
12
12
 
@@ -207,7 +207,8 @@ The canonical snapshot is the handoff to Qubu's pure schema pipeline:
207
207
  None of those layers opens a database connection or changes how introspection
208
208
  represents catalog facts. DDL emission produces statements; it does not apply
209
209
  them. The [ownership map](../reference/supported-surface.md#ownership-boundary)
210
- keeps this handoff separate from application-owned migration execution.
210
+ keeps this pure handoff separate from the pinned adapter session used by the
211
+ [portable migration executor](../migrations/recovery.md#execution-and-concurrency-guarantees).
211
212
 
212
213
  See the [introspection support matrix](../reference/introspection-support.md)
213
214
  for version baselines and dialect-specific limits. Snapshot serialization
@@ -2,13 +2,13 @@
2
2
 
3
3
  > Describe reviewed snapshot changes as deterministic data before selecting a DDL emitter.
4
4
 
5
- The optional `qubu/migration` entrypoint consumes a resolved `SnapshotDiff` and
5
+ The `@qubu/migrate/plan` entrypoint consumes a resolved `SnapshotDiff` and
6
6
  returns an immutable migration-plan IR. It contains operation IDs, paths,
7
7
  logical and physical identity evidence, dependency edges, preconditions, safety,
8
8
  lock and transaction requirements, and reversibility markers.
9
9
 
10
10
  ```ts
11
- import { createMigrationPlan } from "qubu/migration"
11
+ import { createMigrationPlan } from "@qubu/migrate/plan"
12
12
 
13
13
  const result = createMigrationPlan(diff)
14
14
  if (!result.ok) {
@@ -70,7 +70,7 @@ the stable topological ordering. `encodeMigrationPlan()` emits canonical JSON;
70
70
  `decodeMigrationPlan()` and `validateMigrationPlan()` reject unknown fields,
71
71
  future versions, malformed operations, missing edges, and dependency cycles.
72
72
 
73
- After review and approval, pass the plan to
74
- [`qubu/ddl`](./ddl-emission.md). DDL emission remains separate from
75
- application-owned migration execution in the package-wide [ownership
76
- map](../reference/supported-surface.md#ownership-boundary).
73
+ Use [`@qubu/migrate/ddl`](./ddl-emission.md) for a SQL preview. For durable
74
+ execution, compile and seal the authoritative program under the exact
75
+ [artifact approval policy](../migrations/artifacts-and-policy.md#exact-approval-policy),
76
+ then apply it through a verified adapter.
@@ -45,8 +45,8 @@ dialect metadata, and broken foreign-key or column references as structured
45
45
  diagnostics. It does not call `process.exit()` and has no runtime validation
46
46
  library dependency.
47
47
 
48
- `schemaSnapshotDigest()` computes a deterministic content digest from canonical
49
- JSON. The digest is useful for cache keys and fixture assertions only. It is not
48
+ `schemaSnapshotFingerprint()` computes a deterministic content fingerprint from canonical
49
+ JSON. The fingerprint is useful for cache keys and fixture assertions only. It is not
50
50
  an entity identity, a rename marker, or migration lineage.
51
51
 
52
52
  ## Adapter boundary
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "qubu",
3
- "version": "0.4.2",
3
+ "version": "0.5.0",
4
4
  "repository": {
5
5
  "type": "git",
6
6
  "url": "https://github.com/aleclarson/qubu"
@@ -24,10 +24,6 @@
24
24
  "types": "./dist/core.d.mts",
25
25
  "import": "./dist/core.mjs"
26
26
  },
27
- "./ddl": {
28
- "types": "./dist/ddl.d.mts",
29
- "import": "./dist/ddl.mjs"
30
- },
31
27
  "./diff": {
32
28
  "types": "./dist/diff.d.mts",
33
29
  "import": "./dist/diff.mjs"
@@ -36,10 +32,6 @@
36
32
  "types": "./dist/introspection.d.mts",
37
33
  "import": "./dist/introspection.mjs"
38
34
  },
39
- "./migration": {
40
- "types": "./dist/migration.d.mts",
41
- "import": "./dist/migration.mjs"
42
- },
43
35
  "./mysql": {
44
36
  "types": "./dist/mysql.d.mts",
45
37
  "import": "./dist/mysql.mjs"
@@ -76,7 +68,6 @@
76
68
  "@alloc/prettier-config": "^1.0.0",
77
69
  "@electric-sql/pglite": "^0.5.8",
78
70
  "@libsql/client": "^0.17.4",
79
- "@pg-nano/pg-tmp": "^2.0.3",
80
71
  "@stylistic/eslint-plugin": "^6.0.0-beta.6",
81
72
  "@types/bun": "^1.3.0",
82
73
  "@types/node": "^24.6.2",
@@ -100,21 +91,21 @@
100
91
  "prettier": "@alloc/prettier-config",
101
92
  "scripts": {
102
93
  "build": "tsdown",
103
- "build:workspace-packages": "pnpm --recursive --filter './adapters/*' build",
94
+ "build:workspace-packages": "pnpm --recursive --filter './adapters/*' --filter './packages/*' build",
104
95
  "check:package": "node ./scripts/test-package.mjs --check-built",
105
96
  "check:workspace-versions": "node ./scripts/set-release-version.mjs --check",
106
97
  "playground": "bun run ./playground/playground.ts",
107
98
  "test": "vitest",
108
99
  "test:e2e": "vitest --run test/e2e",
109
100
  "test:type-performance": "node ./scripts/test-type-performance.mjs",
110
- "diff-check": "vitest --run test/diff.test.ts test/migration.test.ts",
101
+ "diff-check": "vitest --run test/diff.test.ts && pnpm --filter @qubu/migrate test -- plan.test.ts",
111
102
  "test:bun": "node ./scripts/test-package.mjs --runtime=bun",
112
103
  "test:package": "node ./scripts/test-package.mjs",
113
- "test:workspace-children": "pnpm --recursive --filter './adapters/*' build && node ./scripts/test-workspace-packages.mjs",
104
+ "test:workspace-children": "pnpm run build:workspace-packages && node ./scripts/test-workspace-packages.mjs",
114
105
  "test:workspace-packages": "pnpm run test:package && pnpm run test:workspace-children",
115
106
  "test:package:node": "node ./scripts/test-package.mjs --runtime=node",
116
107
  "typecheck": "vitest --typecheck --run",
117
- "typecheck:workspace-packages": "pnpm --recursive --filter './adapters/*' typecheck",
108
+ "typecheck:workspace-packages": "pnpm --recursive --filter './adapters/*' --filter './packages/*' typecheck",
118
109
  "typecheck:playground": "tsc --project ./playground/tsconfig.json",
119
110
  "format": "oxlint --fix && oxfmt",
120
111
  "release:version": "node ./scripts/set-release-version.mjs",
package/dist/ddl.d.mts DELETED
@@ -1,118 +0,0 @@
1
- import { Tr as SchemaDialect } from "./types-BK1COGZe.mjs";
2
- import { MigrationLockRequirement, MigrationOperation, MigrationPlan, MigrationTransactionRequirement } from "./migration.mjs";
3
- //#region src/ddl/types.d.ts
4
- /** Stable diagnostic categories produced before a migration is rendered. */
5
- type DdlDiagnosticCode = "invalid-plan" | "blocked-plan" | "decision-required" | "dialect-mismatch" | "unsupported" | "server-version" | "lock-conflict" | "transaction-conflict" | "lossy" | "unknown" | "destructive" | "review-required" | "ambiguous" | "malformed-operation" | "custom-sql" | "capability" | "non-canonical";
6
- /** A path-addressed finding from DDL preflight or rendering. */
7
- interface DdlDiagnostic {
8
- readonly code: DdlDiagnosticCode;
9
- readonly severity: "error" | "warning";
10
- readonly message: string;
11
- readonly operationId?: string;
12
- readonly path: readonly (string | number)[];
13
- readonly kind?: MigrationOperation["kind"];
14
- readonly dialect?: string;
15
- readonly requiredVersion?: string;
16
- readonly actualVersion?: string;
17
- readonly lock?: MigrationLockRequirement;
18
- readonly transaction?: MigrationTransactionRequirement;
19
- }
20
- /** One deterministic statement emitted for one plan operation. */
21
- interface DdlStatement {
22
- readonly operationId: string;
23
- readonly position: number;
24
- readonly kind: MigrationOperation["kind"];
25
- /** SQL text with dialect placeholders, if a dialect ever needs them. */
26
- readonly sql: string;
27
- /** Alias for callers that use the query renderer's terminology. */
28
- readonly text: string;
29
- /** DDL literals are normally in SQL; this remains explicit and ordered. */
30
- readonly parameters: readonly unknown[];
31
- }
32
- /** Policy and execution-context facts used by DDL preflight. */
33
- interface DdlEmissionOptions {
34
- /** Permit a plan whose own `ready` flag is false after reviewing diagnostics. */
35
- readonly allowBlocked?: boolean;
36
- /** Alias for callers that intentionally permit all review gates. */
37
- readonly allowUnsafe?: boolean;
38
- readonly allowDecisionRequired?: boolean;
39
- readonly allowUnknown?: boolean;
40
- readonly allowLossy?: boolean;
41
- readonly allowUnsupported?: boolean;
42
- readonly allowDestructive?: boolean;
43
- readonly allowReviewRequired?: boolean;
44
- /** Server version used for syntax checks, such as SQLite DROP COLUMN. */
45
- readonly serverVersion?: string | number;
46
- /** Whether the caller will wrap statements in one transaction. */
47
- readonly transaction?: "managed" | "autocommit" | "none";
48
- /** Maximum lock the caller can acquire for this migration. */
49
- readonly lock?: Exclude<MigrationLockRequirement, "unknown">;
50
- }
51
- /** Result of preflight plus deterministic statement rendering. */
52
- interface DdlEmission {
53
- readonly ok: boolean;
54
- readonly dialect: string;
55
- readonly statements: readonly DdlStatement[];
56
- readonly diagnostics: readonly DdlDiagnostic[];
57
- /** Statements joined with a newline for simple migration-file writers. */
58
- readonly sql: string;
59
- /** Flattened parameters in statement order. */
60
- readonly parameters: readonly unknown[];
61
- }
62
- /** Descriptive alias for callers that name rendered output as a result. */
63
- type DdlEmissionResult = DdlEmission;
64
- /** A dialect-specific DDL emitter. */
65
- interface DdlEmitter {
66
- readonly dialect: string;
67
- diagnose(plan: MigrationPlan, schemaDialect: SchemaDialect, options?: DdlEmissionOptions): readonly DdlDiagnostic[];
68
- emit(plan: MigrationPlan, schemaDialect: SchemaDialect, options?: DdlEmissionOptions): DdlEmission;
69
- }
70
- //#endregion
71
- //#region src/ddl/emitter.d.ts
72
- interface DdlFeatures {
73
- readonly dialect: "postgresql" | "sqlite" | "mysql";
74
- readonly supports: ReadonlySet<string>;
75
- }
76
- /**
77
- * Build the shared strict preflight and rendering boundary for one engine. The renderer only
78
- * receives a validated MigrationPlan and a SchemaDialect.
79
- */
80
- declare function createDdlEmitter(features: DdlFeatures): DdlEmitter;
81
- //#endregion
82
- //#region src/ddl/postgres.d.ts
83
- /** PostgreSQL operation support used by the strict DDL preflight. */
84
- declare const postgresDdlEmitter: DdlEmitter;
85
- /** Emit a reviewed plan with PostgreSQL's schema dialect. */
86
- declare function emitPostgresMigrationPlan(plan: MigrationPlan, options?: DdlEmissionOptions): DdlEmission;
87
- /** Alias using the full PostgreSQL spelling. */
88
- declare const emitPostgresqlMigrationPlan: typeof emitPostgresMigrationPlan;
89
- declare const emitPostgresDdl: typeof emitPostgresMigrationPlan;
90
- declare const emitPostgresqlDdl: typeof emitPostgresMigrationPlan;
91
- //#endregion
92
- //#region src/ddl/sqlite.d.ts
93
- /** SQLite operation support used by the strict DDL preflight. */
94
- declare const sqliteDdlEmitter: DdlEmitter;
95
- /** Emit a reviewed plan with SQLite's schema dialect. */
96
- declare function emitSqliteMigrationPlan(plan: MigrationPlan, options?: DdlEmissionOptions): DdlEmission;
97
- declare const emitSqliteDdl: typeof emitSqliteMigrationPlan;
98
- //#endregion
99
- //#region src/ddl/mysql.d.ts
100
- /** MySQL operation support used by the strict DDL preflight. */
101
- declare const mysqlDdlEmitter: DdlEmitter;
102
- /** Emit a reviewed plan with MySQL's schema dialect. */
103
- declare function emitMysqlMigrationPlan(plan: MigrationPlan, options?: DdlEmissionOptions): DdlEmission;
104
- declare const emitMysqlDdl: typeof emitMysqlMigrationPlan;
105
- //#endregion
106
- //#region src/ddl/index.d.ts
107
- /** Select a first-party emitter by the selected schema dialect name. */
108
- declare function ddlEmitterForDialect(dialect: SchemaDialect): DdlEmitter;
109
- /** Emit a plan through the matching first-party schema dialect. */
110
- declare function emitMigrationPlan(plan: MigrationPlan, dialect: SchemaDialect, options?: DdlEmissionOptions): DdlEmission;
111
- /** Convenient defaults for callers that already selected a plan dialect. */
112
- declare const ddlDialects: Readonly<{
113
- postgresql: SchemaDialect<"row-locking" | "json" | "ilike" | "on-conflict">;
114
- sqlite: SchemaDialect<"json" | "on-conflict">;
115
- mysql: SchemaDialect<"row-locking" | "json">;
116
- }>;
117
- //#endregion
118
- export { DdlDiagnostic, DdlDiagnosticCode, DdlEmission, DdlEmissionOptions, DdlEmissionResult, DdlEmitter, DdlFeatures, DdlStatement, createDdlEmitter, ddlDialects, ddlEmitterForDialect, emitMigrationPlan, emitMysqlDdl, emitMysqlMigrationPlan, emitPostgresDdl, emitPostgresMigrationPlan, emitPostgresqlDdl, emitPostgresqlMigrationPlan, emitSqliteDdl, emitSqliteMigrationPlan, mysqlDdlEmitter, postgresDdlEmitter, sqliteDdlEmitter };