videobook-engine 4.2.0 → 5.3.2

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 (244) hide show
  1. package/README.md +84 -39
  2. package/dist/artifacts.d.ts +5 -10
  3. package/dist/artifacts.d.ts.map +1 -1
  4. package/dist/artifacts.js +79 -142
  5. package/dist/artifacts.js.map +1 -1
  6. package/dist/books.d.ts +1 -1
  7. package/dist/books.d.ts.map +1 -1
  8. package/dist/books.js +16 -9
  9. package/dist/books.js.map +1 -1
  10. package/dist/cas.d.ts +2 -1
  11. package/dist/cas.d.ts.map +1 -1
  12. package/dist/cas.js +33 -4
  13. package/dist/cas.js.map +1 -1
  14. package/dist/catalog-gc-state.d.ts +4 -0
  15. package/dist/catalog-gc-state.d.ts.map +1 -0
  16. package/dist/catalog-gc-state.js +49 -0
  17. package/dist/catalog-gc-state.js.map +1 -0
  18. package/dist/catalog-metadata.d.ts +2 -2
  19. package/dist/catalog-metadata.js +3 -3
  20. package/dist/catalog-metadata.js.map +1 -1
  21. package/dist/context.d.ts +5 -5
  22. package/dist/context.d.ts.map +1 -1
  23. package/dist/context.js +17 -49
  24. package/dist/context.js.map +1 -1
  25. package/dist/domain.d.ts +35 -2
  26. package/dist/domain.d.ts.map +1 -1
  27. package/dist/domain.js +131 -161
  28. package/dist/domain.js.map +1 -1
  29. package/dist/edits.js +2 -2
  30. package/dist/edits.js.map +1 -1
  31. package/dist/engine-types.d.ts +159 -39
  32. package/dist/engine-types.d.ts.map +1 -1
  33. package/dist/engine-types.js +2 -1
  34. package/dist/engine-types.js.map +1 -1
  35. package/dist/engine.d.ts +30 -20
  36. package/dist/engine.d.ts.map +1 -1
  37. package/dist/engine.js +46 -4
  38. package/dist/engine.js.map +1 -1
  39. package/dist/files.d.ts +10 -0
  40. package/dist/files.d.ts.map +1 -1
  41. package/dist/files.js +49 -2
  42. package/dist/files.js.map +1 -1
  43. package/dist/fork.d.ts +14 -30
  44. package/dist/fork.d.ts.map +1 -1
  45. package/dist/fork.js +18 -27
  46. package/dist/fork.js.map +1 -1
  47. package/dist/generations.d.ts +9 -0
  48. package/dist/generations.d.ts.map +1 -0
  49. package/dist/generations.js +175 -0
  50. package/dist/generations.js.map +1 -0
  51. package/dist/history.d.ts +2 -1
  52. package/dist/history.d.ts.map +1 -1
  53. package/dist/history.js +30 -57
  54. package/dist/history.js.map +1 -1
  55. package/dist/index.d.ts +8 -6
  56. package/dist/index.d.ts.map +1 -1
  57. package/dist/index.js +5 -5
  58. package/dist/index.js.map +1 -1
  59. package/dist/inline-temporal-models.d.ts +43 -0
  60. package/dist/inline-temporal-models.d.ts.map +1 -0
  61. package/dist/inline-temporal-models.js +236 -0
  62. package/dist/inline-temporal-models.js.map +1 -0
  63. package/dist/isolated-models.d.ts +8 -0
  64. package/dist/isolated-models.d.ts.map +1 -0
  65. package/dist/isolated-models.js +25 -0
  66. package/dist/isolated-models.js.map +1 -0
  67. package/dist/job-queue.d.ts +1 -1
  68. package/dist/job-queue.d.ts.map +1 -1
  69. package/dist/job-queue.js +20 -6
  70. package/dist/job-queue.js.map +1 -1
  71. package/dist/media-image.d.ts +8 -0
  72. package/dist/media-image.d.ts.map +1 -0
  73. package/dist/media-image.js +41 -0
  74. package/dist/media-image.js.map +1 -0
  75. package/dist/media-process.d.ts +13 -0
  76. package/dist/media-process.d.ts.map +1 -0
  77. package/dist/media-process.js +89 -0
  78. package/dist/media-process.js.map +1 -0
  79. package/dist/media.d.ts +3 -3
  80. package/dist/media.d.ts.map +1 -1
  81. package/dist/media.js +5 -5
  82. package/dist/media.js.map +1 -1
  83. package/dist/merge-policy.d.ts +16 -36
  84. package/dist/merge-policy.d.ts.map +1 -1
  85. package/dist/merge-policy.js +13 -125
  86. package/dist/merge-policy.js.map +1 -1
  87. package/dist/metadata.d.ts +1 -0
  88. package/dist/metadata.d.ts.map +1 -1
  89. package/dist/metadata.js +13 -3
  90. package/dist/metadata.js.map +1 -1
  91. package/dist/migrate-grid-text.d.ts +17 -0
  92. package/dist/migrate-grid-text.d.ts.map +1 -0
  93. package/dist/migrate-grid-text.js +117 -0
  94. package/dist/migrate-grid-text.js.map +1 -0
  95. package/dist/migrate-grid-v22.d.ts +12 -0
  96. package/dist/migrate-grid-v22.d.ts.map +1 -0
  97. package/dist/migrate-grid-v22.js +166 -0
  98. package/dist/migrate-grid-v22.js.map +1 -0
  99. package/dist/migrate-grid-v23.d.ts +10 -0
  100. package/dist/migrate-grid-v23.d.ts.map +1 -0
  101. package/dist/migrate-grid-v23.js +31 -0
  102. package/dist/migrate-grid-v23.js.map +1 -0
  103. package/dist/migration-notebooks.d.ts +25 -0
  104. package/dist/migration-notebooks.d.ts.map +1 -0
  105. package/dist/migration-notebooks.js +131 -0
  106. package/dist/migration-notebooks.js.map +1 -0
  107. package/dist/migration-source.d.ts +6 -0
  108. package/dist/migration-source.d.ts.map +1 -0
  109. package/dist/migration-source.js +37 -0
  110. package/dist/migration-source.js.map +1 -0
  111. package/dist/migration-timeline.d.ts +36 -0
  112. package/dist/migration-timeline.d.ts.map +1 -0
  113. package/dist/migration-timeline.js +187 -0
  114. package/dist/migration-timeline.js.map +1 -0
  115. package/dist/migration-validation.d.ts +12 -0
  116. package/dist/migration-validation.d.ts.map +1 -0
  117. package/dist/migration-validation.js +68 -0
  118. package/dist/migration-validation.js.map +1 -0
  119. package/dist/migration.d.ts.map +1 -1
  120. package/dist/migration.js +220 -119
  121. package/dist/migration.js.map +1 -1
  122. package/dist/model-cache-paths.d.ts +2 -0
  123. package/dist/model-cache-paths.d.ts.map +1 -0
  124. package/dist/model-cache-paths.js +5 -0
  125. package/dist/model-cache-paths.js.map +1 -0
  126. package/dist/model-checksums.json +338 -0
  127. package/dist/model-file-resolver.d.ts +30 -0
  128. package/dist/model-file-resolver.d.ts.map +1 -0
  129. package/dist/model-file-resolver.js +304 -0
  130. package/dist/model-file-resolver.js.map +1 -0
  131. package/dist/model-identity.d.ts +13 -0
  132. package/dist/model-identity.d.ts.map +1 -0
  133. package/dist/model-identity.js +44 -0
  134. package/dist/model-identity.js.map +1 -0
  135. package/dist/model-worker-errors.d.ts +3 -0
  136. package/dist/model-worker-errors.d.ts.map +1 -0
  137. package/dist/model-worker-errors.js +12 -0
  138. package/dist/model-worker-errors.js.map +1 -0
  139. package/dist/model-worker-pool.d.ts +32 -0
  140. package/dist/model-worker-pool.d.ts.map +1 -0
  141. package/dist/model-worker-pool.js +269 -0
  142. package/dist/model-worker-pool.js.map +1 -0
  143. package/dist/model-worker-protocol.d.ts +42 -0
  144. package/dist/model-worker-protocol.d.ts.map +1 -0
  145. package/dist/model-worker-protocol.js +2 -0
  146. package/dist/model-worker-protocol.js.map +1 -0
  147. package/dist/model-worker.d.ts +2 -0
  148. package/dist/model-worker.d.ts.map +1 -0
  149. package/dist/model-worker.js +91 -0
  150. package/dist/model-worker.js.map +1 -0
  151. package/dist/mvp-contract-fixtures.js +1 -1
  152. package/dist/mvp-contract-fixtures.js.map +1 -1
  153. package/dist/mvp-contracts.d.ts +32 -8
  154. package/dist/mvp-contracts.d.ts.map +1 -1
  155. package/dist/mvp-contracts.js +1 -1
  156. package/dist/mvp-contracts.js.map +1 -1
  157. package/dist/notebook/types.d.ts +1 -29
  158. package/dist/notebook/types.d.ts.map +1 -1
  159. package/dist/notebook-grid.d.ts +46 -0
  160. package/dist/notebook-grid.d.ts.map +1 -0
  161. package/dist/notebook-grid.js +187 -0
  162. package/dist/notebook-grid.js.map +1 -0
  163. package/dist/notebook-media-artifact.d.ts +23 -0
  164. package/dist/notebook-media-artifact.d.ts.map +1 -0
  165. package/dist/notebook-media-artifact.js +67 -0
  166. package/dist/notebook-media-artifact.js.map +1 -0
  167. package/dist/notebook-mentions.d.ts +20 -0
  168. package/dist/notebook-mentions.d.ts.map +1 -0
  169. package/dist/notebook-mentions.js +54 -0
  170. package/dist/notebook-mentions.js.map +1 -0
  171. package/dist/runtime-services.js +4 -9
  172. package/dist/runtime-services.js.map +1 -1
  173. package/dist/schema.d.ts +4 -19
  174. package/dist/schema.d.ts.map +1 -1
  175. package/dist/schema.js +66 -92
  176. package/dist/schema.js.map +1 -1
  177. package/dist/search-provider-access.d.ts +11 -0
  178. package/dist/search-provider-access.d.ts.map +1 -0
  179. package/dist/search-provider-access.js +42 -0
  180. package/dist/search-provider-access.js.map +1 -0
  181. package/dist/similarity.d.ts +60 -1
  182. package/dist/similarity.d.ts.map +1 -1
  183. package/dist/similarity.js +174 -154
  184. package/dist/similarity.js.map +1 -1
  185. package/dist/status.js +8 -10
  186. package/dist/status.js.map +1 -1
  187. package/dist/store.d.ts +16 -2
  188. package/dist/store.d.ts.map +1 -1
  189. package/dist/store.js +171 -17
  190. package/dist/store.js.map +1 -1
  191. package/dist/temporal-index-cache.d.ts +13 -0
  192. package/dist/temporal-index-cache.d.ts.map +1 -0
  193. package/dist/temporal-index-cache.js +59 -0
  194. package/dist/temporal-index-cache.js.map +1 -0
  195. package/dist/temporal-model-manifests.d.ts +17 -0
  196. package/dist/temporal-model-manifests.d.ts.map +1 -0
  197. package/dist/temporal-model-manifests.js +33 -0
  198. package/dist/temporal-model-manifests.js.map +1 -0
  199. package/dist/temporal-models.d.ts +20 -35
  200. package/dist/temporal-models.d.ts.map +1 -1
  201. package/dist/temporal-models.js +23 -257
  202. package/dist/temporal-models.js.map +1 -1
  203. package/dist/temporal-search.d.ts +6 -3
  204. package/dist/temporal-search.d.ts.map +1 -1
  205. package/dist/temporal-search.js +438 -122
  206. package/dist/temporal-search.js.map +1 -1
  207. package/dist/temporal-vector-index.d.ts +46 -0
  208. package/dist/temporal-vector-index.d.ts.map +1 -0
  209. package/dist/temporal-vector-index.js +220 -0
  210. package/dist/temporal-vector-index.js.map +1 -0
  211. package/dist/third-party/@huggingface-jinja.LICENSE +21 -0
  212. package/dist/third-party/@huggingface-tokenizers.LICENSE +201 -0
  213. package/dist/third-party/@huggingface-transformers.LICENSE +202 -0
  214. package/dist/third-party/onnxruntime-common.LICENSE +21 -0
  215. package/dist/third-party/versions.json +23 -0
  216. package/dist/transformers-runtime.d.ts +2 -0
  217. package/dist/transformers-runtime.d.ts.map +1 -0
  218. package/dist/transformers-runtime.js +33014 -0
  219. package/dist/transformers-runtime.js.LEGAL.txt +12 -0
  220. package/dist/transformers-runtime.js.map +7 -0
  221. package/docs/doltlite-staging.md +69 -0
  222. package/docs/edit-performance.md +83 -0
  223. package/docs/engine-layout.md +56 -50
  224. package/docs/media-limits.md +57 -0
  225. package/docs/model-download-policy.md +15 -0
  226. package/docs/model-integrity.md +72 -0
  227. package/docs/model-isolation.md +72 -0
  228. package/docs/model-revisions.md +54 -0
  229. package/docs/mvp-prd.md +2 -2
  230. package/docs/release-evidence.md +300 -0
  231. package/docs/search-provider-consent.md +67 -0
  232. package/docs/semantic-durability.md +55 -0
  233. package/docs/temporal-search-performance.md +260 -0
  234. package/docs/v4-migration.md +83 -0
  235. package/fixtures/v5/contract-fixtures.json +4 -4
  236. package/package.json +31 -13
  237. package/dist/artifact-names.d.ts +0 -6
  238. package/dist/artifact-names.d.ts.map +0 -1
  239. package/dist/artifact-names.js +0 -56
  240. package/dist/artifact-names.js.map +0 -1
  241. package/dist/resolver.d.ts +0 -15
  242. package/dist/resolver.d.ts.map +0 -1
  243. package/dist/resolver.js +0 -81
  244. package/dist/resolver.js.map +0 -1
