niceeval 0.16.3-canary.99 → 0.17.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (258) hide show
  1. package/dist/cli/bootstrap.cjs +7 -1
  2. package/dist/cli/bootstrap.cjs.map +1 -1
  3. package/dist/cli/project-configuration.cjs +8 -11
  4. package/dist/cli/project-configuration.cjs.map +1 -1
  5. package/dist/expect/index.cjs.map +1 -1
  6. package/dist/expect/index.d.cts +1 -0
  7. package/dist/expect/index.d.mts +1 -0
  8. package/dist/expect/index.d.ts +1 -0
  9. package/dist/experiment/host/cli/contribution.cjs +6 -11
  10. package/dist/experiment/host/cli/contribution.cjs.map +1 -1
  11. package/dist/experiment/host/cli/contribution.d.cts +0 -16
  12. package/dist/experiment/host/cli/contribution.d.mts +0 -16
  13. package/dist/experiment/host/cli/contribution.d.ts +0 -16
  14. package/dist/experiment/host/operations.cjs +3 -3
  15. package/dist/experiment/host/operations.cjs.map +1 -1
  16. package/dist/experiment/host/types.cjs.map +1 -1
  17. package/dist/experiment/host/types.d.cts +0 -4
  18. package/dist/experiment/host/types.d.mts +0 -4
  19. package/dist/experiment/host/types.d.ts +0 -4
  20. package/dist/fresh-import.cjs +2 -2
  21. package/dist/fresh-import.cjs.map +1 -1
  22. package/dist/fresh-import.d.cts +3 -3
  23. package/dist/fresh-import.d.mts +3 -3
  24. package/dist/fresh-import.d.ts +3 -3
  25. package/dist/index.cjs.map +1 -1
  26. package/dist/index.d.cts +1 -0
  27. package/dist/index.d.mts +1 -0
  28. package/dist/index.d.ts +1 -0
  29. package/dist/inspection/codec.cjs.map +1 -1
  30. package/dist/inspection/codec.d.cts +1 -1
  31. package/dist/inspection/codec.d.mts +1 -1
  32. package/dist/inspection/codec.d.ts +1 -1
  33. package/dist/inspection/facts.cjs +66 -9
  34. package/dist/inspection/facts.cjs.map +1 -1
  35. package/dist/inspection/facts.d.cts +4 -0
  36. package/dist/inspection/facts.d.mts +4 -0
  37. package/dist/inspection/facts.d.ts +4 -0
  38. package/dist/inspection/facts.js +4 -2
  39. package/dist/inspection/index.cjs +1 -3
  40. package/dist/inspection/index.cjs.map +1 -1
  41. package/dist/inspection/index.d.cts +1 -1
  42. package/dist/inspection/index.d.mts +1 -1
  43. package/dist/inspection/index.d.ts +1 -1
  44. package/dist/inspection/index.js +44 -48
  45. package/dist/inspection/limits.cjs +3 -1
  46. package/dist/inspection/limits.cjs.map +1 -1
  47. package/dist/inspection/limits.d.cts +2 -0
  48. package/dist/inspection/limits.d.mts +2 -0
  49. package/dist/inspection/limits.d.ts +2 -0
  50. package/dist/inspection/limits.js +6 -4
  51. package/dist/inspection/project-source.cjs +4 -1
  52. package/dist/inspection/project-source.cjs.map +1 -1
  53. package/dist/inspection/protocol.cjs +10 -18
  54. package/dist/inspection/protocol.cjs.map +1 -1
  55. package/dist/inspection/protocol.d.cts +111 -173
  56. package/dist/inspection/protocol.d.mts +111 -173
  57. package/dist/inspection/protocol.d.ts +111 -173
  58. package/dist/inspection/public.mjs +73 -109
  59. package/dist/inspection/results.cjs +12 -48
  60. package/dist/inspection/results.cjs.map +1 -1
  61. package/dist/inspection/results.d.cts +124 -122
  62. package/dist/inspection/results.d.mts +124 -122
  63. package/dist/inspection/results.d.ts +124 -122
  64. package/dist/inspection/results.js +16 -20
  65. package/dist/inspection/select.cjs +80 -117
  66. package/dist/inspection/select.cjs.map +1 -1
  67. package/dist/inspection/source.cjs +14 -15
  68. package/dist/inspection/source.cjs.map +1 -1
  69. package/dist/inspection/source.d.cts +6 -3
  70. package/dist/inspection/source.d.mts +6 -3
  71. package/dist/inspection/source.d.ts +6 -3
  72. package/dist/inspection/trace.cjs +1 -1
  73. package/dist/inspection/trace.cjs.map +1 -1
  74. package/dist/load-config.cjs +17 -11
  75. package/dist/load-config.cjs.map +1 -1
  76. package/dist/load-config.d.cts +3 -2
  77. package/dist/load-config.d.mts +3 -2
  78. package/dist/load-config.d.ts +3 -2
  79. package/dist/o11y/adapter-usage-projection.cjs +5 -1
  80. package/dist/o11y/adapter-usage-projection.cjs.map +1 -1
  81. package/dist/o11y/adapter-usage-projection.d.cts +109 -1
  82. package/dist/o11y/adapter-usage-projection.d.mts +109 -1
  83. package/dist/o11y/adapter-usage-projection.d.ts +109 -1
  84. package/dist/o11y/cache-read.cjs +113 -0
  85. package/dist/o11y/cache-read.cjs.map +1 -0
  86. package/dist/o11y/cache-read.d.cts +80 -0
  87. package/dist/o11y/cache-read.d.mts +80 -0
  88. package/dist/o11y/cache-read.d.ts +80 -0
  89. package/dist/o11y/cache-read.js +8 -0
  90. package/dist/o11y/cache-read.js.map +1 -0
  91. package/dist/o11y/eval-usage.cjs +4 -1
  92. package/dist/o11y/eval-usage.cjs.map +1 -1
  93. package/dist/o11y/eval-usage.d.cts +4 -1
  94. package/dist/o11y/eval-usage.d.mts +4 -1
  95. package/dist/o11y/eval-usage.d.ts +4 -1
  96. package/dist/record/host/sqlite-host.cjs +188 -53
  97. package/dist/record/host/sqlite-host.cjs.map +1 -1
  98. package/dist/record/host/sqlite-host.d.cts +37 -1
  99. package/dist/record/host/sqlite-host.d.mts +37 -1
  100. package/dist/record/host/sqlite-host.d.ts +37 -1
  101. package/dist/record/host/sqlite-host.js +16 -8
  102. package/dist/record/maintenance/runtime.cjs +3 -3
  103. package/dist/record/maintenance/runtime.cjs.map +1 -1
  104. package/dist/record/sqlite/admission-repository.cjs +18 -18
  105. package/dist/record/sqlite/admission-repository.cjs.map +1 -1
  106. package/dist/record/sqlite/case-repository.cjs +6 -6
  107. package/dist/record/sqlite/case-repository.cjs.map +1 -1
  108. package/dist/record/sqlite/coordination-repository.cjs +25 -25
  109. package/dist/record/sqlite/coordination-repository.cjs.map +1 -1
  110. package/dist/record/sqlite/current-schema.cjs +115 -111
  111. package/dist/record/sqlite/current-schema.cjs.map +1 -1
  112. package/dist/record/sqlite/current-schema.d.cts +3 -3
  113. package/dist/record/sqlite/current-schema.d.mts +3 -3
  114. package/dist/record/sqlite/current-schema.d.ts +3 -3
  115. package/dist/record/sqlite/database.cjs +56 -53
  116. package/dist/record/sqlite/database.cjs.map +1 -1
  117. package/dist/record/sqlite/index.cjs +3 -1
  118. package/dist/record/sqlite/index.cjs.map +1 -1
  119. package/dist/record/sqlite/index.d.cts +5 -2
  120. package/dist/record/sqlite/index.d.mts +5 -2
  121. package/dist/record/sqlite/index.d.ts +5 -2
  122. package/dist/record/sqlite/legacy-schema-018.cjs +443 -0
  123. package/dist/record/sqlite/legacy-schema-018.cjs.map +1 -0
  124. package/dist/record/sqlite/legacy-schema-018.d.cts +6 -0
  125. package/dist/record/sqlite/legacy-schema-018.d.mts +6 -0
  126. package/dist/record/sqlite/legacy-schema-018.d.ts +6 -0
  127. package/dist/record/sqlite/legacy-schema-018.js +6 -0
  128. package/dist/record/sqlite/legacy-schema-018.js.map +1 -0
  129. package/dist/record/sqlite/migration.cjs +105 -46
  130. package/dist/record/sqlite/migration.cjs.map +1 -1
  131. package/dist/record/sqlite/migration.d.cts +2 -1
  132. package/dist/record/sqlite/migration.d.mts +2 -1
  133. package/dist/record/sqlite/migration.d.ts +2 -1
  134. package/dist/record/sqlite/portable-capture.cjs +13 -13
  135. package/dist/record/sqlite/portable-capture.cjs.map +1 -1
  136. package/dist/record/sqlite/registry-repository.cjs +22 -22
  137. package/dist/record/sqlite/registry-repository.cjs.map +1 -1
  138. package/dist/record/sqlite/schema.cjs +10 -2
  139. package/dist/record/sqlite/schema.cjs.map +1 -1
  140. package/dist/record/sqlite/schema.d.cts +4 -1
  141. package/dist/record/sqlite/schema.d.mts +4 -1
  142. package/dist/record/sqlite/schema.d.ts +4 -1
  143. package/dist/record/sqlite/schema.js +20 -14
  144. package/dist/record/sqlite/storage-worker.cjs +1 -1
  145. package/dist/record/sqlite/storage-worker.cjs.map +1 -1
  146. package/dist/record/sqlite/storage.cjs +316 -232
  147. package/dist/record/sqlite/storage.cjs.map +1 -1
  148. package/dist/record/sqlite/storage.d.cts +10 -2
  149. package/dist/record/sqlite/storage.d.mts +10 -2
  150. package/dist/record/sqlite/storage.d.ts +10 -2
  151. package/dist/record/sqlite/storage.js +54 -50
  152. package/dist/record/sqlite/types.cjs +1 -1
  153. package/dist/record/sqlite/types.cjs.map +1 -1
  154. package/dist/record/sqlite/types.d.cts +13 -1
  155. package/dist/record/sqlite/types.d.mts +13 -1
  156. package/dist/record/sqlite/types.d.ts +13 -1
  157. package/dist/run/cli/contribution.cjs +17 -12
  158. package/dist/run/cli/contribution.cjs.map +1 -1
  159. package/dist/run/host/lifecycle-adapter.cjs +1 -1
  160. package/dist/run/host/lifecycle-adapter.cjs.map +1 -1
  161. package/dist/run/storage/owner-identity.cjs +78 -16
  162. package/dist/run/storage/owner-identity.cjs.map +1 -1
  163. package/dist/run/storage/owner-identity.d.cts +2 -1
  164. package/dist/run/storage/owner-identity.d.mts +2 -1
  165. package/dist/run/storage/owner-identity.d.ts +2 -1
  166. package/dist/run/storage/sqlite.cjs +55 -55
  167. package/dist/run/storage/sqlite.cjs.map +1 -1
  168. package/dist/runner/accept.cjs +12 -42
  169. package/dist/runner/accept.cjs.map +1 -1
  170. package/dist/runner/accept.d.cts +2 -3
  171. package/dist/runner/accept.d.mts +2 -3
  172. package/dist/runner/accept.d.ts +2 -3
  173. package/dist/runner/adapter-usage.cjs +2 -2
  174. package/dist/runner/adapter-usage.cjs.map +1 -1
  175. package/dist/runner/adoption.cjs +14 -26
  176. package/dist/runner/adoption.cjs.map +1 -1
  177. package/dist/runner/adoption.d.cts +5 -13
  178. package/dist/runner/adoption.d.mts +5 -13
  179. package/dist/runner/adoption.d.ts +5 -13
  180. package/dist/runner/adoption.js +2 -4
  181. package/dist/runner/record.cjs +24 -18
  182. package/dist/runner/record.cjs.map +1 -1
  183. package/dist/runner/rename-experiment.cjs +5 -7
  184. package/dist/runner/rename-experiment.cjs.map +1 -1
  185. package/dist/runner/reuse-plan.cjs +37 -18
  186. package/dist/runner/reuse-plan.cjs.map +1 -1
  187. package/dist/runner/reuse-plan.d.cts +4 -1
  188. package/dist/runner/reuse-plan.d.mts +4 -1
  189. package/dist/runner/reuse-plan.d.ts +4 -1
  190. package/dist/runner/setup-prefix-plan.cjs +17 -12
  191. package/dist/runner/setup-prefix-plan.cjs.map +1 -1
  192. package/dist/runner/setup-prefix-plan.d.cts +0 -2
  193. package/dist/runner/setup-prefix-plan.d.mts +0 -2
  194. package/dist/runner/setup-prefix-plan.d.ts +0 -2
  195. package/dist/runner/setup-prefix-plan.js +8 -12
  196. package/dist/sandbox/backend.cjs +10 -1
  197. package/dist/sandbox/backend.cjs.map +1 -1
  198. package/dist/sandbox/backend.d.cts +16 -8
  199. package/dist/sandbox/backend.d.mts +16 -8
  200. package/dist/sandbox/backend.d.ts +16 -8
  201. package/dist/sandbox/backend.js +28 -26
  202. package/dist/sandbox/docker.cjs +7 -1
  203. package/dist/sandbox/docker.cjs.map +1 -1
  204. package/dist/sandbox/e2b-cache-repository.cjs +13 -3
  205. package/dist/sandbox/e2b-cache-repository.cjs.map +1 -1
  206. package/dist/sandbox/e2b-cache-repository.d.cts +3 -0
  207. package/dist/sandbox/e2b-cache-repository.d.mts +3 -0
  208. package/dist/sandbox/e2b-cache-repository.d.ts +3 -0
  209. package/dist/sandbox/e2b-cache-repository.js +16 -12
  210. package/dist/sandbox/e2b.cjs +2 -2
  211. package/dist/sandbox/e2b.cjs.map +1 -1
  212. package/dist/sandbox/incus/materialize.cjs +1 -1
  213. package/dist/sandbox/incus/materialize.cjs.map +1 -1
  214. package/dist/show/contribution.cjs +3 -3
  215. package/dist/show/contribution.cjs.map +1 -1
  216. package/dist/show/model.cjs +14 -13
  217. package/dist/show/model.cjs.map +1 -1
  218. package/dist/show/model.d.cts +7 -7
  219. package/dist/show/model.d.mts +7 -7
  220. package/dist/show/model.d.ts +7 -7
  221. package/dist/show/render.cjs +14 -0
  222. package/dist/show/render.cjs.map +1 -1
  223. package/dist/user-database/storage-worker.cjs +13 -3
  224. package/dist/user-database/storage-worker.cjs.map +1 -1
  225. package/dist/view/app-dist/.vite/manifest.json +2 -2
  226. package/dist/view/app-dist/assets/{index-CmVoXbwG.js → index-B3ijZRph.js} +17 -17
  227. package/dist/view/app-dist/assets/{quality-cost-scatter-BuLISaH4.js → quality-cost-scatter-B--DfJ9s.js} +1 -1
  228. package/dist/view/app-dist/index.html +1 -1
  229. package/dist/view/application-runtime.cjs +8 -0
  230. package/dist/view/application-runtime.cjs.map +1 -0
  231. package/dist/view/application-runtime.d.cts +9 -0
  232. package/dist/view/application-runtime.d.mts +9 -0
  233. package/dist/view/application-runtime.d.ts +9 -0
  234. package/dist/view/application-runtime.js +6 -0
  235. package/dist/view/application-runtime.js.map +1 -0
  236. package/dist/view/cli/contribution.cjs +5 -2
  237. package/dist/view/cli/contribution.cjs.map +1 -1
  238. package/dist/view/cli/contribution.d.cts +2 -1
  239. package/dist/view/cli/contribution.d.mts +2 -1
  240. package/dist/view/cli/contribution.d.ts +2 -1
  241. package/dist/view/function-runtime.mjs +1019 -456
  242. package/dist/view/http-protocol.d.cts +1 -9
  243. package/dist/view/http-protocol.d.mts +1 -9
  244. package/dist/view/http-protocol.d.ts +1 -9
  245. package/dist/view/inspection-host.cjs +39 -30
  246. package/dist/view/inspection-host.cjs.map +1 -1
  247. package/dist/view/inspection-host.d.cts +7545 -2
  248. package/dist/view/inspection-host.d.mts +7545 -2
  249. package/dist/view/inspection-host.d.ts +7545 -2
  250. package/dist/view/server.cjs +8 -5
  251. package/dist/view/server.cjs.map +1 -1
  252. package/dist/view/server.d.cts +4 -2
  253. package/dist/view/server.d.mts +4 -2
  254. package/dist/view/server.d.ts +4 -2
  255. package/docs-site/zh/reference/cli.mdx +1 -2
  256. package/docs-site/zh/tutorials/control-run-cost.mdx +22 -0
  257. package/docs-site/zh/tutorials/niceeval-taste-application.mdx +21 -0
  258. package/package.json +1 -1
