videobook-engine 2.0.1 → 4.2.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.
- package/README.md +87 -41
- package/dist/artifact-names.d.ts +6 -0
- package/dist/artifact-names.d.ts.map +1 -0
- package/dist/artifact-names.js +56 -0
- package/dist/artifact-names.js.map +1 -0
- package/dist/artifacts.d.ts.map +1 -1
- package/dist/artifacts.js +57 -23
- package/dist/artifacts.js.map +1 -1
- package/dist/books.js +2 -1
- package/dist/books.js.map +1 -1
- package/dist/cas.d.ts +27 -1
- package/dist/cas.d.ts.map +1 -1
- package/dist/cas.js +78 -6
- package/dist/cas.js.map +1 -1
- package/dist/catalog-metadata.d.ts +56 -0
- package/dist/catalog-metadata.d.ts.map +1 -0
- package/dist/catalog-metadata.js +42 -0
- package/dist/catalog-metadata.js.map +1 -0
- package/dist/communications.js +4 -2
- package/dist/communications.js.map +1 -1
- package/dist/context.d.ts +6 -1
- package/dist/context.d.ts.map +1 -1
- package/dist/context.js +35 -6
- package/dist/context.js.map +1 -1
- package/dist/domain.d.ts +4 -0
- package/dist/domain.d.ts.map +1 -1
- package/dist/domain.js +870 -58
- package/dist/domain.js.map +1 -1
- package/dist/edit-policy.d.ts +3 -0
- package/dist/edit-policy.d.ts.map +1 -0
- package/dist/edit-policy.js +6 -0
- package/dist/edit-policy.js.map +1 -0
- package/dist/edits.d.ts +10 -0
- package/dist/edits.d.ts.map +1 -0
- package/dist/edits.js +1392 -0
- package/dist/edits.js.map +1 -0
- package/dist/engine-types.d.ts +110 -60
- package/dist/engine-types.d.ts.map +1 -1
- package/dist/engine-types.js +33 -0
- package/dist/engine-types.js.map +1 -1
- package/dist/engine.d.ts +69 -8
- package/dist/engine.d.ts.map +1 -1
- package/dist/engine.js +24 -18
- package/dist/engine.js.map +1 -1
- package/dist/files.d.ts.map +1 -1
- package/dist/files.js +31 -27
- package/dist/files.js.map +1 -1
- package/dist/fork.d.ts +147 -0
- package/dist/fork.d.ts.map +1 -0
- package/dist/fork.js +609 -0
- package/dist/fork.js.map +1 -0
- package/dist/history.d.ts +0 -4
- package/dist/history.d.ts.map +1 -1
- package/dist/history.js +166 -595
- package/dist/history.js.map +1 -1
- package/dist/index.d.ts +16 -4
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +12 -2
- package/dist/index.js.map +1 -1
- package/dist/job-queue.d.ts +2 -0
- package/dist/job-queue.d.ts.map +1 -1
- package/dist/job-queue.js +29 -2
- package/dist/job-queue.js.map +1 -1
- package/dist/media.d.ts.map +1 -1
- package/dist/media.js +1 -0
- package/dist/media.js.map +1 -1
- package/dist/merge-policy.d.ts +99 -0
- package/dist/merge-policy.d.ts.map +1 -0
- package/dist/merge-policy.js +310 -0
- package/dist/merge-policy.js.map +1 -0
- package/dist/metadata.d.ts.map +1 -1
- package/dist/metadata.js +15 -20
- package/dist/metadata.js.map +1 -1
- package/dist/migration.d.ts +9 -0
- package/dist/migration.d.ts.map +1 -0
- package/dist/migration.js +534 -0
- package/dist/migration.js.map +1 -0
- package/dist/mvp-contract-fixtures.d.ts +244 -0
- package/dist/mvp-contract-fixtures.d.ts.map +1 -0
- package/dist/mvp-contract-fixtures.js +556 -0
- package/dist/mvp-contract-fixtures.js.map +1 -0
- package/dist/mvp-contracts.d.ts +761 -0
- package/dist/mvp-contracts.d.ts.map +1 -0
- package/dist/mvp-contracts.js +59 -0
- package/dist/mvp-contracts.js.map +1 -0
- package/dist/mvp-time.d.ts +54 -0
- package/dist/mvp-time.d.ts.map +1 -0
- package/dist/mvp-time.js +148 -0
- package/dist/mvp-time.js.map +1 -0
- package/dist/notebook/types.d.ts +113 -8
- package/dist/notebook/types.d.ts.map +1 -1
- package/dist/order-keys.d.ts +22 -0
- package/dist/order-keys.d.ts.map +1 -0
- package/dist/order-keys.js +262 -0
- package/dist/order-keys.js.map +1 -0
- package/dist/runtime-services.js +4 -2
- package/dist/runtime-services.js.map +1 -1
- package/dist/schema.d.ts +24 -5
- package/dist/schema.d.ts.map +1 -1
- package/dist/schema.js +644 -132
- package/dist/schema.js.map +1 -1
- package/dist/search-benchmark.d.ts +4 -0
- package/dist/search-benchmark.d.ts.map +1 -0
- package/dist/search-benchmark.js +144 -0
- package/dist/search-benchmark.js.map +1 -0
- package/dist/sequences.d.ts +20 -0
- package/dist/sequences.d.ts.map +1 -0
- package/dist/sequences.js +825 -0
- package/dist/sequences.js.map +1 -0
- package/dist/similarity.js +1 -1
- package/dist/storage.d.ts +3 -1
- package/dist/storage.d.ts.map +1 -1
- package/dist/storage.js +388 -7
- package/dist/storage.js.map +1 -1
- package/dist/store.d.ts +63 -2
- package/dist/store.d.ts.map +1 -1
- package/dist/store.js +351 -65
- package/dist/store.js.map +1 -1
- package/dist/streams.d.ts +10 -0
- package/dist/streams.d.ts.map +1 -0
- package/dist/streams.js +183 -0
- package/dist/streams.js.map +1 -0
- package/dist/temporal-models.d.ts +48 -0
- package/dist/temporal-models.d.ts.map +1 -0
- package/dist/temporal-models.js +278 -0
- package/dist/temporal-models.js.map +1 -0
- package/dist/temporal-search.d.ts +29 -0
- package/dist/temporal-search.d.ts.map +1 -0
- package/dist/temporal-search.js +1507 -0
- package/dist/temporal-search.js.map +1 -0
- package/dist/transcripts.d.ts +16 -0
- package/dist/transcripts.d.ts.map +1 -0
- package/dist/transcripts.js +519 -0
- package/dist/transcripts.js.map +1 -0
- package/docs/engine-layout.md +346 -106
- package/docs/mvp-prd.md +918 -0
- package/fixtures/media/vancat.mp4 +0 -0
- package/fixtures/media/vancat_profile.jpg +0 -0
- package/fixtures/v5/contract-fixtures.json +1532 -0
- package/package.json +30 -5
- package/dist/history-types.d.ts +0 -74
- package/dist/history-types.d.ts.map +0 -1
- package/dist/history-types.js +0 -2
- package/dist/history-types.js.map +0 -1
- package/dist/timeline.d.ts +0 -9
- package/dist/timeline.d.ts.map +0 -1
- package/dist/timeline.js +0 -236
- package/dist/timeline.js.map +0 -1
package/docs/engine-layout.md
CHANGED
|
@@ -1,8 +1,9 @@
|
|
|
1
1
|
# Videobook engine layout
|
|
2
2
|
|
|
3
3
|
This document is the column-by-column layout of the engine-owned data model.
|
|
4
|
-
It describes schema version 4
|
|
5
|
-
|
|
4
|
+
It describes the original schema version 4 layout, notes where later schema
|
|
5
|
+
versions changed the picture (currently v18), and identifies the additional
|
|
6
|
+
structures needed for a full non-linear video editor.
|
|
6
7
|
|
|
7
8
|
The executable source of truth remains
|
|
8
9
|
[`src/schema.ts`](../src/schema.ts). If this document and the DDL disagree, the
|
|
@@ -41,7 +42,7 @@ flowchart LR
|
|
|
41
42
|
OUTBOX --> STAGE
|
|
42
43
|
STAGE --> REV[Dolt main revision]
|
|
43
44
|
|
|
44
|
-
FILES[Artifact file APIs] --> CAS[
|
|
45
|
+
FILES[Artifact file APIs] --> CAS[SHA-256 objects, forgettable]
|
|
45
46
|
FILES --> MAP[Versioned artifact_files mapping]
|
|
46
47
|
CAS --> WS[Disposable artifact workspace]
|
|
47
48
|
MAP --> WS
|
|
@@ -52,15 +53,24 @@ flowchart LR
|
|
|
52
53
|
|
|
53
54
|
## Global invariants
|
|
54
55
|
|
|
55
|
-
- One engine catalog contains exactly one `book` row and one
|
|
56
|
-
`
|
|
56
|
+
- One engine catalog contains exactly one `book` row and one primary
|
|
57
|
+
`sequences` row. There is no project scope.
|
|
57
58
|
- The only supported live Dolt branch is `main`.
|
|
58
59
|
- Semantic mutations are SQL transactions followed by forward-only Dolt
|
|
59
60
|
commits. A restore creates a new commit; it never rewinds the live branch.
|
|
60
|
-
- `SEMANTIC_TABLES` is the staging allowlist. Every
|
|
61
|
-
`
|
|
62
|
-
|
|
63
|
-
|
|
61
|
+
- `SEMANTIC_TABLES` is the staging allowlist. Every operation declares the
|
|
62
|
+
semantic tables it may write (`OperationInput.tables`, including ON DELETE
|
|
63
|
+
CASCADE targets); a commit probes exactly that set with row-level diffs,
|
|
64
|
+
stages the truly dirty tables, asserts them clean afterwards, and is
|
|
65
|
+
skipped when only runtime bookkeeping changed. A full-catalog sweep runs
|
|
66
|
+
once per open and faults on rows no operation attributed (doltStatus
|
|
67
|
+
itself over-reports and is never trusted for dirtiness). The commit itself
|
|
68
|
+
is the provenance record: the operation, its parameters, write set, and
|
|
69
|
+
base revision ride in a structured commit message under the configured
|
|
70
|
+
identity as `--author`.
|
|
71
|
+
- `runtime_%`, `job_runs`, and `sqlite_sequence` are ignored by Dolt. Runtime
|
|
72
|
+
state can be rebuilt, expired, or invalidated without changing semantic
|
|
73
|
+
history.
|
|
64
74
|
- Engine-generated surrogate identities are stable UUIDv7 strings; the SQL
|
|
65
75
|
columns are `TEXT`, so UUID form is enforced by engine APIs rather than a
|
|
66
76
|
database check. Content identity is a lowercase, 64-character SHA-256.
|
|
@@ -68,8 +78,16 @@ flowchart LR
|
|
|
68
78
|
currently modeled use integer frames.
|
|
69
79
|
- JSON is stored as canonical text with recursively sorted object keys.
|
|
70
80
|
- Deletes are hard deletes. Owned rows cascade; live artifact/entity
|
|
71
|
-
references restrict deletion;
|
|
72
|
-
|
|
81
|
+
references restrict deletion; prior Dolt revisions remain available.
|
|
82
|
+
- Objects are content-immutable but forgettable. `engine.storage.deleteObject`
|
|
83
|
+
forgets one object (refusing `IN_USE` references at HEAD unless forced);
|
|
84
|
+
`engine.storage.gc` sweeps every object nothing references at HEAD.
|
|
85
|
+
Forgetting is a semantic commit that sets `objects.forgotten_at`; the row
|
|
86
|
+
is never deleted, so it remains as the tombstone (hash + size + forgotten
|
|
87
|
+
timestamp) for historical references, and reads of forgotten content
|
|
88
|
+
surface `OBJECT_UNAVAILABLE` rather than failing or lying. Published
|
|
89
|
+
history is append-only, so bulk forgettable text lives behind CAS hashes
|
|
90
|
+
(see "Forgettable data and raw-text audit" below).
|
|
73
91
|
|
|
74
92
|
## Dolt-versioned semantic schema
|
|
75
93
|
|
|
@@ -81,16 +99,16 @@ Notation used below:
|
|
|
81
99
|
- `→` names the referenced column.
|
|
82
100
|
- Defaults and checks are shown inline.
|
|
83
101
|
|
|
84
|
-
There are
|
|
102
|
+
There are 34 allowlisted semantic tables.
|
|
85
103
|
|
|
86
104
|
### Catalog, artifacts, and content
|
|
87
105
|
|
|
88
106
|
| Table | Columns | Keys, constraints, and purpose |
|
|
89
107
|
| --- | --- | --- |
|
|
90
|
-
| `engine_schema` | `singleton INTEGER`<br>`version INTEGER`<br>`created_at INTEGER` | `singleton PK CHECK(singleton = 1)`. Records the clean-break catalog version.
|
|
108
|
+
| `engine_schema` | `singleton INTEGER`<br>`version INTEGER`<br>`created_at INTEGER` | `singleton PK CHECK(singleton = 1)`. Records the clean-break catalog version. The recorded version rejects older catalogs rather than migrating them. |
|
|
91
109
|
| `book` | `book_id TEXT`<br>`slug TEXT`<br>`created_at INTEGER` | `book_id PK`; `slug UQ`. Exactly one row per engine root. |
|
|
92
110
|
| `artifacts` | `artifact_id TEXT`<br>`slug TEXT`<br>`kind TEXT`<br>`created_at INTEGER` | `artifact_id PK`; `slug UQ`; `kind CHECK IN (video, image, audio, script, character, prompt, scene, final)`. The artifact is the stable identity for source media, generated media, documents, and final renders. |
|
|
93
|
-
| `objects` | `object_hash TEXT`<br>`size_bytes INTEGER`<br>`created_at INTEGER
|
|
111
|
+
| `objects` | `object_hash TEXT`<br>`size_bytes INTEGER`<br>`created_at INTEGER`<br>`forgotten_at INTEGER?` | `object_hash PK`; `size_bytes CHECK >= 0`. Versioned metadata for bytes stored outside the database. Rows are append-only: `forgotten_at` marks a tombstone whose bytes were deleted by `deleteObject`/`gc`. |
|
|
94
112
|
| `artifact_files` | `artifact_id TEXT`<br>`path TEXT`<br>`object_hash TEXT`<br>`mtime_ms INTEGER`<br>`created_at INTEGER` | `(artifact_id, path) PK`; `artifact_id FK → artifacts.artifact_id ON DELETE CASCADE`; `object_hash FK → objects.object_hash ON DELETE RESTRICT`. Maps a logical artifact path to immutable content. |
|
|
95
113
|
| `book_metadata` | `key TEXT`<br>`value_json TEXT` | `key PK`. Singleton-book key/value metadata; no redundant `book_id`. |
|
|
96
114
|
| `artifact_metadata` | `artifact_id TEXT`<br>`key TEXT`<br>`value_json TEXT` | `(artifact_id, key) PK`; `artifact_id FK → artifacts.artifact_id ON DELETE CASCADE`. Extensible artifact metadata that participates in revisions. |
|
|
@@ -100,36 +118,47 @@ There are 25 allowlisted semantic tables.
|
|
|
100
118
|
| Table | Columns | Keys, constraints, and purpose |
|
|
101
119
|
| --- | --- | --- |
|
|
102
120
|
| `entities` | `entity_id TEXT`<br>`type TEXT`<br>`name TEXT`<br>`description TEXT?`<br>`prompt TEXT?`<br>`data_json TEXT DEFAULT '{}'`<br>`created_at INTEGER` | `entity_id PK`; `type CHECK IN (prompt, character, scene)`. Normalized reusable creative concepts. |
|
|
103
|
-
| `notebooks` | `notebook_id TEXT`<br>`name TEXT`<br>`
|
|
104
|
-
| `
|
|
121
|
+
| `notebooks` | `notebook_id TEXT`<br>`name TEXT`<br>`created_at INTEGER` | `notebook_id PK`. Owns a generation/authoring graph. Schema v18 removed the monolithic `properties_json` cell. |
|
|
122
|
+
| `notebook_fields` | `notebook_id TEXT`<br>`field TEXT`<br>`value_json TEXT` | `(notebook_id, field) PK`; notebook `FK → notebooks ON DELETE CASCADE`; `field` is restricted to the typed public notebook fields. Stores optional notebook-level workflow values independently. |
|
|
123
|
+
| `cells` | `notebook_id TEXT`<br>`cell_id TEXT`<br>`type TEXT`<br>`slug TEXT`<br>`grid_row INTEGER`<br>`grid_column INTEGER`<br>`output_entity_id TEXT?`<br>`prompt TEXT?`<br>`provider TEXT?`<br>`model TEXT?`<br>`operation TEXT?`<br>`tool TEXT?`<br>`inputs_json TEXT DEFAULT '{}'`<br>`output_artifact_id TEXT?` | `(notebook_id, cell_id) PK`; `(notebook_id, slug) UQ`; notebook `FK → notebooks ON DELETE CASCADE`; entity and output artifacts use `ON DELETE RESTRICT`. Cell types and kind-specific slug prefixes are checked by the schema. |
|
|
124
|
+
| `notebook_cell_executions` | `notebook_id TEXT`<br>`cell_id TEXT`<br>fingerprint/status/output/provider/run/timestamp/tool/error fields<br>`stale INTEGER`<br>`fixture_baseline INTEGER` | `(notebook_id, cell_id) PK` and composite cell FK with cascade. Gives each cell's execution and staleness state its own merge boundary. |
|
|
125
|
+
| `notebook_generation_plans` | `notebook_id TEXT`<br>`plan_id TEXT`<br>`cell_id TEXT`<br>`status TEXT`<br>`plan_json TEXT`<br>output/error/timestamp fields | `(notebook_id, plan_id) PK`; composite cell FK with cascade. |
|
|
126
|
+
| `notebook_run_plans` | `notebook_id TEXT`<br>`plan_id TEXT`<br>`status TEXT`<br>plan/cost/fingerprint/output fields<br>timestamps | `(notebook_id, plan_id) PK`. Stores approval and execution plans as independently mergeable rows. |
|
|
127
|
+
| `notebook_transcript_edits` | `notebook_id TEXT`<br>`action_id TEXT`<br>`kind TEXT`<br>`restored INTEGER`<br>`payload_json TEXT` | `(notebook_id, action_id) PK`; notebook FK with cascade. |
|
|
128
|
+
| `notebook_transcript_attachments` | `notebook_id TEXT`<br>`attachment_id TEXT`<br>`payload_json TEXT` | `(notebook_id, attachment_id) PK`; notebook FK with cascade. |
|
|
105
129
|
| `edges` | `notebook_id TEXT`<br>`edge_id TEXT`<br>`source_cell_id TEXT`<br>`target_cell_id TEXT`<br>`target_input TEXT` | `(notebook_id, edge_id) PK`; notebook `FK → notebooks ON DELETE CASCADE`; composite source and target FKs reference cells in the same notebook and cascade on cell deletion. |
|
|
106
130
|
| `runs` | `run_id TEXT`<br>`notebook_id TEXT`<br>`status TEXT`<br>`started_at INTEGER`<br>`completed_at INTEGER`<br>`cell_order_json TEXT`<br>`outputs_json TEXT`<br>`error TEXT?` | `run_id PK`; notebook `FK → notebooks ON DELETE CASCADE`; `status CHECK IN (completed, failed, aborted)`. Terminal, versioned notebook execution records. |
|
|
107
131
|
|
|
108
|
-
###
|
|
132
|
+
### Sequence timeline and media editing state
|
|
133
|
+
|
|
134
|
+
Sequences are the single timeline model. `sequences`, `sequence_tracks`,
|
|
135
|
+
`sequence_clips`, `clip_links`, `clip_transforms`, `transitions`, and
|
|
136
|
+
`caption_cues` hold the edit; `engine.sequences` and `engine.edits` are the
|
|
137
|
+
only timeline APIs. The legacy schema-v4 `timeline`, `timeline_slots`, and
|
|
138
|
+
`timeline_audio` tables were removed in v17 — schema-v4 imports convert
|
|
139
|
+
still-image slots into clips on the primary sequence instead. See
|
|
140
|
+
[`src/schema.ts`](../src/schema.ts) for the full sequence DDL.
|
|
109
141
|
|
|
110
142
|
| Table | Columns | Keys, constraints, and purpose |
|
|
111
143
|
| --- | --- | --- |
|
|
112
|
-
| `timeline` | `book_id TEXT`<br>`render TEXT DEFAULT 'landscape'` | `book_id PK FK → book.book_id ON DELETE CASCADE`; `render CHECK IN (landscape, portrait, square)`. One sequence-level orientation row. |
|
|
113
|
-
| `timeline_slots` | `slot_id TEXT`<br>`artifact_id TEXT`<br>`ordinal INTEGER`<br>`volume REAL?`<br>`audio_fade_in REAL?`<br>`audio_fade_out REAL?` | `slot_id PK`; artifact `FK → artifacts ON DELETE RESTRICT`; `ordinal CHECK >= 0`; volume and fades are null or `>= 0`. A single ordered visual lane; ownership by the singleton timeline is implicit. |
|
|
114
|
-
| `timeline_audio` | `audio_id TEXT`<br>`artifact_id TEXT`<br>`ordinal INTEGER`<br>`start_frame INTEGER`<br>`duration_frames INTEGER`<br>`volume REAL?`<br>`fade_in REAL?`<br>`fade_out REAL?` | `audio_id PK`; artifact `FK → artifacts ON DELETE RESTRICT`; ordinal/start `CHECK >= 0`; duration `CHECK > 0`; volume and fades are null or `>= 0`. Ordered overlays with explicit timeline timing. |
|
|
115
144
|
| `audio_waveforms` | `artifact_id TEXT`<br>`peaks_json TEXT` | `artifact_id PK FK → artifacts.artifact_id ON DELETE CASCADE`. Versioned waveform peaks used by editing UI. |
|
|
116
145
|
|
|
117
146
|
The normalized current relationship is:
|
|
118
147
|
|
|
119
148
|
```mermaid
|
|
120
149
|
erDiagram
|
|
121
|
-
BOOK
|
|
122
|
-
|
|
123
|
-
|
|
150
|
+
BOOK ||--o{ SEQUENCES : owns
|
|
151
|
+
SEQUENCES ||--o{ SEQUENCE_TRACKS : orders
|
|
152
|
+
SEQUENCE_TRACKS ||--o{ SEQUENCE_CLIPS : places
|
|
153
|
+
ARTIFACTS ||--o{ SEQUENCE_CLIPS : supplies
|
|
124
154
|
ARTIFACTS ||--o| AUDIO_WAVEFORMS : has
|
|
125
155
|
ARTIFACTS ||--o{ ARTIFACT_FILES : maps
|
|
126
156
|
OBJECTS ||--o{ ARTIFACT_FILES : backs
|
|
127
157
|
```
|
|
128
158
|
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
duration frames, but there is no catalog-level frame-rate/timebase row yet.
|
|
159
|
+
Sequence timing is integer frames against each sequence's rational frame
|
|
160
|
+
rate; timed clip sources use rational timebase ticks. Track and clip
|
|
161
|
+
ordering uses fractional order keys with the row UUID as tie-breaker.
|
|
133
162
|
|
|
134
163
|
### Prompts and messages
|
|
135
164
|
|
|
@@ -138,25 +167,39 @@ duration frames, but there is no catalog-level frame-rate/timebase row yet.
|
|
|
138
167
|
| `prompt_entries` | `prompt_id TEXT`<br>`surface TEXT`<br>`prompt TEXT`<br>`context_json TEXT DEFAULT '{}'`<br>`created_at INTEGER` | `prompt_id PK`. Semantic prompt history grouped by UI or agent surface. |
|
|
139
168
|
| `messages` | `message_id TEXT`<br>`role TEXT`<br>`body_json TEXT`<br>`created_at INTEGER` | `message_id PK`. Structured semantic conversation history. |
|
|
140
169
|
|
|
141
|
-
###
|
|
170
|
+
### Provenance and terminal jobs
|
|
142
171
|
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
|
|
172
|
+
Provenance is not a set of tables; it is the Dolt commit log itself. Every
|
|
173
|
+
semantic commit message is structured and machine-parseable:
|
|
174
|
+
|
|
175
|
+
```
|
|
176
|
+
<operation>[ artifact:<artifactId>]
|
|
177
|
+
|
|
178
|
+
op-id: <uuidv7>
|
|
179
|
+
base-revision: <commit hash> (when the mutation declared one)
|
|
180
|
+
actor: <operation actor> (when the mutation declared one)
|
|
181
|
+
write-set: <canonical JSON array> (when non-empty)
|
|
182
|
+
details: <canonical JSON object> (when non-empty)
|
|
183
|
+
```
|
|
184
|
+
|
|
185
|
+
History listings, per-artifact history, stale write-set conflict checks, and
|
|
186
|
+
edit restore are all derived from `dolt_log`, `dolt_diff`, and
|
|
187
|
+
`dolt_at_<table>(revision)` projections — there is no parallel `operations`,
|
|
188
|
+
`actions`, or `edit_batches` record to merge. doltlite rejects commit
|
|
189
|
+
messages of 65536 bytes or more, so an oversized `details` or `write-set`
|
|
190
|
+
payload is dropped in favor of a `details-omitted` / `write-set-omitted`
|
|
191
|
+
trailer that records the payload size; projections treat omitted trailers as
|
|
192
|
+
empty.
|
|
193
|
+
|
|
194
|
+
Terminal job audit rows live in `job_runs` (`run_id PK`; `state CHECK IN
|
|
195
|
+
(done, failed, aborted)`), an ignored runtime table rather than a semantic
|
|
196
|
+
one: job payload blobs are rebuildable bookkeeping, so recording a terminal
|
|
197
|
+
job never mints a commit. Artifact references are loose so completed history
|
|
198
|
+
survives artifact deletion.
|
|
156
199
|
|
|
157
200
|
### Committed Dolt policy table
|
|
158
201
|
|
|
159
|
-
`dolt_ignore` is created and staged separately from the
|
|
202
|
+
`dolt_ignore` is created and staged separately from the 28-table allowlist:
|
|
160
203
|
|
|
161
204
|
| Column | Constraint |
|
|
162
205
|
| --- | --- |
|
|
@@ -168,8 +211,147 @@ Its committed rows are:
|
|
|
168
211
|
| Pattern | Ignored | Meaning |
|
|
169
212
|
| --- | ---: | --- |
|
|
170
213
|
| `runtime_%` | `1` | Never version any engine runtime table. |
|
|
214
|
+
| `job_runs` | `1` | Never version terminal job audit blobs. |
|
|
171
215
|
| `sqlite_sequence` | `1` | Never version local AUTOINCREMENT counters. |
|
|
172
216
|
|
|
217
|
+
### Merge policy per constraint class
|
|
218
|
+
|
|
219
|
+
Merges run through `mergeWithPolicy` (`src/merge-policy.ts`), which encodes
|
|
220
|
+
one rule per constraint class. doltlite verifies the merged working set
|
|
221
|
+
against UNIQUE, CHECK, and foreign-key constraints and rolls a violating
|
|
222
|
+
merge back atomically ("working set with constraint violations"); there is
|
|
223
|
+
no `dolt_verify_constraints()` in doltlite, so the merge itself plus
|
|
224
|
+
post-merge scans (`PRAGMA foreign_key_check`, duplicate-singleton scans)
|
|
225
|
+
are the constraint-verification primitives.
|
|
226
|
+
|
|
227
|
+
- **Precondition: same schema version.** Both sides must carry the same
|
|
228
|
+
`engine_schema.version`; a mismatch is refused with
|
|
229
|
+
`SCHEMA_INCOMPATIBLE` before any merge is attempted
|
|
230
|
+
(`assertSameSchemaVersion`). This was previously only implied by the
|
|
231
|
+
engine's open-time version gate.
|
|
232
|
+
- **`artifacts.slug` (globally unique) → user-facing conflict.** Two forks
|
|
233
|
+
minting the same slug for different artifacts is detected before the
|
|
234
|
+
merge by a three-way (merge-base/ours/theirs) simulation over the
|
|
235
|
+
artifacts slug projection (`findSlugConflicts`, using `dolt_merge_base`
|
|
236
|
+
and `dolt_at_artifacts`), and refused with `MERGE_CONFLICT` listing the
|
|
237
|
+
slug and both artifact ids. doltlite's own verification is the backstop:
|
|
238
|
+
refusals it reports are re-diagnosed and surface as `MERGE_CONFLICT`
|
|
239
|
+
when attributable to slugs. Row-level same-row edits surface as
|
|
240
|
+
`MERGE_CONFLICT` as well. At create time, slug dedup runs inside the
|
|
241
|
+
serialized write chain (not as a read-then-write outside it), so
|
|
242
|
+
concurrent creates cannot race onto the same slug.
|
|
243
|
+
- **RESTRICT foreign keys → verification-surfaced typed violation.** A
|
|
244
|
+
fork that deletes a row another fork newly references is caught by
|
|
245
|
+
doltlite's merge-time working-set verification, which refuses and rolls
|
|
246
|
+
back; the policy maps that refusal to `MERGE_VIOLATION` (never a raw
|
|
247
|
+
`IO_ERROR`) and re-verifies referential integrity after every successful
|
|
248
|
+
merge (`verifyConstraintHealth`). Delete-time `IN_USE` pre-checks cover
|
|
249
|
+
every RESTRICT referencing table of `artifacts` (cells, streams,
|
|
250
|
+
transcripts, clips, pinned search results) so single-branch deletes also
|
|
251
|
+
fail with typed errors.
|
|
252
|
+
- **`transcripts.state='current'` / `sequences.is_primary` → derived
|
|
253
|
+
singletons.** A merge of forks that each crowned a different row yields
|
|
254
|
+
duplicates. Reads resolve a deterministic winner and the post-merge
|
|
255
|
+
reconcile (`reconcileSingletonFlags`) rewrites losers: transcripts keep
|
|
256
|
+
the latest `created_at` (ties: lowest `transcript_id`), sequences keep
|
|
257
|
+
the earliest `created_at` — the original primary (ties: lowest
|
|
258
|
+
`sequence_id`). The reconcile is Dolt-committed so the working set is
|
|
259
|
+
clean for the next merge.
|
|
260
|
+
- **Grid slots and order keys** need no resolution: `(grid_row,
|
|
261
|
+
grid_column)` collisions and identical fractional order keys are both
|
|
262
|
+
resolved at read time by the stable row-UUID tie-break (see the order
|
|
263
|
+
rules above). Writers self-repair: `moveTrack` runs `reconcileOrderKeys`
|
|
264
|
+
over a duplicate-key sibling group before computing a between-key, so the
|
|
265
|
+
position between two merge-minted duplicates stays reachable.
|
|
266
|
+
- **`objects.forgotten_at` → forget wins, earliest stamp.** The same
|
|
267
|
+
takedown applied independently on fork and upstream produces a same-row
|
|
268
|
+
different-value cell (wall clocks differ). The projection merge resolves
|
|
269
|
+
it instead of conflicting: when both sides agree on everything except
|
|
270
|
+
`forgotten_at`, a set value beats NULL (deleted bytes stay deleted on
|
|
271
|
+
both lineages) and two set values keep the earlier timestamp
|
|
272
|
+
(`resolveObjectsRow` in `src/fork.ts`).
|
|
273
|
+
|
|
274
|
+
ve-wsu: doltlite currently corrupts secondary UNIQUE indexes on
|
|
275
|
+
`dolt_checkout` once a working set has three or more tables, corrupts full
|
|
276
|
+
engine catalogs on checkout and `dolt_clone` (the cloned file's schema does
|
|
277
|
+
not even parse: `invalid rootpage` on a secondary autoindex), misfires its
|
|
278
|
+
"uncommitted changes" merge guard on the full 28-table catalog (every
|
|
279
|
+
table reports a phantom `modified` status with zero row diffs), and — when
|
|
280
|
+
the guard is bypassed by committing the phantom dirt — dies in schema
|
|
281
|
+
loading on true merges (`schema conflict on table 'sqlite_autoindex_*'`).
|
|
282
|
+
The dedicated merge-back flow therefore runs this policy around a
|
|
283
|
+
projection-level three-way merge instead of `dolt_merge`; see "Forks and
|
|
284
|
+
merge-back integration" below. `mergeWithPolicy` remains the drop-in merge
|
|
285
|
+
mechanism once the upstream bugs are fixed, exercised against the real
|
|
286
|
+
semantic DDL in `tests/merge-policy.test.ts`.
|
|
287
|
+
|
|
288
|
+
### Forks and merge-back integration
|
|
289
|
+
|
|
290
|
+
A fork of a public book is, from the engine's point of view:
|
|
291
|
+
|
|
292
|
+
1. **A platform fork.** Creating the hosted copy of a catalog and giving
|
|
293
|
+
it a URL is the hosting layer's job; it is out of engine scope.
|
|
294
|
+
2. **A clone of the catalog into a local engine root** (`bootstrapFork` in
|
|
295
|
+
[`src/fork.ts`](../src/fork.ts)). Because `dolt_clone` corrupts full
|
|
296
|
+
catalogs (ve-wsu), bootstrap takes a byte snapshot of a healthy upstream
|
|
297
|
+
`videobook.db` (captured while the upstream engine is closed) and opens
|
|
298
|
+
it as a normal engine — no `initialBookSlug`, the singleton book row
|
|
299
|
+
comes along with the snapshot. A URL bootstrap path attempts
|
|
300
|
+
`dolt_clone` and health-validates the result, surfacing a typed
|
|
301
|
+
`FEATURE_UNAVAILABLE` while the upstream bug stands; it starts working
|
|
302
|
+
unchanged once doltlite is fixed.
|
|
303
|
+
3. **A public-read object store keyed by SHA-256.** `ContentStore` stays
|
|
304
|
+
the abstraction; the existing `ensureLocal` lazy fetch in
|
|
305
|
+
[`src/cas.ts`](../src/cas.ts) downloads any object the fork lacks on
|
|
306
|
+
first touch, so upstream objects of a public book are readable to
|
|
307
|
+
forkers without a bulk copy. Whether the fork's store proxies to
|
|
308
|
+
upstream's is a hosting concern — an engine root only ever sees one
|
|
309
|
+
`ContentStore`.
|
|
310
|
+
|
|
311
|
+
The fork is then a full citizen: it commits on its own `main` and backs up
|
|
312
|
+
to its own catalog remote and object store.
|
|
313
|
+
|
|
314
|
+
**The live-engine never-pulls rule stands.** An open engine never fetches,
|
|
315
|
+
pulls, or merges, and `main` remains the only supported live branch.
|
|
316
|
+
Integration is a dedicated flow, `mergeBack` in
|
|
317
|
+
[`src/fork.ts`](../src/fork.ts), separate from any live engine:
|
|
318
|
+
|
|
319
|
+
1. Copy a healthy upstream `videobook.db` (engine closed) into a throwaway
|
|
320
|
+
temp workspace. The flow never requires or mutates the user's open
|
|
321
|
+
catalog — the source file is only read.
|
|
322
|
+
2. Register/fetch the fork remote (`dolt_remote`, `dolt_fetch`) and
|
|
323
|
+
resolve heads and the merge base (`dolt_merge_base`; commit hashes via
|
|
324
|
+
`dolt_log`/`dolt_branches` — `doltHashOf` returns content hashes, not
|
|
325
|
+
commit hashes; the fetched remote-tracking ref gets a local branch
|
|
326
|
+
pointer, a ref-only write that is safe under ve-wsu).
|
|
327
|
+
3. Run the merge policy: same-schema precondition, pre-merge slug-conflict
|
|
328
|
+
detection (`MERGE_CONFLICT`), then a projection-level three-way row
|
|
329
|
+
merge over `dolt_at_<table>` snapshots of base/ours/theirs (row
|
|
330
|
+
semantics mirror Dolt: one-sided changes win, identical changes
|
|
331
|
+
resolve, incompatible changes abort with `MERGE_CONFLICT`), deterministic
|
|
332
|
+
singleton-flag reconcile, and post-merge constraint verification
|
|
333
|
+
(`MERGE_VIOLATION`). The working-set rewrite uses the restore idiom —
|
|
334
|
+
delete all semantic tables in reverse, reinsert parent-before-child.
|
|
335
|
+
4. Upload the fork's new objects (rows in `dolt_at_objects(theirs)` not at
|
|
336
|
+
ours, tombstones excluded) from the fork's object store to upstream's
|
|
337
|
+
BEFORE the catalog ref moves — the same objects-before-push ordering as
|
|
338
|
+
`engine.storage.backup`.
|
|
339
|
+
5. Land one forward integration commit on `main` and `dolt_push` it.
|
|
340
|
+
|
|
341
|
+
ve-wsu makes a true two-parent `dolt_merge` commit impossible on full
|
|
342
|
+
catalogs today, so the integration commit is single-parent and records the
|
|
343
|
+
integrated fork head in a `merged-revision` commit-message trailer (plus
|
|
344
|
+
`base-revision`, per the structured-message convention). Re-running the
|
|
345
|
+
flow is a no-op when the fork's net changes are already on `main`. The
|
|
346
|
+
projection merge in `mergeRefs` is the single swap point: when doltlite is
|
|
347
|
+
fixed, `mergeWithPolicy` + `dolt_merge` replace it and the commit becomes
|
|
348
|
+
a true merge commit.
|
|
349
|
+
|
|
350
|
+
When a plain `engine.storage.backup()` push is rejected because upstream
|
|
351
|
+
moved, the backup surfaces `DIVERGED` with guidance into this flow —
|
|
352
|
+
someone with a healthy upstream catalog runs `mergeBack`; the fork never
|
|
353
|
+
pulls to catch up.
|
|
354
|
+
|
|
173
355
|
### Semantic indexes
|
|
174
356
|
|
|
175
357
|
Primary keys and unique declarations create their own backing indexes. The
|
|
@@ -186,15 +368,8 @@ schema additionally defines every index below.
|
|
|
186
368
|
| `edges_source` | `edges(notebook_id, source_cell_id)` |
|
|
187
369
|
| `edges_target` | `edges(notebook_id, target_cell_id)` |
|
|
188
370
|
| `runs_notebook_completed` | `runs(notebook_id, completed_at, run_id)` |
|
|
189
|
-
| `timeline_slots_order` | `timeline_slots(ordinal, slot_id)` |
|
|
190
|
-
| `timeline_slots_artifact` | `timeline_slots(artifact_id)` |
|
|
191
|
-
| `timeline_audio_order` | `timeline_audio(ordinal, audio_id)` |
|
|
192
|
-
| `timeline_audio_artifact` | `timeline_audio(artifact_id)` |
|
|
193
371
|
| `prompt_entries_lookup` | `prompt_entries(surface, created_at, prompt_id)` |
|
|
194
372
|
| `messages_created` | `messages(created_at, message_id)` |
|
|
195
|
-
| `operations_created` | `operations(created_at, operation_id)` |
|
|
196
|
-
| `operations_artifact_created` | `operations(artifact_id, created_at, operation_id)` |
|
|
197
|
-
| `action_events_action_created` | `action_events(action_id, created_at, event_id)` |
|
|
198
373
|
|
|
199
374
|
## Local-only runtime schema
|
|
200
375
|
|
|
@@ -252,57 +427,106 @@ to recover safely:
|
|
|
252
427
|
|
|
253
428
|
1. Start `BEGIN IMMEDIATE`.
|
|
254
429
|
2. Change the requested semantic rows.
|
|
255
|
-
3. Insert
|
|
256
|
-
|
|
257
|
-
|
|
258
|
-
|
|
259
|
-
|
|
260
|
-
|
|
261
|
-
|
|
262
|
-
|
|
263
|
-
|
|
430
|
+
3. Insert `runtime_commit_outbox(operation_id, tables_json, message, created_at)`;
|
|
431
|
+
`tables_json` carries the operation's declared write set alongside the
|
|
432
|
+
allow-empty flag, so the declaration commits atomically with the mutation
|
|
433
|
+
and recovery stages the same tables.
|
|
434
|
+
4. Commit the SQL transaction.
|
|
435
|
+
5. Probe each declared table with a row-level diff (`dolt_diff_<table>`,
|
|
436
|
+
which also sees staged-but-uncommitted rows during recovery) and stage
|
|
437
|
+
the dirty ones one `dolt_add` at a time — doltlite's multi-argument
|
|
438
|
+
`dolt_add` over-stages, and its `doltStatus` phantom `modified` entries
|
|
439
|
+
are why status is never consulted for dirtiness.
|
|
440
|
+
6. Create a Dolt commit on `main` with the configured identity as `--author`;
|
|
441
|
+
when nothing semantic changed, clear the outbox row instead of minting an
|
|
442
|
+
empty commit.
|
|
443
|
+
7. Assert the committed tables are no longer dirty, then delete the runtime
|
|
444
|
+
outbox row.
|
|
445
|
+
|
|
446
|
+
On reopen, the engine drains any surviving outbox record (legacy rows
|
|
447
|
+
without a declared table list fall back to probing the full allowlist) and
|
|
448
|
+
then sweeps the whole catalog: any semantic table with unattributed
|
|
449
|
+
uncommitted rows faults the open with `STORAGE_ERROR`. Staged tables are
|
|
450
|
+
asserted against the allowlist before every commit. Opening a catalog never creates a
|
|
451
|
+
commit: terminal-job reconciliation writes the ignored `job_runs` table
|
|
452
|
+
through a runtime transaction. Historical reads use
|
|
264
453
|
`dolt_at_<semantic_table>(revision)`; history and conflict projections use
|
|
265
|
-
Dolt log, status, and diff APIs.
|
|
454
|
+
Dolt log, status, and diff APIs. A whole-book restore reloads **every** table
|
|
455
|
+
in `SEMANTIC_TABLES` from its `dolt_at_*` projection at the target revision —
|
|
456
|
+
deleting in reverse and reinserting in forward, parent-before-child order,
|
|
457
|
+
with columns taken from `PRAGMA table_info` — so the restored state is
|
|
458
|
+
exactly the recorded state and no hand-maintained table list can drift.
|
|
459
|
+
Remote catalog support is push-backup only.
|
|
460
|
+
|
|
461
|
+
## Forgettable data and raw-text audit
|
|
462
|
+
|
|
463
|
+
Published history is append-only: once a catalog has been pushed anywhere
|
|
464
|
+
someone could fork it, its commits are permanent. Forgetting therefore means
|
|
465
|
+
deleting content-addressed objects, never rewriting history. History squash
|
|
466
|
+
tooling would only be legal before the first push (before anyone can fork);
|
|
467
|
+
the engine deliberately does not implement it.
|
|
468
|
+
|
|
469
|
+
### Object deletion and GC
|
|
470
|
+
|
|
471
|
+
- `engine.storage.deleteObject(hash, { force?, remote? })` forgets one
|
|
472
|
+
object. It refuses with `IN_USE` (listing the HEAD references) when a HEAD
|
|
473
|
+
row still names the hash, unless `force` is given — the takedown path.
|
|
474
|
+
- `engine.storage.gc({ dryRun?, remote?, doltGc? })` sweeps every object
|
|
475
|
+
nothing references at HEAD, plus stray local files that never got an
|
|
476
|
+
`objects` row. A hash is referenced at HEAD when a HEAD row names it in a
|
|
477
|
+
first-class `object_hash`/`payload_hash` column (`artifact_files`,
|
|
478
|
+
`artifact_streams`, `pinned_search_results`, `sequence_clips`,
|
|
479
|
+
`transcripts`) or embeds it as an `objectHash` in a `cell_references`
|
|
480
|
+
snapshot. Historical revisions are not consulted.
|
|
481
|
+
- Both record forgetting as a semantic commit (`delete_object` /
|
|
482
|
+
`gc_objects`) that sets `objects.forgotten_at`. The row is never deleted:
|
|
483
|
+
it stays as the tombstone (hash + size + forgotten timestamp) for every
|
|
484
|
+
historical row that named the object, and backup never tries to publish a
|
|
485
|
+
forgotten object again. Re-importing the same bytes resurrects the row
|
|
486
|
+
(`forgotten_at` is cleared when the object is re-linked).
|
|
487
|
+
- Restoring an old revision whose object was forgotten relinks the
|
|
488
|
+
tombstone: the forward restore commit stands, and reads of the missing
|
|
489
|
+
bytes surface `OBJECT_UNAVAILABLE` through the existing error path instead
|
|
490
|
+
of crashing. Deleting a referenced object with `force` behaves the same
|
|
491
|
+
way at HEAD.
|
|
492
|
+
- With `remote: true`, deletion also unpublishes via
|
|
493
|
+
`ContentStore.delete(key)` and clears the `runtime_object_publications`
|
|
494
|
+
marker so a later re-import is published again.
|
|
495
|
+
- doltlite exposes `dolt_gc()` as a SQL function (verified: it returns a
|
|
496
|
+
`"N chunks removed, M chunks kept"` summary). `gc({ doltGc: true })` runs
|
|
497
|
+
it after collecting to physically reclaim chunks left behind by dropped
|
|
498
|
+
table data in the versioned catalog.
|
|
499
|
+
- Run `deleteObject` and `gc` only while no imports are in flight; CAS puts
|
|
500
|
+
happen outside the serialized write chain, so a concurrent import could
|
|
501
|
+
race the sweep.
|
|
502
|
+
|
|
503
|
+
### Raw-text audit
|
|
504
|
+
|
|
505
|
+
| Table / column | Decision | Rationale |
|
|
506
|
+
| --- | --- | --- |
|
|
507
|
+
| `transcript_segments.text`, `transcript_words.text` | **Moved behind CAS** (schema v16) | Full transcripts are the bulk-text case. Segment/word text lives in one CAS object named by `transcripts.payload_hash`; the versioned rows keep only structure (IDs, ordinals, ticks, speaker, confidence, kind), so `transcripts.selectionRange` and caption-cue word references keep working after the payload is forgotten. `transcripts.delete` removes the rows; the payload then becomes GC-collectable. |
|
|
508
|
+
| `caption_cues.text` | Accepted permanent | Short editorial cue text needed to render without CAS access; a deliberate editorial snapshot that can diverge from the transcript. |
|
|
509
|
+
| `prompt_entries.prompt`, `cells.prompt`, `entities.prompt`/`description` | Accepted permanent | Small user-authored creative working data; part of the semantic record users expect to persist, like commit messages. |
|
|
510
|
+
| `messages.body_json` | Accepted permanent | Small per-row authored conversation record. |
|
|
511
|
+
| `pinned_search_results.query_json`/`signals_json`/`representative_json`, `cell_references.snapshot_json` | Accepted permanent | Small selection snapshots; may embed short excerpts. Snapshot `objectHash` values are honored as loose GC roots. |
|
|
512
|
+
| `runs.cell_order_json`/`outputs_json`/`error`, `book_metadata`/`artifact_metadata.value_json` | Accepted permanent | Structural or small key/value data. |
|
|
513
|
+
| `runtime_segment_text.text`, `runtime_text_similarity_chunks.chunk_text` | Out of scope | `runtime_*` tables are never versioned or pushed, so they never enter the public record; rebuild or drop them locally at will. |
|
|
266
514
|
|
|
267
515
|
## Video-editing structures exposed today
|
|
268
516
|
|
|
269
517
|
The SQL schema is only one part of the editing model. These structures and
|
|
270
518
|
conventions are also important.
|
|
271
519
|
|
|
272
|
-
###
|
|
273
|
-
|
|
274
|
-
```ts
|
|
275
|
-
type TimelineRender = "landscape" | "portrait" | "square";
|
|
276
|
-
|
|
277
|
-
interface Timeline {
|
|
278
|
-
bookId: string;
|
|
279
|
-
render: TimelineRender;
|
|
280
|
-
slots: TimelineSlot[];
|
|
281
|
-
audio: TimelineAudio[];
|
|
282
|
-
}
|
|
283
|
-
|
|
284
|
-
interface TimelineSlot {
|
|
285
|
-
id: string; // UUIDv7
|
|
286
|
-
artifactId: string;
|
|
287
|
-
volume?: number;
|
|
288
|
-
audioFadeIn?: number;
|
|
289
|
-
audioFadeOut?: number;
|
|
290
|
-
}
|
|
291
|
-
|
|
292
|
-
interface TimelineAudio {
|
|
293
|
-
id: string; // UUIDv7
|
|
294
|
-
artifactId: string;
|
|
295
|
-
startFrame: number;
|
|
296
|
-
durationFrames: number;
|
|
297
|
-
volume?: number;
|
|
298
|
-
fadeIn?: number;
|
|
299
|
-
fadeOut?: number;
|
|
300
|
-
}
|
|
301
|
-
```
|
|
520
|
+
### Sequence contract
|
|
302
521
|
|
|
303
|
-
|
|
304
|
-
|
|
305
|
-
|
|
522
|
+
The timeline is a `Sequence` projection: rational frame rate and pixel
|
|
523
|
+
aspect, an audio sample rate and channel layout, ordered video/audio/caption
|
|
524
|
+
tracks, clips with source ranges and transforms, transitions, and caption
|
|
525
|
+
cues. `engine.sequences` reads and mutates sequence structure (tracks,
|
|
526
|
+
names, primary sequence); `engine.edits` applies transactional clip,
|
|
527
|
+
transition, and caption operations. `getAtRevision()` projects the sequence
|
|
528
|
+
tables at a Dolt revision. The full contract types live in
|
|
529
|
+
[`src/mvp-contracts.ts`](../src/mvp-contracts.ts).
|
|
306
530
|
|
|
307
531
|
### Artifact manifest and content
|
|
308
532
|
|
|
@@ -360,12 +584,10 @@ status, and error. Entities provide structured prompts, characters, and scenes.
|
|
|
360
584
|
|
|
361
585
|
### Provenance and concurrency
|
|
362
586
|
|
|
363
|
-
- `Revision` projects Dolt commit hash, operation, artifact,
|
|
364
|
-
|
|
365
|
-
- `
|
|
366
|
-
|
|
367
|
-
- `base_revision` plus normalized write sets detect overlapping semantic
|
|
368
|
-
actions.
|
|
587
|
+
- `Revision` projects the Dolt commit hash, operation, artifact, and
|
|
588
|
+
parameters parsed from the structured commit message.
|
|
589
|
+
- `base_revision` plus the write sets carried in commit messages detect
|
|
590
|
+
overlapping semantic changes.
|
|
369
591
|
- Runtime jobs, resource leases, artifact views, owner IDs, expiry times, and
|
|
370
592
|
monotonic fences coordinate processors without polluting Dolt history.
|
|
371
593
|
|
|
@@ -381,10 +603,15 @@ status, and error. Entities provide structured prompts, characters, and scenes.
|
|
|
381
603
|
|
|
382
604
|
## Full NLE structures not yet implemented
|
|
383
605
|
|
|
384
|
-
|
|
385
|
-
|
|
386
|
-
|
|
387
|
-
|
|
606
|
+
The core sequence model proposed below has since landed (`sequences`,
|
|
607
|
+
`sequence_tracks`, `sequence_clips`, `clip_links`, `clip_transforms`,
|
|
608
|
+
`transitions`, `caption_cues`) and is now the only timeline model; the
|
|
609
|
+
legacy v4 lane described here was removed in v17. The remaining proposals —
|
|
610
|
+
effects, keyframes, audio buses, markers, derivatives — are still open.
|
|
611
|
+
Schema v4 assembled one ordered visual lane plus timed audio overlays. The
|
|
612
|
+
following is a concrete candidate layout for the remaining pieces. Every
|
|
613
|
+
name in this section is proposed and, unless noted above, does **not** exist
|
|
614
|
+
in the catalog.
|
|
388
615
|
|
|
389
616
|
### Core sequence model
|
|
390
617
|
|
|
@@ -460,7 +687,16 @@ must reproduce a render.
|
|
|
460
687
|
- Preserve loose references only in audit/lineage records that must outlive the
|
|
461
688
|
target.
|
|
462
689
|
- Keep order as an integer plus stable ID tie-breaker, or use a documented
|
|
463
|
-
fractional ordering key if frequent insertion warrants it.
|
|
690
|
+
fractional ordering key if frequent insertion warrants it. The engine uses
|
|
691
|
+
fractional/lexicographic order keys (base-62, `"a0"`-style midpoint keys,
|
|
692
|
+
see `src/order-keys.ts`) for engine-maintained orderings — sequence tracks
|
|
693
|
+
and, before the legacy triple was removed in v17, timeline slots and
|
|
694
|
+
timeline audio — with the row UUID as tie-breaker, so inserting or moving
|
|
695
|
+
one row never renumbers its neighbors. Notebook cells
|
|
696
|
+
keep their explicit integer `(grid_row, grid_column)` slot as the ordering
|
|
697
|
+
key with the cell UUID as tie-breaker; slot uniqueness is no longer
|
|
698
|
+
enforced by the schema and collisions left by a merge are repaired on the
|
|
699
|
+
next write instead.
|
|
464
700
|
- Put user intent and accepted edit decisions in Dolt. Put playhead position,
|
|
465
701
|
selections, UI panels, decode caches, thumbnails, temporary renders, active
|
|
466
702
|
jobs, locks, and presence in ignored runtime tables.
|
|
@@ -478,12 +714,16 @@ must reproduce a render.
|
|
|
478
714
|
| Concern | Implementation |
|
|
479
715
|
| --- | --- |
|
|
480
716
|
| DDL, table allowlists, indexes | [`src/schema.ts`](../src/schema.ts) |
|
|
717
|
+
| Fractional order keys and minimal rekeying | [`src/order-keys.ts`](../src/order-keys.ts) |
|
|
481
718
|
| SQL transactions, Dolt staging, commits, outbox recovery | [`src/store.ts`](../src/store.ts) |
|
|
719
|
+
| Merge policy per constraint class | [`src/merge-policy.ts`](../src/merge-policy.ts) |
|
|
720
|
+
| Fork bootstrap and merge-back integration | [`src/fork.ts`](../src/fork.ts) |
|
|
482
721
|
| Engine paths and row projections | [`src/context.ts`](../src/context.ts) |
|
|
483
|
-
|
|
|
722
|
+
| Content-addressed object layout, remote keys, deletion | [`src/cas.ts`](../src/cas.ts) |
|
|
723
|
+
| Object publication, deletion, GC, and catalog backup | [`src/storage.ts`](../src/storage.ts) |
|
|
484
724
|
| Artifact mappings and workspace materialization | [`src/files.ts`](../src/files.ts) |
|
|
485
|
-
|
|
|
486
|
-
| Public
|
|
725
|
+
| Sequence reads/structure and transactional edits | [`src/sequences.ts`](../src/sequences.ts), [`src/edits.ts`](../src/edits.ts) |
|
|
726
|
+
| Public manifest, job, status, and similarity types | [`src/engine-types.ts`](../src/engine-types.ts) |
|
|
487
727
|
| Entity/notebook graph types | [`src/notebook/types.ts`](../src/notebook/types.ts) |
|
|
488
728
|
| Revision and action projections/restores | [`src/history.ts`](../src/history.ts), [`src/history-types.ts`](../src/history-types.ts) |
|
|
489
729
|
| Media naming and discovery conventions | [`src/media.ts`](../src/media.ts) |
|