@@ -0,0 +1,54 @@
1
+ # Immutable model revision selection
2
+
3
+ Built-in CLIP, CLAP and MiniLM models continue to use their existing pinned commits. No new model setting is needed for their default configuration. The compatibility image/video vector cache requires a one-time reindex, as described below. Temporal, audio and text default embedding identities are unchanged.
4
+
5
+ For a custom remote model used by the compatibility similarity API, supply `modelRevision` alongside `modelId`. It must be a full 40-character hexadecimal commit SHA from that model repository. Branch names, tags, abbreviated hashes and omitted custom revisions fail with `INVALID_INPUT` before any model request. Uppercase hashes are normalized to lowercase.
6
+
7
+ ```typescript
8
+ const engine = createEngine({
9
+ rootDir,
10
+ similarity: {
11
+ modelCacheDir,
12
+ modelId: "your-org/compatible-clip",
13
+ modelRevision: clipCommitSha,
14
+ allowModelDownload: true,
15
+ audio: {
16
+ modelId: "your-org/compatible-clap",
17
+ modelRevision: clapCommitSha,
18
+ },
19
+ text: {
20
+ modelId: "your-org/compatible-minilm",
21
+ modelRevision: textCommitSha,
22
+ },
23
+ },
24
+ });
25
+ const prepared = await engine.similarity.prepare();
26
+ ```
27
+
28
+ Each `*CommitSha` variable above is the actual full commit ID selected by the application. The engine does not resolve a moving alias implicitly. Supplying another commit for a built-in repository is also supported and creates a distinct custom embedding identity. Audio and text select their own repositories and revisions; they do not inherit the visual model selection. The existing cache-directory and download-permission inheritance rules are unchanged.
29
+
30
+ Custom models must remain compatible with the corresponding pipeline: 512-dimensional CLIP image/video embeddings, 512-dimensional CLAP audio embeddings or 384-dimensional MiniLM text embeddings, with the supported quantization and preprocessing. Selecting a commit does not make an incompatible model architecture compatible.
31
+
32
+ ## Coherent loading and index identity
33
+
34
+ The selected repository and commit are copied into the model worker configuration and worker-session key. Every model-file request must agree with them, including tokenizer/config files and external ONNX weights. A request for another repository, another commit or an omitted/moving revision fails with `MODEL_UNAVAILABLE`. Remote selections do not fall back to unversioned files under Transformers' `localModelPath`; use an explicit directory model ID for trusted local files.
35
+
36
+ Custom embedding-space identities include the provider kind, exact repository, full revision and preprocessing version through a SHA-256 digest. Repository names that previously collided after punctuation normalization now remain distinct. A different revision cannot reuse vectors from an existing space, even while the old model worker is warm. Changing a caller's configuration object after Engine construction does not alter the selected model.
37
+
38
+ Existing custom-model vector identities intentionally change. Reindex custom-model artifacts after supplying the commit. The API shape remains source-compatible on version 5.3.1, but old custom remote configurations without a commit now fail closed rather than loading `main`.
39
+
40
+ Older compatibility image/video vectors are ambiguous: custom image models previously used the same embedding-space string as the built-in CLIP model, without recording which model produced a row. The compatibility visual space now uses `compat-visual-v2`, including for the default model. This requires a one-time reindex of compatibility image/video artifacts and prevents old custom vectors from silently being treated as built-in vectors. Until reindexed, status returns `not_indexed` and similarity queries return `NOT_READY`. Source media and the old derived rows remain intact. The media library's temporal index and the default compatibility audio/text spaces retain their identities; model files do not need to be downloaded again.
41
+
42
+ Model downloads still require explicit permission. After online preparation, the selected revision's verified cached files and integrity receipts support offline preparation, indexing and queries. Changing to a revision that is not cached returns `OFFLINE`; it does not substitute another revision. [Model integrity verification](model-integrity.md) describes digest verification and its trust boundary for custom repositories.
43
+
44
+ ## Local directories
45
+
46
+ Absolute paths and explicit relative paths beginning with `.` remain supported as trusted local model directories, without `modelRevision` or network access. Relative paths are resolved when the provider is configured. Equivalent resolved paths share an identity; different directory paths have distinct identities. `modelRevision` applies only to remote repositories and is rejected for directory selections.
47
+
48
+ Keep each local model version in a separate immutable directory. Local directories do not carry a verified upstream commit, and their contents are not authenticated as a remote snapshot. Replacing files in place requires application-owned reindexing; the engine does not claim that a path alone makes local bytes immutable.
49
+
50
+ Injected embedding providers manage their own model identity and revisions. These options apply to built-in loader implementations, not to arbitrary injected code. Injected providers remain subject to the [network declaration and application consent contract](search-provider-consent.md).
51
+
52
+ ## Verification
53
+
54
+ `tests/model-revision.test.ts` uses actual Engine APIs and an HTTP receiver to cover rejected revisions with zero requests, all three modalities' pinned requests, separate identities, configuration snapshots, local-directory selection, and cross-repository/revision file rejection. `tests/model-revision.e2e.test.ts`, enabled by `VIDEOBOOK_RUN_CUSTOM_MODEL_E2E=1`, serves real cached CLIP/CLAP/MiniLM files under custom repository IDs and verifies coherent revision requests, indexing, offline reopen, revision isolation, retained source bytes and explicit local-directory inference. It requires the three fixture models to have been prepared separately; it does not download them from an external service.
package/docs/mvp-prd.md CHANGED
@@ -1,7 +1,7 @@
1
1
  # videobook-engine MVP Requirements