@@ -1,6 +1,10 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
3
  exports.recordHost = void 0;
4
+ exports.detachPlanningReference = detachPlanningReference;
5
+ exports.stagePlanningReference = stagePlanningReference;
6
+ exports.selectPlanningLocator = selectPlanningLocator;
7
+ exports.selectPlanningSources = selectPlanningSources;
4
8
  exports.writerGenerationForRunSession = writerGenerationForRunSession;
5
9
  exports.discardAttemptWriteSession = discardAttemptWriteSession;
6
10
  exports.makeRecordHost = makeRecordHost;
@@ -32,6 +36,7 @@ const errors_ts_3 = require("../writer/errors.cjs");
32
36
  const limits_ts_1 = require("../writer/limits.cjs");
33
37
  const types_ts_1 = require("./types.cjs");
34
38
  const index_ts_5 = require("../sqlite/index.cjs");
39
+ const errors_ts_4 = require("../../run/storage/errors.cjs");
35
40
  const WRITE_DEADLINE_MS = 30000;
36
41
  const MAILBOX_COMMANDS = 64;
37
42
  const COLLECTION_READ_MAX_ROWS = 10000;
@@ -89,48 +94,162 @@ function exactMarker(value, key) {
89
94
  return descriptor?.enumerable && "value" in descriptor ? descriptor.value : undefined;
90
95
  }