2
2
 
3
3
  > Historical design baseline: this document proposed the 3.x/schema-v5
4
- > transition. The implemented package is 4.0.0 with catalog schema v18; current
4
+ > transition. The implemented package is 4.2.0 with catalog schema v19; current
5
5
  > API and layout documentation take precedence.
6
6
 
7
7
  ## Temporal media retrieval and a reversible edit engine
@@ -365,7 +365,7 @@ runtime structures capable of many segments and modalities per artifact:
365
365
  | Segment text | Transcript/OCR/description/metadata text, language, half-open UTF-8 byte offsets or timed source ranges, confidence, provenance |
366
366
  | Segment embeddings | Segment, modality, embedding space, dimensions, quantized vector, source hash, updated time; multiple spaces permitted |
367
367
  | Exact/near duplicates | Cryptographic hash and optional perceptual/frame fingerprints with extractor version |
368
- | Lexical index | FTS-capable index over transcript, OCR, descriptions, labels, slugs, and selected metadata |
368
+ | Lexical index | FTS-capable index over transcript, OCR, descriptions, labels, and selected metadata |
369
369
  | ANN indexes | Cached per embedding space and compatible query modality, rebuilt from runtime rows |
370
370
 
371
371
  All runtime tables remain excluded from Dolt staging. A stale manifest or source