91
96
  function hasOwnMarker(value, key) { return typeof value === "object" && value !== null && !Array.isArray(value) && Object.prototype.hasOwnProperty.call(value, key); }
92
- /** Capture planning facts together, then release SQLite before any dispatch. */
93
- function captureReaderSnapshot(root) {
97
+ function pinnedRead(read) {
94
98
  return effect_1.Effect.try({
95
- try: () => {
96
- const session = (0, index_ts_5.openOperationalRecordReadSession)(root);
97
- try {
98
- const summaries = [];
99
- const resources = [];
100
- const cores = new Map();
101
- let afterRunId = "";
102
- for (;;) {
103
- const page = session.readSealedRunSummaryPage(afterRunId, 100);
104
- summaries.push(...page.summaries);
105
- if (page.nextAfterRunId === null)
106
- break;
107
- afterRunId = page.nextAfterRunId;
108
- }
109
- for (const summary of summaries) {
110
- const core = session.readSealedRunCore(summary.runId);
111
- if (core !== undefined)
112
- cores.set(summary.runId, core);
113
- }
114
- afterRunId = "";
115
- for (;;) {
116
- const page = session.listRunResources({ afterRunId, pageSize: 100 });
117
- resources.push(...page.runs);
118
- if (page.nextAfterRunId === null)
119
- break;
120
- afterRunId = page.nextAfterRunId;
121
- }
122
- return Object.freeze({ summaries: Object.freeze(summaries), resources: Object.freeze(resources), cutoff: session.publicationCutoff(), cores });
123
- }
124
- finally {
125
- session.close();
126
- }
127
- },
128
- catch: (cause) => cause instanceof index_ts_4.SqliteRecordError ? cause : new index_ts_4.SqliteRecordError("record-sqlite-error", "record-reader-snapshot", "Could not capture reader facts", { cause }),
99
+ try: read,
100
+ catch: (cause) => cause instanceof index_ts_4.SqliteRecordError ? cause : new index_ts_4.SqliteRecordError(cause instanceof errors_ts_4.RunStorageError && cause.code === "run-storage-invalid" ? "record-database-invalid" : "record-sqlite-error", "record-reader", "Could not read selected facts", { cause }),
129
101
  });
130
102
  }
103
+ const readers = new WeakMap();
131
104
  const runSessions = new WeakMap();
132
105
  const attemptSessions = new WeakMap();
133
106
  const selectedAttemptCapabilities = new WeakMap();
107
+ const exactReferenceBrand = Symbol("record/planning-reference");
108
+ const exactReferences = new WeakSet();
109
+ function planningCorruption(error) {
110
+ return error instanceof errors_ts_2.RecordIntegrityFailure || error instanceof index_ts_4.SqliteRecordError &&
111
+ ["record-database-invalid", "record-content-invalid", "record-seal-incomplete"].includes(error.code);
112
+ }
113
+ function detachPlanningReference(reader, attempt) {
114
+ const runtime = readers.get(reader), capability = selectedAttemptCapabilities.get(attempt);
115
+ const publication = attempt.publicationIdentity;
116
+ if (runtime === undefined || runtime.lifecycle.closed || capability?.lifecycle !== runtime.lifecycle ||
117
+ publication === undefined || publication.originRunId !== attempt.originRunId || publication.attemptId !== attempt.attemptId)
118
+ return undefined;
119
+ const reference = Object.freeze({ record: runtime.root, originRunId: attempt.originRunId,
120
+ attemptId: attempt.attemptId, publicationIdentity: Object.freeze({ ...publication }), [exactReferenceBrand]: true });
121
+ exactReferences.add(reference);
122
+ return reference;
123
+ }
124
+ /** Stages Core membership; the following binding transaction rechecks the publication CAS. */
125
+ function stagePlanningReference(session, input) {
126
+ const run = runSessions.get(session);
127
+ if (run === undefined || !exactReferences.has(input.reference) || !sameRoot(run.root, input.reference.record)) {
128
+ return effect_1.Effect.fail(new record_errors_ts_1.RecordReferenceInvalid({ code: "record-reference-invalid" }));
129
+ }
130
+ return run.lock.withPermits(1)(effect_1.Effect.gen(function* () {
131
+ yield* assertRunOpen(run);
132
+ if (!run.expectedBySlot.has(input.slotId) || run.reservations.has(input.slotId))
133
+ return yield* effect_1.Effect.fail(coreInvalid());
134
+ run.members.set(input.slotId, Object.freeze({ slotId: input.slotId, action: input.action,
135
+ attempt: Object.freeze({ originRunId: input.reference.originRunId, attemptId: input.reference.attemptId }) }));
136
+ run.reservations.add(input.slotId);
137
+ }));
138
+ }
139
+ function selectPlanningLocator(reader, locator) {
140
+ return effect_1.Effect.gen(function* () {
141
+ const runtime = readers.get(reader);
142
+ if (runtime === undefined || runtime.lifecycle.closed)
143
+ return yield* effect_1.Effect.fail(new errors_ts_2.RecordReaderClosed({ code: "record-reader-closed" }));
144
+ const candidates = yield* pinnedRead(() => runtime.session.findAttemptLocatorCandidates(locator, 256, false));
145
+ const runIds = yield* effect_1.Schema.decodeUnknownEffect(effect_1.Schema.Array(identifiers_ts_1.RunIdSchema))([...new Set(candidates.candidates.map((candidate) => candidate.runId))]).pipe(effect_1.Effect.mapError(() => new errors_ts_2.RecordHandleInvalid({ code: "record-handle-invalid" })));
146
+ return yield* reader.selectRuns({ runIds, includePublishedActive: true });
147
+ });
148
+ }
149
+ /** Select barriers before loading Core; fetch only those barriers and necessary origins. */
150
+ function selectPlanningSources(reader, positions) {
151
+ return effect_1.Effect.gen(function* () {
152
+ const runtime = readers.get(reader);
153
+ if (runtime === undefined || runtime.lifecycle.closed)
154
+ return yield* effect_1.Effect.fail(new errors_ts_2.RecordReaderClosed({ code: "record-reader-closed" }));
155
+ const candidates = yield* pinnedRead(() => positions.flatMap((position) => {
156
+ const candidate = runtime.session.findSourceBarrierCandidate(position);
157
+ return candidate === undefined ? [] : [{ ...candidate, position }];
158
+ }));
159
+ const sourceIds = [...new Set(candidates.map((candidate) => candidate.runId))];
160
+ const experimentByRun = new Map(candidates.map((candidate) => [candidate.runId, candidate.position.experimentId]));
161
+ const issuesByExperiment = new Map();
162
+ const sourceProblem = (id, error) => {
163
+ const experiment = experimentByRun.get(id);
164
+ if (experiment !== undefined)
165
+ issuesByExperiment.set(experiment, invalidIssues(["run", id, error.code,
166
+ ...(error instanceof errors_ts_2.RecordIntegrityFailure ? [error.reason] : [])]));
167
+ };
168
+ const resources = [];
169
+ for (const id of sourceIds) {
170
+ const result = yield* effect_1.Effect.result(pinnedRead(() => runtime.session.readRunResource(id)));
171
+ if (effect_1.Result.isFailure(result)) {
172
+ if (!planningCorruption(result.failure))
173
+ return yield* effect_1.Effect.fail(result.failure);
174
+ sourceProblem(id, result.failure);
175
+ }
176
+ else if (result.success !== undefined)
177
+ resources.push(result.success);
178
+ }
179
+ const members = new Map();
180
+ const ids = new Set(sourceIds);
181
+ for (const resource of resources) {
182
+ const runId = yield* effect_1.Schema.decodeUnknownEffect(identifiers_ts_1.RunIdSchema)(resource.runId).pipe(effect_1.Effect.mapError(() => new errors_ts_2.RecordHandleInvalid({ code: "record-handle-invalid" })));
183
+ const bindings = [];
184
+ for (const slot of resource.slots) {
185
+ if (!candidates.some((candidate) => candidate.runId === resource.runId &&
186
+ candidate.position.evalId === slot.evalId && candidate.position.attemptOrdinal === slot.attemptOrdinal))
187
+ continue;
188
+ const publication = slot.publication;
189
+ if (publication.state !== "published")
190
+ continue;
191
+ const decoded = (0, index_ts_2.decodeMemberDocument)({ slotId: slot.slotId, action: publication.action,
192
+ attempt: { originRunId: publication.originRunId, attemptId: publication.attemptId } });
193
+ if (effect_1.Result.isFailure(decoded) || decoded.success.attempt === null)
194
+ return yield* effect_1.Effect.fail(new errors_ts_2.RecordIntegrityFailure({ code: "record-integrity-failure", runId, reason: "core-invalid" }));
195
+ ids.add(publication.originRunId);
196
+ // A carried rename still needs its earlier accepted membership as
197
+ // proof. The latest barrier and origin alone cannot establish it.
198
+ if (publication.action === "carried") {
199
+ const witnesses = yield* pinnedRead(() => runtime.session.findAcceptedAttemptRunIds({
200
+ experimentId: resource.experimentId,
201
+ originRunId: publication.originRunId,
202
+ attemptId: publication.attemptId,
203
+ bindingRevision: publication.bindingRevision,
204
+ }));
205
+ for (const witness of witnesses)
206
+ ids.add(witness);
207
+ }
208
+ bindings.push(Object.freeze({ document: decoded.success, bindingRevision: publication.bindingRevision,
209
+ attempt: attemptRef(runtime, decoded.success.attempt.originRunId, decoded.success.attempt.attemptId, publication.publicationIdentity) }));
210
+ }
211
+ members.set(runId, Object.freeze(bindings));
212
+ }
213
+ // A legacy barrier's members can reference origins outside this Experiment.
214
+ const selections = [];
215
+ for (const id of ids) {
216
+ const runId = yield* effect_1.Schema.decodeUnknownEffect(identifiers_ts_1.RunIdSchema)(id).pipe(effect_1.Effect.mapError(() => new errors_ts_2.RecordHandleInvalid({ code: "record-handle-invalid" })));
217
+ const result = yield* effect_1.Effect.result(reader.selectRuns({ runIds: [runId], includePublishedActive: true }));
218
+ if (effect_1.Result.isFailure(result)) {
219
+ if (!planningCorruption(result.failure))
220
+ return yield* effect_1.Effect.fail(result.failure);
221
+ sourceProblem(id, result.failure);
222
+ continue;
223
+ }
224
+ selections.push(result.success);
225
+ if (sourceIds.includes(id))
226
+ for (const ref of result.success.runRefs) {
227
+ const run = yield* reader.readRun(ref);
228
+ if (run.state !== "available")
229
+ continue;
230
+ const resource = resources.find((resource) => resource.runId === id);
231
+ if (run.value.document.experimentId !== experimentByRun.get(id) || resource !== undefined &&
232
+ (resource.slots.length !== run.value.document.expectedSlots.length || resource.slots.some((slot) => !run.value.document.expectedSlots.some((expected) => expected.slotId === slot.slotId && expected.evalId === slot.evalId &&
233
+ expected.attemptOrdinal === slot.attemptOrdinal && expected.executionIdentityDigest === slot.executionIdentityDigest)))) {
234
+ sourceProblem(id, new errors_ts_2.RecordIntegrityFailure({ code: "record-integrity-failure", runId, reason: "core-invalid" }));
235
+ }
236
+ for (const member of run.value.members) {
237
+ const slot = run.value.document.expectedSlots.find((slot) => slot.slotId === member.document.slotId);
238
+ if (slot !== undefined && member.attempt !== null && candidates.some((candidate) => candidate.runId === id &&
239
+ candidate.position.evalId === slot.evalId && candidate.position.attemptOrdinal === slot.attemptOrdinal))
240
+ ids.add(member.attempt.originRunId);
241
+ }
242
+ }
243
+ }
244
+ // Resource-only and missing origins are assessed per slot, never discarded
245
+ // in favour of an older source barrier.
246
+ const selection = Object.freeze({ runRefs: Object.freeze(selections.flatMap((selection) => selection.runRefs)),
247
+ runFacts: Object.freeze(selections.flatMap((selection) => selection.runFacts)),
248
+ expectedSlots: Object.freeze(selections.flatMap((selection) => selection.expectedSlots)), warnings: Object.freeze([]),
249
+ problems: Object.freeze(selections.flatMap((selection) => selection.problems).filter((problem) => sourceIds.includes(problem.runId) && !members.has(problem.runId))) });
250
+ return Object.freeze({ selection, resources: Object.freeze(resources), members, issuesByExperiment, experimentByRun });
251
+ });
252
+ }
134
253
  function writerGenerationForRunSession(session) {
135
254
  return runSessions.get(session)?.writerGeneration;
136
255
  }
@@ -608,7 +727,7 @@ function openNewRuntime(request, catalog, referenceOnly) {
608
727
  const record = decodedRecord !== undefined && effect_1.Result.isSuccess(decodedRecord) ? decodedRecord.success : deterministicRecord(request.root);
609
728
  if (record === undefined)
610
729
  return yield* effect_1.Effect.fail(coreInvalid());
611
- yield* withWriteAdmission(coordination, request.root, (deadlineEpochMs) => client.beginRun({ runId, writerGeneration, startedAt: new Date(request.startedAt).toISOString(), deadlineEpochMs }));
730
+ yield* withWriteAdmission(coordination, request.root, (deadlineEpochMs) => client.beginRun({ runId, experimentId: request.experimentId, writerGeneration, startedAt: new Date(request.startedAt).toISOString(), deadlineEpochMs }));
612
731
  const lock = yield* effect_1.Semaphore.make(1), queue = yield* effect_1.Queue.bounded(MAILBOX_COMMANDS);
613
732
  const run = { root: request.root, client, coordination, entropy, catalog, record, writerGeneration, runId, experimentId: request.experimentId, context: context.success, startedAt: request.startedAt, expectedSlots: Object.freeze([...request.expectedSlots]), expectedBySlot: new Map(request.expectedSlots.map((slot) => [slot.slotId, slot])), lock, queue, attempts: new Map(), members: new Map(), reservations: new Set(), families: new Set(), attachments: new Map(), state: "open" };
614
733
  yield* effect_1.Effect.forkScoped(collectionWorker(run));
@@ -647,7 +766,15 @@ function decodeCore(core) {
647
766
  function readCore(runtime, runId) {
648
767
  if (runtime.lifecycle.closed)
649
768
  return effect_1.Effect.fail(new errors_ts_2.RecordReaderClosed({ code: "record-reader-closed" }));
650
- return effect_1.Effect.succeed(runtime.coreCache.get(runId));
769
+ return pinnedRead(() => {
770
+ const cached = runtime.coreCache.get(runId);
771
+ if (cached !== undefined)
772
+ return cached;
773
+ const core = runtime.session.readSealedRunCore(runId, true);
774
+ if (core !== undefined)
775
+ runtime.coreCache.set(runId, core);
776
+ return core;
777
+ });
651
778
  }
652
779
  function runRef(runtime, runId) {
653
780
  const old = runtime.runRefs.get(runId);
@@ -699,6 +826,11 @@ function readAttempt(runtime, ref) {
699
826
  const document = decoded.attempts.find(({ attemptId }) => attemptId === location.attemptId);
700
827
  if (document === undefined)
701
828
  return effect_1.Effect.fail(new errors_ts_2.RecordIntegrityFailure({ code: "record-integrity-failure", runId: location.runId, reason: "publication-closure-invalid" }));
829
+ const actual = core.attempts.find((attempt) => attempt.attemptId === document.attemptId)?.publicationIdentity;
830
+ if (ref.publicationIdentity !== undefined && (actual === undefined ||
831
+ actual.originRunId !== ref.publicationIdentity.originRunId || actual.attemptId !== ref.publicationIdentity.attemptId ||
832
+ actual.revision !== ref.publicationIdentity.revision))
833
+ return effect_1.Effect.fail(new errors_ts_2.RecordIntegrityFailure({ code: "record-integrity-failure", runId: location.runId, reason: "publication-closure-invalid" }));
702
834
  return effect_1.Effect.succeed(Object.freeze({ state: "available", value: Object.freeze({ ref, owner: ownerRef(runtime, { kind: "attempt", runId: location.runId, attemptId: location.attemptId }), document, origin: Object.freeze({ owner: ownerRef(runtime, { kind: "run", runId: location.runId }), runId: location.runId, experimentId: decoded.run.experimentId, startedAt: decoded.run.startedAt, context: decoded.run.context }) }) }));
703
835
  });
704
836
  }
@@ -716,7 +848,7 @@ function contentStream(runtime, handle) {
716
848
  return effect_1.Effect.succeed(effect_1.Stream.paginate({ after: -1, ordinal: 0, byteLength: 0 }, (state) => {
717
849
  if (runtime.lifecycle.closed)
718
850
  return effect_1.Effect.fail(new errors_ts_2.RecordReaderClosed({ code: "record-reader-closed" }));
719
- return sqliteEffect(() => runtime.client.readContentChunkPage(metadata.contentId, state.after, CONTENT_READ_PAGE_ROWS)).pipe(effect_1.Effect.flatMap((page) => {
851
+ return pinnedRead(() => runtime.session.readContentChunkPage(metadata.contentId, state.after, CONTENT_READ_PAGE_ROWS)).pipe(effect_1.Effect.flatMap((page) => {
720
852
  if (page.chunks.length === 0) {
721
853
  return state.ordinal === metadata.chunkCount && state.byteLength === metadata.byteLength && hash.digest("hex") === metadata.digest
722
854
  ? effect_1.Effect.succeed([[], effect_1.Option.none()])
@@ -823,12 +955,12 @@ function readFamily(runtime, ownerValue, definition) {
823
955
  const persistence = runtime.catalog.persistence(resolved);
824
956
  if (persistence === undefined)
825
957
  return effect_1.Effect.fail(new errors_ts_2.FamilyDefinitionRequired({ code: "family-definition-required", owner: owner.kind, family: resolved.family, revision: 1 }));
826
- return effect_1.Effect.map(readCore(runtime, owner.runId), (core) => {
958
+ return effect_1.Effect.flatMap(readCore(runtime, owner.runId), (core) => pinnedRead(() => {
827
959
  if (core === undefined)
828
960
  return Object.freeze({ state: "not-recorded" });
829
961
  const attachment = findAttachment(core, owner, resolved.family);
830
962
  return attachment === undefined ? Object.freeze({ state: "not-recorded" }) : hydrateAttachment(runtime, attachment, persistence);
831
- });
963
+ }));
832
964
  }
833
965
  function collectionStream(runtime, attachment, authoring, expectedDigest) {
834
966
  if (runtime.lifecycle.closed)
@@ -840,7 +972,7 @@ function collectionStream(runtime, attachment, authoring, expectedDigest) {
840
972
  return effect_1.Effect.succeed(effect_1.Stream.paginate({ after: -1, ordinal: 0, byteLength: 0 }, (state) => {
841
973
  if (runtime.lifecycle.closed)
842
974
  return effect_1.Effect.fail(new errors_ts_2.RecordReaderClosed({ code: "record-reader-closed" }));
843
- return sqliteEffect(() => runtime.client.readCollectionItemPage(attachment.attachmentId, state.after, index_ts_4.RECORD_SQLITE_MAX_PAGE_ROWS)).pipe(effect_1.Effect.flatMap((page) => {
975
+ return pinnedRead(() => runtime.session.readCollectionItemPage(attachment.attachmentId, state.after, index_ts_4.RECORD_SQLITE_MAX_PAGE_ROWS)).pipe(effect_1.Effect.flatMap((page) => {
844
976
  if (page.items.length === 0) {
845
977
  return state.ordinal === attachment.collectionItemCount && state.byteLength === attachment.collectionItemByteLength && hash.digest("hex") === expectedDigest
846
978
  ? effect_1.Effect.succeed([[], effect_1.Option.none()])
@@ -888,7 +1020,7 @@ function openCollection(runtime, ownerValue, definition) {
888
1020
  const owner = runtime.owners.get(ownerValue), authoring = (0, authoring_ts_1.attemptRecordCollectionRuntime)(definition);
889
1021
  if (owner === undefined || owner.kind !== "attempt" || authoring === undefined)
890
1022
  return effect_1.Effect.fail(new errors_ts_2.RecordHandleInvalid({ code: "record-handle-invalid" }));
891
- return effect_1.Effect.map(readCore(runtime, owner.runId), (core) => {
1023
+ return effect_1.Effect.flatMap(readCore(runtime, owner.runId), (core) => pinnedRead(() => {
892
1024
  if (core === undefined)
893
1025
  return Object.freeze({ state: "not-recorded" });
894
1026
  const attachment = findAttachment(core, owner, authoring.attachment.family);
@@ -904,7 +1036,7 @@ function openCollection(runtime, ownerValue, definition) {
904
1036
  if (payload?.collection === undefined || collection === undefined || collection.count !== attachment.collectionItemCount || collection.byteLength !== attachment.collectionItemByteLength || typeof collection.digest !== "string")
905
1037
  return Object.freeze({ state: "invalid", issues: invalidIssues(["collection"]) });
906
1038
  return Object.freeze({ state: "available", collection: payload.collection, logicalIdentity: attachment.logicalIdentity, logicalSealIdentity: core.logicalSealIdentity, count: attachment.collectionItemCount, digest: collection.digest, canonicalBytes: attachment.collectionItemByteLength, items: collectionStream(runtime, attachment, authoring, collection.digest) });
907
- });
1039
+ }));
908
1040
  }
909
1041
  function readCollectionWhole(runtime, owner, definition) {
910
1042
  return effect_1.Effect.flatMap(openCollection(runtime, owner, definition), (opened) => {
@@ -922,9 +1054,7 @@ function makeReadSession(runtime) {
922
1054
  const pageSize = input.pageSize ?? 100;
923
1055
  if (!Number.isSafeInteger(pageSize) || pageSize < 1 || pageSize > 256)
924
1056
  return effect_1.Effect.fail(new errors_ts_2.RecordHandleInvalid({ code: "record-handle-invalid" }));
925
- const candidates = runtime.snapshot.resources.filter((run) => run.runId > (input.afterRunId ?? "") && (input.invocationId === undefined || run.invocationId === input.invocationId));
926
- const runs = Object.freeze(candidates.slice(0, pageSize));
927
- return effect_1.Effect.succeed(Object.freeze({ cutoff: runtime.snapshot.cutoff, runs, nextAfterRunId: candidates.length > pageSize ? runs.at(-1).runId : null }));
1057
+ return pinnedRead(() => runtime.session.listRunResources(input));
928
1058
  });
929
1059
  const selectRuns = (request) => effect_1.Effect.gen(function* () {
930
1060
  if (runtime.lifecycle.closed)
@@ -932,8 +1062,12 @@ function makeReadSession(runtime) {
932
1062
  const requested = request?.runIds === undefined ? undefined : new Set(request.runIds);
933
1063
  const cores = [];
934
1064
  let after = "";
1065
+ const exact = requested === undefined ? undefined : yield* pinnedRead(() => [...requested].flatMap((id) => {
1066
+ const summary = runtime.session.readSealedRunSummary(id);
1067
+ return summary === undefined ? [] : [summary];
1068
+ }));
935
1069
  while (true) {
936
- const page = runtime.snapshot.summaries.filter((summary) => summary.runId > after).slice(0, 100);
1070
+ const page = exact ?? (yield* pinnedRead(() => runtime.session.readSealedRunSummaryPage(after, 100))).summaries;
937
1071
  if (page.length === 0)
938
1072
  break;
939
1073
  for (const summary of page) {
@@ -952,7 +1086,7 @@ function makeReadSession(runtime) {
952
1086
  return yield* effect_1.Effect.fail(new errors_ts_2.RecordIntegrityFailure({ code: "record-integrity-failure", runId, reason: "core-invalid" }));
953
1087
  cores.push({ core, decoded });
954
1088
  }
955
- if (page.length < 100)
1089
+ if (exact !== undefined || page.length < 100)
956
1090
  break;
957
1091
  }
958
1092
  const problems = [];
@@ -1023,10 +1157,11 @@ function openRead(root, catalog) {
1023
1157
  const projectState = yield* index_ts_4.ProjectStateDatabase;
1024
1158
  const client = (yield* projectState.bind(rootPath)).record;
1025
1159
  const lifecycle = { closed: false };
1026
- const snapshot = yield* captureReaderSnapshot(rootPath);
1027
- const runtime = { root, client, catalog, lifecycle, snapshot, runs: new WeakMap(), attempts: new WeakMap(), owners: new WeakMap(), selections: new WeakSet(), coreCache: new Map(snapshot.cores), runRefs: new Map(), attemptRefs: new Map(), content: new WeakMap() };
1028
- yield* effect_1.Effect.addFinalizer(() => effect_1.Effect.sync(() => { lifecycle.closed = true; }));
1029
- return makeReadSession(runtime);
1160
+ const session = yield* effect_1.Effect.acquireRelease(pinnedRead(() => (0, index_ts_5.openOperationalRecordReadSession)(rootPath)), (session) => effect_1.Effect.sync(() => { lifecycle.closed = true; session.close(); }));
1161
+ const runtime = { root, client, catalog, lifecycle, session, runs: new WeakMap(), attempts: new WeakMap(), owners: new WeakMap(), selections: new WeakSet(), coreCache: new Map(), runRefs: new Map(), attemptRefs: new Map(), content: new WeakMap() };
1162
+ const reader = makeReadSession(runtime);
1163
+ readers.set(reader, runtime);
1164
+ return reader;
1030
1165
  });
1031
1166
  }
1032
1167
  function closeMaintenanceFailure(error) { return Object.freeze({ _tag: "RecordMaintenanceOperationFailed", code: error.code ?? "record-maintenance-failed" }); }