@@ -0,0 +1,300 @@
1
+ # MVP release evidence
2
+
3
+ Audit date: September 6, 2026 (Asia/Bangkok). Functional baseline: engine
4
+ `c4f1d89` (5.3.2, DoltLite 0.50.6), consumer `92f1f2c6`.
5
+ Performance artifacts retain their original revision and hardware
6
+ qualifications.
7
+ This is an assessment of the requirements in
8
+ `docs/mvp-prd.md`, not a release approval. E4, E5 and the MVP remain incomplete.
9
+ Beads contains the work assignments and current status; this report records
10
+ the evidence and its limits at these revisions.
11
+
12
+ ## Current patch candidate
13
+
14
+ Engine `c4f1d89` adopts DoltLite 0.50.6. Both default and all-table staging
15
+ probes now pass on the real 12-table fixture, and URL bootstrap preserves the
16
+ complete catalog. Catalogs seeded with the previous engine's 0.11.37 and the
17
+ consumer's 0.11.51 reopen with identical committed head, history, table counts,
18
+ semantic projections, contents, and runtime settings; restore and new writes
19
+ remain durable after another reopen.
20
+
21
+ Native merge still rejects clean catalogs containing ignored runtime tables.
22
+ `scripts/dolt-ignored-merge-probe.cjs` reproduces this even without secondary
23
+ indexes; its semantic-only control succeeds. Production retains the projection
24
+ merge and its existing policies. `ve-wsu` remains blocked on the native merge
25
+ limitation; the staging and URL-bootstrap fixes do not close it.
26
+
27
+ The engine passes 352 default tests, typecheck, dead-code checks, build, and
28
+ clean packed README/reopen/media checks, including cached CLIP/CLAP image,
29
+ audio, and text inference. The package has one Sharp resolution and no
30
+ production audit findings. Consumer `92f1f2c6` passes 3,218 tests across 375
31
+ files, lint, all four test typechecks, dead-code checks, and client/server builds.
32
+ Its explicit cached-model, readiness, bounded-batch/resume, and reference-range
33
+ run passes all 24 cases on `92f1f2c6`. Its isolated exact committed-source
34
+ clean install passes native Sharp,
35
+ MCP create/list, client delivery, and graceful shutdown without a sibling engine
36
+ checkout. The consumer corpus validator now rejects unverified rights metadata,
37
+ non-finite durations/counts, and fractional counts; its runner is typechecked
38
+ against the current book identity API. These synthetic manifest checks do not
39
+ supply a quality corpus.
40
+
41
+ The application CI run exposed three additional issues, corrected in
42
+ `92f1f2c6`. Watermark text is now centered by its rendered glyph bounds rather
43
+ than platform-specific SVG baseline metrics; changed badge variants use new
44
+ cache layout identifiers. Queued watermark burns declare processing work, and
45
+ upload discovery respects active queued jobs even before they claim a lock.
46
+ This prevents a second processing job from racing the watermark operation and
47
+ removing its frame directory during ingestion. The GC fixture stops its
48
+ background worker before creating 2,000 leased churn rows, avoiding a large
49
+ expired-job abort sweep during teardown. Its size assertions are unchanged.
50
+ The original rendering and queued-job failures reproduce on Linux; all 41
51
+ focused cases pass after the fixes on both macOS and Debian 13/x64. The full
52
+ application CI command passes locally in both stages (3,214 plus four tests),
53
+ with all typechecks, lint, dead-code checks and both builds passing.
54
+
55
+ The catalog-GC churn case allows 180 seconds for its 2,000 synchronous job
56
+ write/dequeue/heartbeat iterations on shared CI runners. Its 200 ms reopen and
57
+ 16 MiB catalog-size assertions are unchanged. The focused seven-case suite
58
+ passes locally; the timeout change addresses the 84-second fixture that
59
+ exceeded the previous 60-second watchdog on Node 22.
60
+
61
+ The candidate is a patch within the existing 5.x series. No 2.0.0 release or
62
+ major bump is planned. Registry publication and frozen-corpus quality remain
63
+ outstanding. The M2 Pro reference-device run is deferred because the user
64
+ confirmed that the hardware is unavailable.
65
+
66
+ ## Performance and quality
67
+
68
+ The available machine reports Apple M1 Pro, 10 logical CPUs and 16 GiB RAM.
69
+ The PRD specifies M2 Pro, 16 GB RAM and local SSD. Existing measurements retain
70
+ their actual hardware qualification; none is an M2 Pro acceptance run. The
71
+ reference-device measurements are deferred in `ve-ovz.22` following the user's
72
+ September 6 confirmation that no M2 Pro is available. The passing M1 Pro results
73
+ remain the available benchmark evidence. This exact-device check does not
74
+ block publication of the already validated 5.3.2 patch.
75
+
76
+ | Requirement | Evidence inspected | Assessment and follow-up |
77
+ | --- | --- | --- |
78
+ | VE-NFR-001: 1,000-artifact open and semantic summary <2 s | Clean engine `c4f1d89`: 171 ms same-process after a fresh 1,000-artifact/100,000-moment build and 1,714 ms in a fresh process reopening the retained fixture. Raw reports: `temporal-100k-doltlite-0506.json` and `temporal-100k-doltlite-0506-reopen.json`, both on M1 Pro. | Passes on measured hardware for the current source. The M2 Pro reference-device run remains outstanding and is tracked explicitly; M1 Pro results are not equated with it. |
79
+ | VE-NFR-002: metadata and imported normalized transcript searchable <5 s after semantic commit | Consumer `tests/v2/text-readiness.test.ts` times the real job queue on a real probed video: analysis metadata write to first lexical hit 688 ms (OCR text 689 ms), transcript import to first quoted speech hit 314 ms, both under the 5 s gate with model downloads disabled and no cached model. | Passes end to end through the application's actual enqueue, poll, index and lexical query path on M1 Pro. |
80
+ | VE-NFR-003: searchable coverage at least every 60 source seconds, resume last committed batch | Synthetic benchmark: 4,000 batches of at most 30 source seconds, every cursor checked, first coverage 45 ms. The consumer's fixed four-unit deep batches could exceed 60 s on videos longer than about seven minutes because frame sampling caps at 30 frames; `commitDeepBatches` now bounds each CLIP/CLAP batch by covered source seconds. Consumer `tests/v2/semantic-index-cadence.test.ts` verifies the bound and durable-cursor resume through the engine, and the explicit real-model case runs the actual CLIP pipeline on a real ten-minute video: 15 two-frame batches of at most 41.4 s, interruption after two batches, resume from cursor 4 without re-embedding committed frames, and retrieval of the source. | Passes for the actual model pipeline. A single sampled frame whose own span exceeds 60 s (videos over about 29 minutes) is committed alone; frame density itself is a quality question for the frozen corpus, not a cadence failure. |
81
+ | VE-NFR-004: 100k moments, warm p50 <500 ms, p95 <1.5 s including hybrid | Clean `c4f1d89` fresh build: 50 warm reads per mode, p50/p95 image 59/66 ms, video 113/165 ms, hybrid 332/411 ms; fresh-process reopen: image 60/73 ms, video 117/179 ms, hybrid 310/388 ms. | Passes the full synthetic workload on the current source, M1 Pro. Reference-device run outstanding and tracked explicitly. |
82
+ | VE-NFR-005: 100-operation preview on 1,000 clips, p95 <250 ms, no mutation | Clean `c4f1d89`, `npm run benchmark:edits` (`docs/edit-performance.md`): 50 independent previews of fresh 100-operation batches against 1,000 clips, p50 105 ms, p95 114 ms, max 118 ms; head revision, every table row count and the canonical sequence projection unchanged after each preview. Recorded in `benchmarks/results/edit-100x1000-doltlite-0506.json`. | Passes with strict gates on M1 Pro. `tests/edit-transactions.test.ts` keeps its single-sample 500 ms tripwire for shared CI runners. |
83
+ | VE-NFR-006: same commit batch, p95 <1 s | Same run: 50 independent commits, p50 299 ms, p95 331 ms, max 348 ms; every commit advanced the head and applied all 100 transforms; reopened catalog exposes the last revision. | Passes on M1 Pro; no derived jobs run inside `edits.commit`. |
84
+ | VE-NFR-007: 100k query/index structures <4 GB RSS beyond loaded model | Clean `c4f1d89` fresh build and query process peak 3.03 GiB including fixture construction; fresh-process reopen and 150 queries 2.08 GiB; no model loaded. | Passes on the current source, M1 Pro. Reference-device run outstanding. |
85
+ | VE-NFR-008: forced termination at every SQL/outbox/Dolt boundary | Baseline edit tests only threw exceptions and closed normally. Subsequent `tests/semantic-crash.test.ts` covers real SIGKILL at each semantic/outbox/table-staging/Dolt boundary for a multi-table edit and provenance operation, including interrupted recovery and an intervening write. | Kill matrix exposed and corrected duplicate provenance replay. See `docs/semantic-durability.md` for scope and invariants; tracked in `ve-ovz.10`. |
86
+ | VE-NFR-009: stable search ordering, identical canonical previews/hashes | Current-source temporal runs repeat every first query per mode against the unchanged generation and require identical hits; the edit distribution run previews each of 50 large batches twice and requires identical canonical operations, ranges, write sets, diffs and all hashes. | Passes for the exact 100-operation/1,000-clip workload and the 100k search workload. |
87
+ | VE-NFR-010: every application frozen-corpus quality threshold | E4 evaluator and small real-model fixtures exist | Full rights-cleared frozen corpus and judged ranges absent. `ve-s84` remains incomplete; synthetic scale data cannot replace it. |
88
+ | VE-NFR-011: with required models cached, search/index/edit/history initiates no network | Per-Engine local-media scopes; nine engine regressions and ten installed-app workflow cases. A real cached CLIP queue index/reference/library/temporal-search/edit/history workflow makes zero model or B2 HTTP requests. Missing-media cases also stay offline, including migration frame preparation. | Media hydration policy and these complete built-in workflows are verified in `ve-ovz.19`. Arbitrary callback networking and explicitly consented remote providers are separate boundaries; input scoping and the remaining owned-service privacy checks are complete in `ve-ovz.14`. |
89
+ | VE-NFR-012: bounded scale degradation, no corruption/unbounded React payloads/full-vector scan each query | Native ANN candidate retrieval, bounded video starts/windows, stable pagination, cache deletion/replacement regressions; clean `c4f1d89` indexes 100k moments in 4,000 bounded batches (320 s including preparation) and pages at most 100 hits per query; consumer deep batches are bounded by source seconds. | Search architecture and the measured 100k workload pass on the current source. Larger-than-100k books degrade through longer indexing only by design; no measurement beyond 100k moments exists. |
90
+
91
+ Detailed benchmark provenance and raw samples are linked from
92
+ `docs/temporal-search-performance.md`. Reused fixtures inherit original
93
+ indexing metrics; they do not measure a fresh index build. First-query times
94
+ include snapshot loading and are not warm-query latency or cold OS-cache tests.
95
+
96
+ ## Security and privacy
97
+
98
+ | Section 13 requirement | Evidence inspected | Assessment and follow-up |
99
+ | --- | --- | --- |
100
+ | Opt-in/configurable, pinned, checksum-verified and disableable model downloads | Engine defaults local-only; built-in pinned model inventories carry upstream Git/LFS digests. The verified file resolver checks downloads and cached files before returning bytes or ONNX paths, including external weights. Real transfers, corrupt caches and installed-package rejection are tested. | Checksum hardening and custom commit pinning are integrated in consumer `80ce4f58`. Remote file requests must match the worker repository/revision, and embedding identities isolate revisions. See `docs/model-integrity.md` and `docs/model-revisions.md`. |
101
+ | Scoped provider inputs, local built-in provider, injected network declaration and application consent | Explicit download/inference declarations and separate application grants guard temporal and compatibility dispatch. Actual HTTP tests cover rejected and authorized providers, revocation, changed declarations, and per-Engine scope. CLIP/CLAP declare local inference. | Engine and consumer consent integration are verified. Identical registrations preserve overlapping searches; replacement/removal revokes later calls. Consumer `tests/v2/search-reference-range-scope.test.ts` proves the application's `search_moments` forwards only the prepared reference and the requested `reference_range` window: each window retrieves only its own moment, negative, zero-length and frame-less windows and image references with ranges fail before any search, and unknown reference ids are rejected. |
102
+ | Argument arrays, bounded outputs, timeouts, cancellation and scoped workspaces; no untrusted shell | Shared media-process limits and isolated model pool provide deadlines, process-group cancellation and owned scratch cleanup. Consumer actual queue tests cancel stalled model requests and preserve source bytes/status. | Engine isolation and consumer signal forwarding are implemented and tested. See `docs/media-limits.md` and `docs/model-isolation.md`. |
103
+ | Malformed codec, oversized image, decompression bomb and model OOM fail job without book corruption | Tests reject malformed/oversized/high-expansion inputs; an actual heap-exhausted worker leaves a live engine writable and reopenable and permits fresh-worker retry. Consumer cached-model queue tests verify malformed-image failure and corrected retry. | Process isolation, typed job failures and consumer integration are verified. The worker heap cap is not an OS-wide memory limit. |
104
+ | Excerpts/explanations treated as user content | Consumer `tests/v2/search-hostile-content.e2e.test.ts` seeds a real book whose name, artifact label and indexed description carry script, event-handler and javascript: payloads, serves it through the actual MCP server and Vite app in Chromium, and verifies the library search card header, excerpt, thumbnail alt text, signal chip title, notice text and media library dialog render the literal strings; injected hostile explanation and error responses render literally too. No window marker is set, no active element exists, and no page error occurs. | Complete for every owned search result surface (`vb-3esp`). Media response sandboxing remains separately verified. |
105
+ | Logs contain IDs/hashes/sizes/phases/codes rather than secrets/full content | Consumer `7cd32e85` routes owned runtime console and persistent diagnostics through fixed events and validated UUIDs, queue IDs, counts, enums and error codes. Tool/job names require trusted registration. Tests cover private returned/thrown errors, real queue/provider failures, book reopening, explicit chat history and a real subprocess with multi-megabyte private output. | `vb-wtu9` is complete: 3,160 default tests, 19 model/queue tests including all 3 real cached-model cases, media rollback E2E, lint/types/knip/builds and isolated clean install pass. Full caller/job error details and explicit chat content remain available; old diagnostic files are not rewritten. The remaining owned-service offline/privacy invariants are verified in `ve-ovz.14`. |
106
+ | Content hashes are identity, not authorization | Engine provider tests reject foreign artifact UUIDs and raw hash/path references. Actual HTTP file, manifest, and range tests reject mismatched owning books and raw hashes. All HTTP routes reject foreign Origin/Host before parsing or accessing content. | Consumer `9d0179ad` (`vb-0ujh`) enforces loopback Host/Origin policy and binds to `127.0.0.1`. It remains a local single-user service: native clients and accepted local origins can access all books. Hashes and UUIDs are not credentials; this is not a remote or multi-user authentication design. |
107
+ | Remote publication/backup explicit, never triggered by local search | Actual application B2 HTTP counters stay empty through cached indexing, reference preparation, search, edits and history. Explicit backup then performs HEAD/PUT/verification. A configured local catalog backup target stays absent through indexing/search/history and is written only by explicit backup. | The tested object-store and catalog publication boundaries are verified. This is not an authorization audit of every transport or remote service. Owning-book/API access and the remaining owned-service privacy checks are verified in `ve-ovz.14`. |
108
+
109
+ Remote hydration integrity is verified in engine `07f0515` and consumer
110
+ `20db91d1` (`ve-ovz.18` / `vb-fuib`). Eight engine HTTP/public-API cases cover
111
+ same-size wrong content, partial failures, concurrent valid/corrupt transfers,
112
+ state preservation, retry, cached reuse, and a forget during download. SHA-256
113
+ verification precedes local publication; a final synchronous tombstone check
114
+ and rename prevent an in-flight download from republishing forgotten bytes.
115
+ The actual application B2 adapter rejects a corrupt HTTP response and supports
116
+ valid retry and cached reads after the fixture server shuts down. Existing local
117
+ objects are not rehashed on every read. This evidence does not establish
118
+ cross-book authorization or the complete offline workflow.
119
+
120
+ Engine `bf952c5` adds `withLocalMedia`: asynchronous per-book scopes block implicit
121
+ CAS downloads with typed `MEDIA_MISSING`, while concurrent explicit reads and
122
+ other books remain independent. Compatibility and temporal search/indexing,
123
+ edits and history use the policy automatically. Restores succeed for committed
124
+ metadata when unavailable bytes prevent workspace hydration. Consumer `96892e26`
125
+ applies the scope to direct and queued semantic indexing (including migration
126
+ frames), temporary references, library asset projection, and ingest status/retry.
127
+ Auxiliary failures preserve source-media readiness. Nine missing-media app cases
128
+ exercise the actual B2 adapter and explicit retrieval retry; the additional
129
+ cached-model case covers search, edits, restoration and explicit backup.
130
+
131
+ This completes `ve-ovz.19` / `vb-ld4o`, not the complete security/privacy audit.
132
+ Cold-index preparation in the media picker was fixed separately in consumer
133
+ `185ec77c` (`vb-ackl`), with a real 1,200-vector queue/poll/retry and
134
+ persisted-index regression.
135
+
136
+ Consumer `64da847a` completes `vb-j3qy`: completed image-subject edits, Library
137
+ copies and Duplicate Asset schedule detached indexing jobs deduplicated by
138
+ artifact and source hash. Semantic indexing and frame preparation select stream
139
+ records matching the current file mapping, rather than an older stream for the
140
+ same path. The Library reports missing current-source CLIP coverage and offers
141
+ an explicit repair action; its MCP endpoint returns queued per-book jobs and the
142
+ client polls their status. Repair skips covered media, prepares missing video
143
+ frames, continues past per-asset failures and preserves source readiness.
144
+
145
+ Validation includes 3,176 default tests across 371 files, explicit cached-model
146
+ repair of zero-vector and stale-stream cases, corrupt-media continuation and
147
+ idempotence, and a real Chromium Library repair/poll/Similar-search flow. Lint,
148
+ test types, client/server builds, dead-code checks, generated command references
149
+ and isolated clean installation pass. The original failing edited image now
150
+ ranks itself first with no book errors. A saved-library repair resolved all 74
151
+ current-source coverage gaps; the final scan reports zero missing visual
152
+ indexes. One empty copied video was recovered from its exact preceding
153
+ nonempty artifact revision after SHA-256, dimensions and duration verification
154
+ (`vb-v9nq`), then indexed and retrieved successfully. These fixture and local
155
+ library results do not replace the frozen-corpus or reference-hardware gates.
156
+
157
+ Provider dispatch scoping is hardened in Engine `dffaf21` (`ve-ovz.20`).
158
+ Compatibility preparation and embedding receive a fresh options object containing
159
+ only the supplied cancellation signal and timeout. Actual HTTP fixtures showed
160
+ that the previous implementation transmitted extra application context and let
161
+ providers mutate query controls. Six regressions now verify all four modalities,
162
+ selected file/text transmission, caller-option isolation, rejected foreign-book
163
+ UUIDs and raw hash/path references, and temporal reference/query separation.
164
+ The engine's 347 default tests, types, dead-code checks, build and installed
165
+ package smoke test pass, as does Node 22/24 CI. See
166
+ `docs/search-provider-consent.md` for the trusted in-process provider boundary.
167
+ Consumer `0661c994` vendors the exact verified package (SHA-256
168
+ `cb71bf39f3a088058b44273e402569c0a7c90bbb8abb8866f4118979d5ddfbb8`).
169
+ Its 3,176 default tests, 35 explicit model/offline/repair cases, lint, test
170
+ types, client/server builds, dead-code checks and isolated clean install pass.
171
+ `vb-g3ai` is complete; its application commit was local at that validation point.
172
+
173
+ The HTTP audit reproduced private fixture disclosure through modern MCP with
174
+ an untrusted Origin and Host. Consumer `9d0179ad` fixes this at both the direct
175
+ MCP handler and Express entry, before CORS, body parsing, static files, or API
176
+ routes. The server binds to `127.0.0.1`, accepts loopback browser origins and
177
+ native clients, and permits the bundled extension's exact stable origin.
178
+ Twenty-three direct-handler cases and actual HTTP/Chromium tests cover foreign,
179
+ opaque and malformed origins; rebinding hosts; all routes including uploads and
180
+ archives; permitted preflight; extension-worker MCP discovery/tool calls; and
181
+ owning-book/hash/range denials. The public extension key pins a development ID,
182
+ not a credential. Consumer README documents the trusted local-client boundary.
183
+
184
+ A subsequent real browser fixture exposed another path: uploaded SVG scripts
185
+ ran in the media server's origin and read private book names through MCP.
186
+ Consumer `43d31b32` applies CSP sandbox and `nosniff` to media and archive
187
+ responses. The identical private-query fixture no longer executes. Browser
188
+ regressions verify blocked SVG/HTML scripts, forms, and external resource
189
+ requests, preserved inline SVG styling and image rendering, and actual H.264
190
+ playback. The final combined run also verifies the Library's real cached-model
191
+ repair and Similar search flow. All 3,199 default tests across 372 files,
192
+ seven explicit HTTP/Chromium/model E2E cases, lint, test types, dead-code checks,
193
+ client/server builds, and isolated clean installation pass.
194
+
195
+ `vb-0ujh`, `vb-sby1`, `vb-3esp`, and `vb-bkgq` are complete. Consumer
196
+ `fc751e79` adds the hostile search text browser checks and application provider
197
+ range/input evidence that close `ve-ovz.14`. Its full default suite passed
198
+ 3,202 tests across 374 files, with lint, test types, dead-code checks, and both
199
+ builds passing. These local service checks do not establish authentication
200
+ for remote or multi-user deployments.
201
+
202
+ ## Migration, consumer and packaging
203
+
204
+ Section 15.4 migration is covered by `tests/migration.test.ts`, the pinned v4
205
+ schema fixture and consumer migration tests. Evidence includes valid notebook
206
+ graphs/generation choices, properties/prompts/messages, real timed media,
207
+ empty and large catalogs, content-hash validation, unchanged source bytes,
208
+ identical reruns, cancellation/process interruption and source edits before
209
+ publication. Consumer queue tests cover durable status/cancel, archive/switch
210
+ recovery and idempotent reindex scheduling. `ve-ovz.5`, `ve-ovz.6` and `vb-6eu9`
211
+ are complete. This migration evidence does not prove general edit durability.
212
+
213
+ Engine `e328f5e` passed 341 default tests (12 opt-in cases skipped), typecheck
214
+ and knip. Runtime `bf952c5` also passed build and standalone installed-package
215
+ checks for local-media denial, explicit retry, checksum rejection, README usage,
216
+ and native image decoding. [Node 22/24 runtime CI](https://github.com/justintanner/videobook-engine/actions/runs/34007728660)
217
+ passed. `e328f5e` adds only the configured-catalog publication regression.
218
+ Consumer `96892e26` passed 3,171 default tests across 370 files (4 opt-in cases
219
+ skipped), 38 final explicit workflow/migration/indexing checks including the real
220
+ cached-model workflow, and the separate 19 model/queue cases with all three
221
+ cached-model cases enabled. Lint, test types, dead-code checks, client/server
222
+ builds and the final isolated worktree clean install passed. The initial full run
223
+ caught the migration-frame hydration bypass while it was being fixed; the final
224
+ full-source run is green.
225
+
226
+ The earlier model-revision baseline `3f9b37d` passed 324 tests (12 opt-in tests skipped), typecheck, knip,
227
+ build and the 22-group API benchmark smoke. Node 22/24 CI passed tests,
228
+ builds and clean-package verification at `5db34ef`, which differs only by a
229
+ bounded cleanup retry in a merge test. The first Node 24 run failed removing
230
+ that temporary database directory after its assertions passed; no runtime
231
+ source or semantic assertion changed in the cleanup correction. The consent package was also installed
232
+ locally with explicit cached CLIP/CLAP inference enabled. Eleven provider-access
233
+ tests exercise actual HTTP dispatch, denied/changed/revoked consent, identical
234
+ registration during an overlapping query, and compatibility modalities.
235
+
236
+ Earlier consumer `80ce4f58` passed 3,151 tests across 366 files, lint, test types,
237
+ dead-code checks and both builds. Its three real-model queue cases, skipped by
238
+ default, passed in the explicit 37-test focused run. Those cases include an
239
+ existing-image Similar reference and indexed source retrieval with downloads
240
+ disabled. Corrupt pinned caches fail both actual indexing and reference jobs
241
+ with `MODEL_UNAVAILABLE` while source bytes/status remain unchanged. This
242
+ integration exposed a preparation race: missing tokenizer failure could precede
243
+ a corrupt config check in the other branch. Engine `162bdcd` awaits both
244
+ branches and prioritizes integrity failure; repeated public-provider and
245
+ consumer queue tests verify the correction.
246
+
247
+ Both worktree and exact committed-source (`80ce4f58`) clean installs passed
248
+ native Sharp, MCP create/list, client delivery and graceful shutdown without a
249
+ sibling engine checkout.
250
+
251
+ Consumer `b4e369b5` vendors `videobook-engine-5.3.2-c4f1d89.tgz`, SHA-256
252
+ `79f42f492fa569d13993f433da44a3b1ee11a4536fb54246d825d61978284c54`.
253
+ Its provenance file records the exact engine revision; application and engine
254
+ resolve one DoltLite 0.50.6 and one Sharp 0.35.4. The application remains 0.1.0.
255
+ Local package smoke and
256
+ vendored-consumer verification do not prove installation of a published
257
+ registry package: `ve-yc7` and `ve-orp` retain that release gate. Registry
258
+ authentication was rechecked on September 6, 2026 using the environment's
259
+ `NPM_TOKEN` explicitly through an isolated temporary npm configuration.
260
+ Both npm authentication and a direct registry authentication request returned
261
+ 401. Publishing the packed 5.3.2 candidate from `4b85f01` then failed with
262
+ `E404` on the registry PUT, reporting that the package was unavailable or the
263
+ token lacked access. No package version or release tag was created. The
264
+ temporary authentication configuration was removed. The obsolete 0.1.0 and
265
+ 2.0.0 publication tickets are superseded by
266
+ `ve-yc7`; they are not additional release targets.
267
+
268
+ Subsequent checksum hardening adds verified file resolution for all built-in
269
+ model paths, complete upstream digest inventories for three pinned snapshots,
270
+ cache-staging cleanup and public-provider corruption regressions. Nine explicit
271
+ real-model tests pass, including MiniLM external ONNX weights and offline reopen.
272
+ The installed package rejects corrupt pinned configuration and runs cached
273
+ CLIP/CLAP inference. The consumer now includes this verified resolver and
274
+ explicit application-owned provider download consent.
275
+
276
+ All 12 explicit real-model checks passed at model-revision baseline `3f9b37d`. The custom-revision
277
+ suite serves actual cached CLIP/CLAP/MiniLM files under custom repository IDs,
278
+ verifies fixed revision URLs and integrity receipts, indexes and queries real
279
+ media, reopens offline, rejects reuse under a different revision, and loads
280
+ explicit local model directories. Sixteen default contract tests cover missing
281
+ or moving revisions, configuration snapshots, repository-name collisions,
282
+ worker file scope, separate modality defaults and legacy visual cache safety.
283
+
284
+ Legacy compatibility custom image models previously shared the built-in CLIP
285
+ vector identity without recording their provenance. The compatibility visual
286
+ space now uses `compat-visual-v2`, requiring a one-time reindex instead of
287
+ reusing ambiguous old vectors. Temporal index identities, including those used
288
+ by the media library, are unchanged. Source files remain intact. This migration
289
+ and the commit requirement for custom remote models are documented in
290
+ `docs/model-revisions.md`; `ve-ovz.15` and consumer `vb-3f45` are complete.
291
+
292
+ The NFR measurement pass (`ve-ovz.9`) records current-source distributions
293
+ for VE-NFR-001/002/004/005/006/007/009/012 and the actual model-pipeline
294
+ cadence for VE-NFR-003 in this document, `docs/edit-performance.md` and
295
+ `docs/temporal-search-performance.md`. Every measured gate passes on the
296
+ available M1 Pro; the M2 Pro reference device named by the PRD has not been
297
+ measured and M1 Pro results are recorded as M1 Pro results only. The full
298
+ quality corpus (`ve-s84`) and published-package verification (`ve-yc7`, `ve-orp`)
299
+ remain outstanding. Exact reference-device acceptance (`ve-ovz.22`) is deferred
300
+ because the hardware is unavailable; full E4/E5/MVP acceptance is not claimed.
@@ -0,0 +1,67 @@
1
+ # Search provider network consent
2
+
3
+ Injected search providers must declare `networkAccess` with two explicit booleans:
4
+
5
+ - `modelDownloads`: preparation or execution may fetch model files.
6
+ - `inference`: execution may send query text or selected media to a remote service.
7
+
8
+ The declaration describes capability. It does not grant permission. The application supplies a separate `SearchProviderConsent`. Each permission defaults to denied and only literal `true` grants it. Download consent never authorizes remote inference.
9
+
10
+ ```typescript
11
+ const provider = new MySearchProvider({
12
+ networkAccess: { modelDownloads: false, inference: true },
13
+ });
14
+ engine.temporalSearch.providers.register(provider, { inference: true });
15
+ ```
16
+
17
+ The example assumes the application's configuration or user interaction has authorized remote inference. The engine does not display consent UI or infer authorization from a model manifest, provider name, or the fact that a provider was passed to it.
18
+
19
+ A local injected provider declares `{ modelDownloads: false, inference: false }` and needs no grant. The built-in temporal CLIP and CLAP providers declare local inference and model downloads according to their constructor's `allowModelDownload` option. Constructor options are copied and frozen. Explicit online preparation outside an Engine remains controlled by that constructor option. When registering a download-enabled built-in with an Engine, also pass `{ modelDownloads: true }`. For normal offline use, omit `allowModelDownload` and register without consent.
20
+
21
+ ## Registration and revocation
22
+
23
+ Temporal registration validates declarations and grants before accepting a provider. Missing or malformed declarations produce `INVALID_INPUT`; denied network permissions produce `OFFLINE`. A failed replacement leaves the existing registration intact.
24
+
25
+ Authorization is checked before every `prepare` and embedding invocation, including after an awaited preparation step. Grants and declarations are snapshotted. Changing the declaration requires registration again; mutating a previously supplied consent object does not change an existing grant. Re-register with the desired grant, or use:
26
+
27
+ ```typescript
28
+ engine.temporalSearch.providers.unregister(provider.manifestId);
29
+ ```
30
+
31
+ Registering the same provider with unchanged capabilities and grants is idempotent, so repeated registration does not interrupt overlapping searches. Removal or successful replacement revokes future calls through the old registration, including the embedding stage of a query currently awaiting preparation. It cannot recall content already delivered to a running provider. Registrations and grants belong to one Engine instance and are not persisted in semantic data, history, or action logs. Reopening an Engine requires registration again.
32
+
33
+ ## Compatibility similarity API
34
+
35
+ `EngineConfig.similarity.provider`, `.audio.provider`, and `.text.provider` use the same declarations and dispatch checks. Set `providerConsent` next to each injected provider:
36
+
37
+ ```typescript
38
+ const engine = createEngine({
39
+ rootDir,
40
+ similarity: {
41
+ provider: visualProvider,
42
+ providerConsent: { inference: true },
43
+ text: {
44
+ provider: textProvider,
45
+ providerConsent: { inference: true },
46
+ },
47
+ },
48
+ });
49
+ ```
50
+
51
+ These configurations are checked when the provider is invoked, returning the normal `Result` error from preparation, indexing, or query operations. Each modality owns its grant; audio and text do not inherit the visual provider's consent. Recreate the Engine to change a compatibility provider's grant. Built-in compatibility providers retain their existing `allowModelDownload` configuration and local inference behavior; `providerConsent` applies only to injected implementations.
52
+
53
+ The new properties are optional in TypeScript so existing integrations still compile on this patch version. **Undeclared injected providers fail at runtime.** Update them to declare their capabilities explicitly. This is an intentional fail-closed migration, not an inference that old providers are local.
54
+
55
+ ## Input and trust boundary
56
+
57
+ Temporal text dispatch supplies only the query string; preparation receives no search payload. Neither invocation receives the Engine, catalog, book metadata, candidate IDs or other artifacts. Pure reference queries operate on stored/prepared vectors without calling an embedding provider.
58
+
59
+ Compatibility dispatch resolves the artifact in the selected Engine before choosing its CAS media path or normalized text. A foreign-book artifact UUID, raw object hash or filesystem path cannot substitute for that artifact reference, even when the source bytes exist locally. Labels, metadata, sidecars and unrelated artifacts are not passed to the provider.
60
+
61
+ Each compatibility preparation and embedding invocation receives a fresh `MediaOperationOptions` object containing only supplied `signal` and `timeoutMs` controls. Query/index controls (`kind`, `force`, `limit`, `minScore`) and extra runtime application context remain inside the engine. Provider mutation of its options copy cannot alter the caller's query controls, and preparation cannot add fields to the later embedding options. The original cancellation signal is preserved.
62
+
63
+ Compatibility indexing authorizes its entire selected media source; it does not accept a time range. Direct application indexing and reference preparation still choose the media paths and ranges supplied to built-ins. Application range selection and HTTP access authorization require their own checks.
64
+
65
+ A declaration is a contract with trusted injected JavaScript, not a network sandbox. Providers can lie about capabilities, access their own ambient credentials, or inspect files accessible to the host process. Applications must trust and audit injected implementations. Consent gates prevent the engine from dispatching to undeclared, unauthorized, changed, or revoked providers; they do not intercept arbitrary socket or filesystem calls made by malicious code. These Engine dispatch checks do not prove HTTP/API authorization, filesystem isolation against malicious providers, or whole-application input/range scoping; those remain separate boundaries.
66
+
67
+ `tests/search-provider-access.test.ts` exercises actual Engine dispatch against an HTTP receiver, including rejected grants with zero requests, query-only transmission, frozen providers, Engine isolation, revocation/replacement during preparation, capability mutation, built-in declarations, compatibility image/video/audio/text denial and separate grants, exact selected-file/text transmission, rejected cross-book/path/hash references, copied operation controls and provider-mutation isolation. The HTTP fixtures explicitly carry private adjacent files, metadata and runtime context so unintended transmission fails the regression.
@@ -0,0 +1,55 @@
1
+ # Semantic commit recovery
2
+
3
+ Semantic mutations and their outbox entry commit in one SQL transaction.
4
+ The engine then stages each declared changed semantic table, creates one Dolt
5
+ revision carrying the operation ID, and removes the outbox entry in a second
6
+ SQL transaction. Reopening replays pending outbox entries before exposing the
7
+ catalog.
8
+
9
+ For a mutation that changes rows, recovery uses the remaining working diff to
10
+ finish the original commit. If that commit is already durable, no semantic
11
+ diff remains and recovery only clears the outbox. Provenance-only operations
12
+ intentionally create empty commits, so absence of a diff is ambiguous. During
13
+ recovery, the engine searches recorded operation IDs before creating another
14
+ empty commit. This includes an earlier committed operation followed by a later
15
+ successful write; checking only HEAD would duplicate the older entry.
16
+ After a failed semantic write, the next semantic write first recovers pending
17
+ outbox work. This preserves operation order and prevents a later mutation
18
+ from absorbing an earlier transaction's uncommitted history. Ordinary successful
19
+ writes do not add an outbox scan to their path.
20
+
21
+ `tests/semantic-crash.test.ts` launches separate Node processes against copies
22
+ of a closed fixture. It first records the actual boundary sequence for a
23
+ four-operation edit affecting clips and transforms and for a provenance-only
24
+ operation. It then sends the executing process SIGKILL at every observed
25
+ boundary, including every individual table-staging call. The callback writes
26
+ its boundary synchronously before termination; the parent checks both the
27
+ last boundary and the SIGKILL exit signal. A timeout cannot masquerade as a
28
+ successful boundary test.
29
+
30
+ The matrix covers:
31
+
32
+ - Semantic changes inside the SQL transaction, before outbox insertion.
33
+ - Outbox insertion before the semantic SQL commit, and immediately after it.
34
+ - Each table stage, before the Dolt commit, and immediately after it.
35
+ - Before outbox deletion, after deletion before its SQL commit, and after
36
+ that commit.
37
+ - Repeated termination during recovery of an already committed SQL batch.
38
+ - A committed provenance operation left in the outbox while another operation
39
+ succeeds, followed by process termination.
40
+
41
+ Before the semantic SQL commit, reopen must show the original state and no
42
+ new operation. After it, reopen must show all three clips, the transform and
43
+ exactly one corresponding history entry, or exactly one provenance entry.
44
+ The tests also verify the edit audit, empty outbox, no staged rows, subsequent
45
+ successful writes and repeated reopen. No graceful engine close runs in the
46
+ killed process. Existing exception-recovery tests remain useful for error
47
+ responses, but do not substitute for this matrix.
48
+
49
+ These tests verify application-visible transaction boundaries in the native
50
+ catalog on the executing platform. They do not simulate physical disk failure
51
+ or interrupt the interior of a native SQL statement. Migration publication
52
+ and consumer archive switching have separate process-interruption fixtures.
53
+ The optional `semanticCommitBoundary` callback is a diagnostic fault-injection
54
+ hook; normal consumers should omit it. `after-table-stage` may occur several
55
+ times for one operation, and recovery can invoke callbacks during engine open.