niceeval 0.16.3-canary.99 → 0.17.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/cli/bootstrap.cjs +7 -1
- package/dist/cli/bootstrap.cjs.map +1 -1
- package/dist/cli/project-configuration.cjs +8 -11
- package/dist/cli/project-configuration.cjs.map +1 -1
- package/dist/expect/index.cjs.map +1 -1
- package/dist/expect/index.d.cts +2 -1
- package/dist/expect/index.d.mts +2 -1
- package/dist/expect/index.d.ts +2 -1
- package/dist/experiment/host/cli/contribution.cjs +6 -11
- package/dist/experiment/host/cli/contribution.cjs.map +1 -1
- package/dist/experiment/host/cli/contribution.d.cts +0 -16
- package/dist/experiment/host/cli/contribution.d.mts +0 -16
- package/dist/experiment/host/cli/contribution.d.ts +0 -16
- package/dist/experiment/host/operations.cjs +3 -3
- package/dist/experiment/host/operations.cjs.map +1 -1
- package/dist/experiment/host/types.cjs.map +1 -1
- package/dist/experiment/host/types.d.cts +0 -4
- package/dist/experiment/host/types.d.mts +0 -4
- package/dist/experiment/host/types.d.ts +0 -4
- package/dist/fresh-import.cjs +2 -2
- package/dist/fresh-import.cjs.map +1 -1
- package/dist/fresh-import.d.cts +3 -3
- package/dist/fresh-import.d.mts +3 -3
- package/dist/fresh-import.d.ts +3 -3
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +2 -1
- package/dist/index.d.mts +2 -1
- package/dist/index.d.ts +2 -1
- package/dist/inspection/codec.cjs.map +1 -1
- package/dist/inspection/codec.d.cts +1 -1
- package/dist/inspection/codec.d.mts +1 -1
- package/dist/inspection/codec.d.ts +1 -1
- package/dist/inspection/facts.cjs +66 -9
- package/dist/inspection/facts.cjs.map +1 -1
- package/dist/inspection/facts.d.cts +4 -0
- package/dist/inspection/facts.d.mts +4 -0
- package/dist/inspection/facts.d.ts +4 -0
- package/dist/inspection/facts.js +4 -2
- package/dist/inspection/index.cjs +1 -3
- package/dist/inspection/index.cjs.map +1 -1
- package/dist/inspection/index.d.cts +1 -1
- package/dist/inspection/index.d.mts +1 -1
- package/dist/inspection/index.d.ts +1 -1
- package/dist/inspection/index.js +44 -48
- package/dist/inspection/limits.cjs +3 -1
- package/dist/inspection/limits.cjs.map +1 -1
- package/dist/inspection/limits.d.cts +2 -0
- package/dist/inspection/limits.d.mts +2 -0
- package/dist/inspection/limits.d.ts +2 -0
- package/dist/inspection/limits.js +6 -4
- package/dist/inspection/project-source.cjs +4 -1
- package/dist/inspection/project-source.cjs.map +1 -1
- package/dist/inspection/protocol.cjs +10 -18
- package/dist/inspection/protocol.cjs.map +1 -1
- package/dist/inspection/protocol.d.cts +111 -173
- package/dist/inspection/protocol.d.mts +111 -173
- package/dist/inspection/protocol.d.ts +111 -173
- package/dist/inspection/public.mjs +73 -109
- package/dist/inspection/results.cjs +12 -48
- package/dist/inspection/results.cjs.map +1 -1
- package/dist/inspection/results.d.cts +124 -122
- package/dist/inspection/results.d.mts +124 -122
- package/dist/inspection/results.d.ts +124 -122
- package/dist/inspection/results.js +16 -20
- package/dist/inspection/select.cjs +80 -117
- package/dist/inspection/select.cjs.map +1 -1
- package/dist/inspection/source.cjs +14 -15
- package/dist/inspection/source.cjs.map +1 -1
- package/dist/inspection/source.d.cts +6 -3
- package/dist/inspection/source.d.mts +6 -3
- package/dist/inspection/source.d.ts +6 -3
- package/dist/inspection/trace.cjs +1 -1
- package/dist/inspection/trace.cjs.map +1 -1
- package/dist/load-config.cjs +17 -11
- package/dist/load-config.cjs.map +1 -1
- package/dist/load-config.d.cts +3 -2
- package/dist/load-config.d.mts +3 -2
- package/dist/load-config.d.ts +3 -2
- package/dist/o11y/adapter-usage-projection.cjs +5 -1
- package/dist/o11y/adapter-usage-projection.cjs.map +1 -1
- package/dist/o11y/adapter-usage-projection.d.cts +109 -1
- package/dist/o11y/adapter-usage-projection.d.mts +109 -1
- package/dist/o11y/adapter-usage-projection.d.ts +109 -1
- package/dist/o11y/cache-read.cjs +113 -0
- package/dist/o11y/cache-read.cjs.map +1 -0
- package/dist/o11y/cache-read.d.cts +80 -0
- package/dist/o11y/cache-read.d.mts +80 -0
- package/dist/o11y/cache-read.d.ts +80 -0
- package/dist/o11y/cache-read.js +8 -0
- package/dist/o11y/cache-read.js.map +1 -0
- package/dist/o11y/eval-usage.cjs +22 -1
- package/dist/o11y/eval-usage.cjs.map +1 -1
- package/dist/o11y/eval-usage.d.cts +9 -1
- package/dist/o11y/eval-usage.d.mts +9 -1
- package/dist/o11y/eval-usage.d.ts +9 -1
- package/dist/record/host/sqlite-host.cjs +188 -53
- package/dist/record/host/sqlite-host.cjs.map +1 -1
- package/dist/record/host/sqlite-host.d.cts +37 -1
- package/dist/record/host/sqlite-host.d.mts +37 -1
- package/dist/record/host/sqlite-host.d.ts +37 -1
- package/dist/record/host/sqlite-host.js +16 -8
- package/dist/record/maintenance/runtime.cjs +3 -3
- package/dist/record/maintenance/runtime.cjs.map +1 -1
- package/dist/record/sqlite/admission-repository.cjs +18 -18
- package/dist/record/sqlite/admission-repository.cjs.map +1 -1
- package/dist/record/sqlite/case-repository.cjs +6 -6
- package/dist/record/sqlite/case-repository.cjs.map +1 -1
- package/dist/record/sqlite/coordination-repository.cjs +25 -25
- package/dist/record/sqlite/coordination-repository.cjs.map +1 -1
- package/dist/record/sqlite/current-schema.cjs +115 -111
- package/dist/record/sqlite/current-schema.cjs.map +1 -1
- package/dist/record/sqlite/current-schema.d.cts +3 -3
- package/dist/record/sqlite/current-schema.d.mts +3 -3
- package/dist/record/sqlite/current-schema.d.ts +3 -3
- package/dist/record/sqlite/database.cjs +56 -53
- package/dist/record/sqlite/database.cjs.map +1 -1
- package/dist/record/sqlite/index.cjs +3 -1
- package/dist/record/sqlite/index.cjs.map +1 -1
- package/dist/record/sqlite/index.d.cts +5 -2
- package/dist/record/sqlite/index.d.mts +5 -2
- package/dist/record/sqlite/index.d.ts +5 -2
- package/dist/record/sqlite/legacy-schema-018.cjs +443 -0
- package/dist/record/sqlite/legacy-schema-018.cjs.map +1 -0
- package/dist/record/sqlite/legacy-schema-018.d.cts +6 -0
- package/dist/record/sqlite/legacy-schema-018.d.mts +6 -0
- package/dist/record/sqlite/legacy-schema-018.d.ts +6 -0
- package/dist/record/sqlite/legacy-schema-018.js +6 -0
- package/dist/record/sqlite/legacy-schema-018.js.map +1 -0
- package/dist/record/sqlite/migration.cjs +105 -46
- package/dist/record/sqlite/migration.cjs.map +1 -1
- package/dist/record/sqlite/migration.d.cts +2 -1
- package/dist/record/sqlite/migration.d.mts +2 -1
- package/dist/record/sqlite/migration.d.ts +2 -1
- package/dist/record/sqlite/portable-capture.cjs +13 -13
- package/dist/record/sqlite/portable-capture.cjs.map +1 -1
- package/dist/record/sqlite/registry-repository.cjs +22 -22
- package/dist/record/sqlite/registry-repository.cjs.map +1 -1
- package/dist/record/sqlite/schema.cjs +10 -2
- package/dist/record/sqlite/schema.cjs.map +1 -1
- package/dist/record/sqlite/schema.d.cts +4 -1
- package/dist/record/sqlite/schema.d.mts +4 -1
- package/dist/record/sqlite/schema.d.ts +4 -1
- package/dist/record/sqlite/schema.js +20 -14
- package/dist/record/sqlite/storage-worker.cjs +1 -1
- package/dist/record/sqlite/storage-worker.cjs.map +1 -1
- package/dist/record/sqlite/storage.cjs +316 -232
- package/dist/record/sqlite/storage.cjs.map +1 -1
- package/dist/record/sqlite/storage.d.cts +10 -2
- package/dist/record/sqlite/storage.d.mts +10 -2
- package/dist/record/sqlite/storage.d.ts +10 -2
- package/dist/record/sqlite/storage.js +54 -50
- package/dist/record/sqlite/types.cjs +1 -1
- package/dist/record/sqlite/types.cjs.map +1 -1
- package/dist/record/sqlite/types.d.cts +13 -1
- package/dist/record/sqlite/types.d.mts +13 -1
- package/dist/record/sqlite/types.d.ts +13 -1
- package/dist/run/cli/contribution.cjs +17 -12
- package/dist/run/cli/contribution.cjs.map +1 -1
- package/dist/run/host/lifecycle-adapter.cjs +1 -1
- package/dist/run/host/lifecycle-adapter.cjs.map +1 -1
- package/dist/run/storage/owner-identity.cjs +78 -16
- package/dist/run/storage/owner-identity.cjs.map +1 -1
- package/dist/run/storage/owner-identity.d.cts +2 -1
- package/dist/run/storage/owner-identity.d.mts +2 -1
- package/dist/run/storage/owner-identity.d.ts +2 -1
- package/dist/run/storage/sqlite.cjs +55 -55
- package/dist/run/storage/sqlite.cjs.map +1 -1
- package/dist/runner/accept.cjs +12 -42
- package/dist/runner/accept.cjs.map +1 -1
- package/dist/runner/accept.d.cts +2 -3
- package/dist/runner/accept.d.mts +2 -3
- package/dist/runner/accept.d.ts +2 -3
- package/dist/runner/adapter-usage.cjs +2 -2
- package/dist/runner/adapter-usage.cjs.map +1 -1
- package/dist/runner/adoption.cjs +14 -26
- package/dist/runner/adoption.cjs.map +1 -1
- package/dist/runner/adoption.d.cts +5 -13
- package/dist/runner/adoption.d.mts +5 -13
- package/dist/runner/adoption.d.ts +5 -13
- package/dist/runner/adoption.js +2 -4
- package/dist/runner/record.cjs +24 -18
- package/dist/runner/record.cjs.map +1 -1
- package/dist/runner/rename-experiment.cjs +5 -7
- package/dist/runner/rename-experiment.cjs.map +1 -1
- package/dist/runner/reuse-plan.cjs +37 -18
- package/dist/runner/reuse-plan.cjs.map +1 -1
- package/dist/runner/reuse-plan.d.cts +4 -1
- package/dist/runner/reuse-plan.d.mts +4 -1
- package/dist/runner/reuse-plan.d.ts +4 -1
- package/dist/runner/setup-prefix-plan.cjs +17 -12
- package/dist/runner/setup-prefix-plan.cjs.map +1 -1
- package/dist/runner/setup-prefix-plan.d.cts +0 -2
- package/dist/runner/setup-prefix-plan.d.mts +0 -2
- package/dist/runner/setup-prefix-plan.d.ts +0 -2
- package/dist/runner/setup-prefix-plan.js +8 -12
- package/dist/sandbox/backend.cjs +10 -1
- package/dist/sandbox/backend.cjs.map +1 -1
- package/dist/sandbox/backend.d.cts +16 -8
- package/dist/sandbox/backend.d.mts +16 -8
- package/dist/sandbox/backend.d.ts +16 -8
- package/dist/sandbox/backend.js +28 -26
- package/dist/sandbox/docker.cjs +7 -1
- package/dist/sandbox/docker.cjs.map +1 -1
- package/dist/sandbox/e2b-cache-repository.cjs +13 -3
- package/dist/sandbox/e2b-cache-repository.cjs.map +1 -1
- package/dist/sandbox/e2b-cache-repository.d.cts +3 -0
- package/dist/sandbox/e2b-cache-repository.d.mts +3 -0
- package/dist/sandbox/e2b-cache-repository.d.ts +3 -0
- package/dist/sandbox/e2b-cache-repository.js +16 -12
- package/dist/sandbox/e2b.cjs +2 -2
- package/dist/sandbox/e2b.cjs.map +1 -1
- package/dist/sandbox/incus/materialize.cjs +1 -1
- package/dist/sandbox/incus/materialize.cjs.map +1 -1
- package/dist/show/contribution.cjs +3 -3
- package/dist/show/contribution.cjs.map +1 -1
- package/dist/show/model.cjs +14 -13
- package/dist/show/model.cjs.map +1 -1
- package/dist/show/model.d.cts +7 -7
- package/dist/show/model.d.mts +7 -7
- package/dist/show/model.d.ts +7 -7
- package/dist/show/render.cjs +14 -0
- package/dist/show/render.cjs.map +1 -1
- package/dist/user-database/storage-worker.cjs +13 -3
- package/dist/user-database/storage-worker.cjs.map +1 -1
- package/dist/view/app-dist/.vite/manifest.json +2 -2
- package/dist/view/app-dist/assets/{index-CmVoXbwG.js → index-B3ijZRph.js} +17 -17
- package/dist/view/app-dist/assets/{quality-cost-scatter-BuLISaH4.js → quality-cost-scatter-B--DfJ9s.js} +1 -1
- package/dist/view/app-dist/index.html +1 -1
- package/dist/view/application-runtime.cjs +8 -0
- package/dist/view/application-runtime.cjs.map +1 -0
- package/dist/view/application-runtime.d.cts +9 -0
- package/dist/view/application-runtime.d.mts +9 -0
- package/dist/view/application-runtime.d.ts +9 -0
- package/dist/view/application-runtime.js +6 -0
- package/dist/view/application-runtime.js.map +1 -0
- package/dist/view/cli/contribution.cjs +5 -2
- package/dist/view/cli/contribution.cjs.map +1 -1
- package/dist/view/cli/contribution.d.cts +2 -1
- package/dist/view/cli/contribution.d.mts +2 -1
- package/dist/view/cli/contribution.d.ts +2 -1
- package/dist/view/function-runtime.mjs +1019 -456
- package/dist/view/http-protocol.d.cts +1 -9
- package/dist/view/http-protocol.d.mts +1 -9
- package/dist/view/http-protocol.d.ts +1 -9
- package/dist/view/inspection-host.cjs +39 -30
- package/dist/view/inspection-host.cjs.map +1 -1
- package/dist/view/inspection-host.d.cts +7545 -2
- package/dist/view/inspection-host.d.mts +7545 -2
- package/dist/view/inspection-host.d.ts +7545 -2
- package/dist/view/server.cjs +8 -5
- package/dist/view/server.cjs.map +1 -1
- package/dist/view/server.d.cts +4 -2
- package/dist/view/server.d.mts +4 -2
- package/dist/view/server.d.ts +4 -2
- package/docs-site/zh/reference/cli.mdx +1 -2
- package/docs-site/zh/tutorials/control-run-cost.mdx +61 -0
- package/docs-site/zh/tutorials/niceeval-taste-application.mdx +21 -0
- package/package.json +1 -1
|
@@ -24,6 +24,8 @@ exports.publishRunSeal = publishRunSeal;
|
|
|
24
24
|
exports.verifyAllSealedRuns = verifyAllSealedRuns;
|
|
25
25
|
exports.readSealedRunSummary = readSealedRunSummary;
|
|
26
26
|
exports.readSealedRunCutoff = readSealedRunCutoff;
|
|
27
|
+
exports.findSourceBarrierCandidate = findSourceBarrierCandidate;
|
|
28
|
+
exports.findAcceptedAttemptRunIds = findAcceptedAttemptRunIds;
|
|
27
29
|
exports.findExperimentRunIds = findExperimentRunIds;
|
|
28
30
|
exports.listSealedRunSummaries = listSealedRunSummaries;
|
|
29
31
|
exports.readSealedRunSummaryPage = readSealedRunSummaryPage;
|
|
@@ -50,19 +52,19 @@ function discardAttempt(connection, input) {
|
|
|
50
52
|
requireIdentity(input.writerGeneration, "writerGeneration");
|
|
51
53
|
requireIdentity(input.attemptId, "attemptId");
|
|
52
54
|
(0, transaction_ts_1.withImmediateTransaction)(connection, input.deadlineEpochMs, "discard-attempt", () => {
|
|
53
|
-
const barrier = (0, database_ts_1.recordStatement)(connection, "SELECT barrier_state FROM
|
|
55
|
+
const barrier = (0, database_ts_1.recordStatement)(connection, "SELECT barrier_state FROM ne19_record_metadata WHERE singleton=1").get();
|
|
54
56
|
if (barrier === undefined || text(barrier, "barrier_state") !== "open") {
|
|
55
57
|
throw (0, errors_ts_1.sqliteError)("record-command-conflict", "discard-attempt", "ProjectDatabase writer barrier is not open");
|
|
56
58
|
}
|
|
57
|
-
const run = (0, database_ts_1.recordStatement)(connection, "SELECT status,writer_generation FROM
|
|
59
|
+
const run = (0, database_ts_1.recordStatement)(connection, "SELECT status,writer_generation FROM ne19_runs WHERE run_id=?").get(input.runId);
|
|
58
60
|
if (run === undefined || text(run, "status") !== "open" || text(run, "writer_generation") !== input.writerGeneration) {
|
|
59
61
|
throw (0, errors_ts_1.sqliteError)("record-sqlite-error", "discard-attempt", "Attempt owner is no longer writable");
|
|
60
62
|
}
|
|
61
|
-
(0, database_ts_1.recordStatement)(connection, "DELETE FROM
|
|
63
|
+
(0, database_ts_1.recordStatement)(connection, "DELETE FROM ne19_attachments WHERE owner_kind='attempt' AND owner_run_id=? AND owner_attempt_id=?")
|
|
62
64
|
.run(input.runId, input.attemptId);
|
|
63
|
-
(0, database_ts_1.recordStatement)(connection, "DELETE FROM
|
|
65
|
+
(0, database_ts_1.recordStatement)(connection, "DELETE FROM ne19_members WHERE target_run_id=? AND origin_run_id=? AND attempt_id=?")
|
|
64
66
|
.run(input.runId, input.runId, input.attemptId);
|
|
65
|
-
(0, database_ts_1.recordStatement)(connection, "DELETE FROM
|
|
67
|
+
(0, database_ts_1.recordStatement)(connection, "DELETE FROM ne19_attempts WHERE origin_run_id=? AND attempt_id=?")
|
|
66
68
|
.run(input.runId, input.attemptId);
|
|
67
69
|
});
|
|
68
70
|
}
|
|
@@ -385,24 +387,24 @@ function visitRunSealEntries(connection, runId, visit, verifyPayloadBytes = true
|
|
|
385
387
|
}
|
|
386
388
|
return value;
|
|
387
389
|
};
|
|
388
|
-
const record = (0, database_ts_1.recordStatement)(connection, "SELECT record_payload,record_digest FROM
|
|
390
|
+
const record = (0, database_ts_1.recordStatement)(connection, "SELECT record_payload,record_digest FROM ne19_record_metadata WHERE singleton=1").get();
|
|
389
391
|
visit((0, seal_ts_1.recordSealEntry)(verified(record, "record_digest", "record_payload")));
|
|
390
|
-
const run = (0, database_ts_1.recordStatement)(connection, `SELECT run_id,writer_generation,started_at,core_payload,core_digest FROM
|
|
392
|
+
const run = (0, database_ts_1.recordStatement)(connection, `SELECT run_id,writer_generation,started_at,core_payload,core_digest FROM ne19_runs WHERE run_id=?`).get(runId);
|
|
391
393
|
if (run === undefined)
|
|
392
394
|
throw (0, errors_ts_1.sqliteError)("record-seal-incomplete", "verify-seal", `Run ${runId} is missing`);
|
|
393
395
|
visit((0, seal_ts_1.runSealEntry)({ runId: text(run, "run_id"), writerGeneration: text(run, "writer_generation"), startedAt: text(run, "started_at"), coreDigest: verified(run, "core_digest", "core_payload") }));
|
|
394
|
-
for (const row of (0, database_ts_1.recordStatement)(connection, "SELECT slot_id,ordinal,core_payload,core_digest FROM
|
|
396
|
+
for (const row of (0, database_ts_1.recordStatement)(connection, "SELECT slot_id,ordinal,core_payload,core_digest FROM ne19_slots WHERE run_id=?").iterate(runId)) {
|
|
395
397
|
visit((0, seal_ts_1.slotSealEntry)(runId, { slotId: text(row, "slot_id"), ordinal: integer(row, "ordinal"), coreDigest: verified(row, "core_digest", "core_payload") }));
|
|
396
398
|
}
|
|
397
|
-
for (const row of (0, database_ts_1.recordStatement)(connection, "SELECT attempt_id,attempt_locator,core_payload,core_digest FROM
|
|
399
|
+
for (const row of (0, database_ts_1.recordStatement)(connection, "SELECT attempt_id,attempt_locator,core_payload,core_digest FROM ne19_attempts WHERE origin_run_id=?").iterate(runId)) {
|
|
398
400
|
visit((0, seal_ts_1.attemptSealEntry)(runId, text(row, "attempt_id"), text(row, "attempt_locator"), verified(row, "core_digest", "core_payload")));
|
|
399
401
|
}
|
|
400
|
-
for (const row of (0, database_ts_1.recordStatement)(connection, `SELECT slot_id,origin_run_id,attempt_id,action,core_payload,core_digest FROM
|
|
402
|
+
for (const row of (0, database_ts_1.recordStatement)(connection, `SELECT slot_id,origin_run_id,attempt_id,action,core_payload,core_digest FROM ne19_members WHERE target_run_id=?`).iterate(runId)) {
|
|
401
403
|
visit((0, seal_ts_1.memberSealEntry)(runId, { slotId: text(row, "slot_id"), originRunId: optionalText(row, "origin_run_id"),
|
|
402
404
|
attemptId: optionalText(row, "attempt_id"), action: memberAction(row, "action"), coreDigest: verified(row, "core_digest", "core_payload") }));
|
|
403
405
|
}
|
|
404
406
|
for (const row of (0, database_ts_1.recordStatement)(connection, `SELECT attachment_id,owner_kind,owner_run_id,owner_attempt_id,family,family_revision,logical_identity,
|
|
405
|
-
canonical_payload,canonical_digest,logical_inventory,inventory_digest FROM
|
|
407
|
+
canonical_payload,canonical_digest,logical_inventory,inventory_digest FROM ne19_attachments WHERE owner_run_id=?`).iterate(runId)) {
|
|
406
408
|
const canonicalDigest = verified(row, "canonical_digest", "canonical_payload");
|
|
407
409
|
const inventoryDigest = verified(row, "inventory_digest", "logical_inventory");
|
|
408
410
|
visit((0, seal_ts_1.attachmentSealEntry)({ attachmentId: text(row, "attachment_id"), ownerKind: ownerKind(row, "owner_kind"),
|
|
@@ -410,25 +412,25 @@ function visitRunSealEntries(connection, runId, visit, verifyPayloadBytes = true
|
|
|
410
412
|
familyRevision: integer(row, "family_revision"), logicalIdentity: text(row, "logical_identity"), canonicalDigest, inventoryDigest }));
|
|
411
413
|
}
|
|
412
414
|
for (const row of (0, database_ts_1.recordStatement)(connection, `SELECT r.attachment_id,r.ordinal,r.target_owner_kind,r.target_family,r.canonical_payload,r.reference_digest
|
|
413
|
-
FROM
|
|
415
|
+
FROM ne19_attachment_references r JOIN ne19_attachments a ON a.attachment_id=r.attachment_id WHERE a.owner_run_id=?`).iterate(runId)) {
|
|
414
416
|
visit((0, seal_ts_1.referenceSealEntry)(text(row, "attachment_id"), { ordinal: integer(row, "ordinal"), owner: ownerKind(row, "target_owner_kind"),
|
|
415
417
|
family: text(row, "target_family"), referenceDigest: verified(row, "reference_digest", "canonical_payload") }));
|
|
416
418
|
}
|
|
417
419
|
for (const row of (0, database_ts_1.recordStatement)(connection, `SELECT i.attachment_id,i.ordinal,i.logical_identity,i.canonical_payload,i.canonical_digest
|
|
418
|
-
FROM
|
|
420
|
+
FROM ne19_collection_items i JOIN ne19_attachments a ON a.attachment_id=i.attachment_id WHERE a.owner_run_id=?`).iterate(runId)) {
|
|
419
421
|
visit((0, seal_ts_1.collectionItemSealEntry)(text(row, "attachment_id"), { ordinal: integer(row, "ordinal"), logicalIdentity: text(row, "logical_identity"),
|
|
420
422
|
canonicalDigest: verified(row, "canonical_digest", "canonical_payload") }));
|
|
421
423
|
}
|
|
422
424
|
for (const row of (0, database_ts_1.recordStatement)(connection, `SELECT c.content_id,c.attachment_id,c.logical_handle,c.byte_length,c.overall_digest,c.chunk_count
|
|
423
|
-
FROM
|
|
425
|
+
FROM ne19_contents c JOIN ne19_attachments a ON a.attachment_id=c.attachment_id WHERE a.owner_run_id=?`).iterate(runId)) {
|
|
424
426
|
visit((0, seal_ts_1.contentSealEntry)(text(row, "attachment_id"), { contentId: text(row, "content_id"), logicalHandle: text(row, "logical_handle"),
|
|
425
427
|
byteLength: integer(row, "byte_length"), digest: text(row, "overall_digest"), chunkCount: integer(row, "chunk_count") }));
|
|
426
428
|
}
|
|
427
429
|
const chunkSql = verifyContentChunkBytes
|
|
428
|
-
? `SELECT c.content_id,c.ordinal,c.bytes,c.chunk_digest FROM
|
|
429
|
-
JOIN
|
|
430
|
-
: `SELECT c.content_id,c.ordinal,c.chunk_digest FROM
|
|
431
|
-
JOIN
|
|
430
|
+
? `SELECT c.content_id,c.ordinal,c.bytes,c.chunk_digest FROM ne19_content_chunks c
|
|
431
|
+
JOIN ne19_contents n ON n.content_id=c.content_id JOIN ne19_attachments a ON a.attachment_id=n.attachment_id WHERE a.owner_run_id=?`
|
|
432
|
+
: `SELECT c.content_id,c.ordinal,c.chunk_digest FROM ne19_content_chunks c
|
|
433
|
+
JOIN ne19_contents n ON n.content_id=c.content_id JOIN ne19_attachments a ON a.attachment_id=n.attachment_id WHERE a.owner_run_id=?`;
|
|
432
434
|
for (const row of (0, database_ts_1.recordStatement)(connection, chunkSql).iterate(runId)) {
|
|
433
435
|
const chunkDigest = text(row, "chunk_digest");
|
|
434
436
|
requireDigest(chunkDigest, "chunk_digest");
|
|
@@ -444,8 +446,8 @@ function collectRunSealEntries(connection, runId) {
|
|
|
444
446
|
return orderEntries(entries);
|
|
445
447
|
}
|
|
446
448
|
function runRow(connection, runId) {
|
|
447
|
-
return (0, database_ts_1.recordStatement)(connection, `SELECT run_id,status,writer_generation,started_at,core_payload,core_digest,mutation_sequence,
|
|
448
|
-
candidate_seal_identity,candidate_seal_entry_count,candidate_seal_staged_count,logical_seal_identity FROM
|
|
449
|
+
return (0, database_ts_1.recordStatement)(connection, `SELECT run_id,experiment_id,status,writer_generation,started_at,core_payload,core_digest,mutation_sequence,
|
|
450
|
+
candidate_seal_identity,candidate_seal_entry_count,candidate_seal_staged_count,logical_seal_identity FROM ne19_runs WHERE run_id=?`)
|
|
449
451
|
.get(runId);
|
|
450
452
|
}
|
|
451
453
|
function assertBoundedBatch(operation, rowCount, byteCount) {
|
|
@@ -460,11 +462,11 @@ function assertBoundedRow(operation, field, value) {
|
|
|
460
462
|
}
|
|
461
463
|
}
|
|
462
464
|
function assertRunFence(connection, runId, writerGeneration, operation, expectedStatus = "open") {
|
|
463
|
-
const barrier = (0, database_ts_1.recordStatement)(connection, "SELECT barrier_state FROM
|
|
465
|
+
const barrier = (0, database_ts_1.recordStatement)(connection, "SELECT barrier_state FROM ne19_record_metadata WHERE singleton=1").get();
|
|
464
466
|
if (barrier === undefined || text(barrier, "barrier_state") !== "open") {
|
|
465
467
|
throw (0, errors_ts_1.sqliteError)("record-command-conflict", operation, "ProjectDatabase writer barrier is not open");
|
|
466
468
|
}
|
|
467
|
-
const active = (0, database_ts_1.recordStatement)(connection, "SELECT 1 FROM
|
|
469
|
+
const active = (0, database_ts_1.recordStatement)(connection, "SELECT 1 FROM ne19_run_resources WHERE run_id=? AND terminal_state IS NULL AND current_writer_generation=?")
|
|
468
470
|
.get(runId, writerGeneration);
|
|
469
471
|
const row = runRow(connection, runId);
|
|
470
472
|
if (active === undefined || row === undefined || text(row, "writer_generation") !== writerGeneration || text(row, "status") !== expectedStatus) {
|
|
@@ -473,23 +475,37 @@ function assertRunFence(connection, runId, writerGeneration, operation, expected
|
|
|
473
475
|
return row;
|
|
474
476
|
}
|
|
475
477
|
function bumpMutationSequence(connection, runId) {
|
|
476
|
-
(0, database_ts_1.recordStatement)(connection, "UPDATE
|
|
478
|
+
(0, database_ts_1.recordStatement)(connection, "UPDATE ne19_runs SET mutation_sequence=mutation_sequence+1 WHERE run_id=? AND status='open'").run(runId);
|
|
477
479
|
}
|
|
478
480
|
function assertAttachmentFence(connection, runId, attachmentId, operation) {
|
|
479
|
-
const row = (0, database_ts_1.recordStatement)(connection, `SELECT a.owner_run_id,a.owner_kind,at.publication_state FROM
|
|
480
|
-
LEFT JOIN
|
|
481
|
+
const row = (0, database_ts_1.recordStatement)(connection, `SELECT a.owner_run_id,a.owner_kind,at.publication_state FROM ne19_attachments a
|
|
482
|
+
LEFT JOIN ne19_attempts at ON at.origin_run_id=a.owner_run_id AND at.attempt_id=a.owner_attempt_id
|
|
481
483
|
WHERE a.attachment_id=?`).get(attachmentId);
|
|
482
484
|
if (row === undefined || text(row, "owner_run_id") !== runId ||
|
|
483
485
|
(text(row, "owner_kind") === "attempt" && optionalText(row, "publication_state") === "published")) {
|
|
484
486
|
throw (0, errors_ts_1.sqliteError)("record-command-conflict", operation, `Attachment ${attachmentId} does not belong to Run ${runId}`);
|
|
485
487
|
}
|
|
486
488
|
}
|
|
489
|
+
function validatedRunExperimentId(bytes, runId) {
|
|
490
|
+
let decoded;
|
|
491
|
+
try {
|
|
492
|
+
decoded = (0, core_ts_1.decodeRunDocument)(JSON.parse(new TextDecoder("utf-8", { fatal: true }).decode(bytes)));
|
|
493
|
+
}
|
|
494
|
+
catch (cause) {
|
|
495
|
+
throw (0, errors_ts_1.sqliteError)("record-content-invalid", "run-experiment-identity", "Run Core is not valid JSON", cause);
|
|
496
|
+
}
|
|
497
|
+
if (effect_1.Result.isFailure(decoded) || decoded.success.runId !== runId) {
|
|
498
|
+
throw (0, errors_ts_1.sqliteError)("record-content-invalid", "run-experiment-identity", "Run Core identity is invalid");
|
|
499
|
+
}
|
|
500
|
+
return decoded.success.experimentId;
|
|
501
|
+
}
|
|
487
502
|
function beginRun(connection, input) {
|
|
488
503
|
requireIdentity(input.runId, "runId");
|
|
504
|
+
requireIdentity(input.experimentId, "experimentId");
|
|
489
505
|
requireIdentity(input.writerGeneration, "writerGeneration");
|
|
490
506
|
requireIdentity(input.startedAt, "startedAt");
|
|
491
507
|
(0, transaction_ts_1.withImmediateTransaction)(connection, input.deadlineEpochMs, "begin-run", () => {
|
|
492
|
-
const barrier = (0, database_ts_1.recordStatement)(connection, "SELECT barrier_state FROM
|
|
508
|
+
const barrier = (0, database_ts_1.recordStatement)(connection, "SELECT barrier_state FROM ne19_record_metadata WHERE singleton=1").get();
|
|
493
509
|
if (barrier === undefined)
|
|
494
510
|
throw (0, errors_ts_1.sqliteError)("record-database-invalid", "begin-run", "ProjectDatabase barrier is missing");
|
|
495
511
|
if (text(barrier, "barrier_state") === "draining") {
|
|
@@ -497,11 +513,11 @@ function beginRun(connection, input) {
|
|
|
497
513
|
}
|
|
498
514
|
if (text(barrier, "barrier_state") === "portable")
|
|
499
515
|
throw (0, errors_ts_1.sqliteError)("record-command-conflict", "begin-run", "ProjectDatabase must reopen before writer admission");
|
|
500
|
-
(0, database_ts_1.recordStatement)(connection, `INSERT OR IGNORE INTO
|
|
516
|
+
(0, database_ts_1.recordStatement)(connection, `INSERT OR IGNORE INTO ne19_runs(run_id,experiment_id,status,writer_generation,started_at,core_payload,core_digest,
|
|
501
517
|
mutation_sequence,candidate_seal_identity,candidate_seal_entry_count,candidate_seal_staged_count,logical_seal_identity)
|
|
502
|
-
VALUES (
|
|
518
|
+
VALUES (?,?,'open',?,?,NULL,NULL,0,NULL,NULL,0,NULL)`).run(input.runId, input.experimentId, input.writerGeneration, input.startedAt);
|
|
503
519
|
const stored = runRow(connection, input.runId);
|
|
504
|
-
if (stored === undefined || text(stored, "writer_generation") !== input.writerGeneration ||
|
|
520
|
+
if (stored === undefined || text(stored, "experiment_id") !== input.experimentId || text(stored, "writer_generation") !== input.writerGeneration ||
|
|
505
521
|
text(stored, "started_at") !== input.startedAt) {
|
|
506
522
|
throw (0, errors_ts_1.sqliteError)("record-command-conflict", "begin-run", `Run ${input.runId} conflicts with its durable admission`);
|
|
507
523
|
}
|
|
@@ -515,9 +531,9 @@ function admitAttempt(connection, input) {
|
|
|
515
531
|
requireAttemptLocator(input.attemptId, input.attemptLocator, "admit-attempt");
|
|
516
532
|
(0, transaction_ts_1.withImmediateTransaction)(connection, input.deadlineEpochMs, "admit-attempt", () => {
|
|
517
533
|
assertRunFence(connection, input.runId, input.writerGeneration, "admit-attempt");
|
|
518
|
-
const inserted = (0, database_ts_1.recordStatement)(connection, `INSERT OR IGNORE INTO
|
|
534
|
+
const inserted = (0, database_ts_1.recordStatement)(connection, `INSERT OR IGNORE INTO ne19_attempts(origin_run_id,attempt_id,attempt_locator,core_payload,core_digest)
|
|
519
535
|
VALUES (?,?,?,NULL,NULL)`).run(input.runId, input.attemptId, input.attemptLocator);
|
|
520
|
-
const stored = (0, database_ts_1.recordStatement)(connection, "SELECT origin_run_id,attempt_locator FROM
|
|
536
|
+
const stored = (0, database_ts_1.recordStatement)(connection, "SELECT origin_run_id,attempt_locator FROM ne19_attempts WHERE origin_run_id=? AND attempt_id=?")
|
|
521
537
|
.get(input.runId, input.attemptId);
|
|
522
538
|
if (stored === undefined || text(stored, "origin_run_id") !== input.runId || text(stored, "attempt_locator") !== input.attemptLocator) {
|
|
523
539
|
throw (0, errors_ts_1.sqliteError)("record-command-conflict", "admit-attempt", `Attempt ${input.attemptId} conflicts with its durable admission`);
|
|
@@ -538,15 +554,15 @@ function admitAttachment(connection, input) {
|
|
|
538
554
|
(0, transaction_ts_1.withImmediateTransaction)(connection, input.deadlineEpochMs, "admit-attachment", () => {
|
|
539
555
|
assertRunFence(connection, input.runId, input.writerGeneration, "admit-attachment");
|
|
540
556
|
if (input.ownerKind === "attempt") {
|
|
541
|
-
const admitted = (0, database_ts_1.recordStatement)(connection, "SELECT 1 AS admitted FROM
|
|
557
|
+
const admitted = (0, database_ts_1.recordStatement)(connection, "SELECT 1 AS admitted FROM ne19_attempts WHERE origin_run_id=? AND attempt_id=?")
|
|
542
558
|
.get(input.runId, input.ownerAttemptId);
|
|
543
559
|
if (admitted === undefined)
|
|
544
560
|
throw (0, errors_ts_1.sqliteError)("record-command-conflict", "admit-attachment", "attempt owner is not admitted");
|
|
545
561
|
}
|
|
546
|
-
const inserted = (0, database_ts_1.recordStatement)(connection, `INSERT OR IGNORE INTO
|
|
562
|
+
const inserted = (0, database_ts_1.recordStatement)(connection, `INSERT OR IGNORE INTO ne19_attachments(attachment_id,owner_kind,owner_run_id,owner_attempt_id,
|
|
547
563
|
family,family_revision,logical_identity,canonical_payload,canonical_digest,logical_inventory,inventory_digest)
|
|
548
564
|
VALUES (?,?,?,?,?,?,NULL,NULL,NULL,NULL,NULL)`).run(input.attachmentId, input.ownerKind, input.ownerRunId, input.ownerAttemptId ?? null, input.family, input.familyRevision);
|
|
549
|
-
const stored = (0, database_ts_1.recordStatement)(connection, `SELECT owner_kind,owner_run_id,owner_attempt_id,family,family_revision FROM
|
|
565
|
+
const stored = (0, database_ts_1.recordStatement)(connection, `SELECT owner_kind,owner_run_id,owner_attempt_id,family,family_revision FROM ne19_attachments
|
|
550
566
|
WHERE attachment_id=?`).get(input.attachmentId);
|
|
551
567
|
if (stored === undefined || text(stored, "owner_kind") !== input.ownerKind || text(stored, "owner_run_id") !== input.ownerRunId ||
|
|
552
568
|
optionalText(stored, "owner_attempt_id") !== input.ownerAttemptId || text(stored, "family") !== input.family ||
|
|
@@ -562,16 +578,16 @@ function admitContent(connection, input) {
|
|
|
562
578
|
requireIdentity(input.logicalHandle, "logicalHandle");
|
|
563
579
|
(0, transaction_ts_1.withImmediateTransaction)(connection, input.deadlineEpochMs, "admit-content", () => {
|
|
564
580
|
assertRunFence(connection, input.runId, input.writerGeneration, "admit-content");
|
|
565
|
-
const attachment = (0, database_ts_1.recordStatement)(connection, `SELECT a.owner_run_id,a.owner_kind,at.publication_state FROM
|
|
566
|
-
LEFT JOIN
|
|
581
|
+
const attachment = (0, database_ts_1.recordStatement)(connection, `SELECT a.owner_run_id,a.owner_kind,at.publication_state FROM ne19_attachments a
|
|
582
|
+
LEFT JOIN ne19_attempts at ON at.origin_run_id=a.owner_run_id AND at.attempt_id=a.owner_attempt_id WHERE a.attachment_id=?`)
|
|
567
583
|
.get(input.attachmentId);
|
|
568
584
|
if (attachment === undefined || text(attachment, "owner_run_id") !== input.runId ||
|
|
569
585
|
(text(attachment, "owner_kind") === "attempt" && optionalText(attachment, "publication_state") === "published")) {
|
|
570
586
|
throw (0, errors_ts_1.sqliteError)("record-command-conflict", "admit-content", "attachment admission is missing");
|
|
571
587
|
}
|
|
572
|
-
const inserted = (0, database_ts_1.recordStatement)(connection, `INSERT OR IGNORE INTO
|
|
588
|
+
const inserted = (0, database_ts_1.recordStatement)(connection, `INSERT OR IGNORE INTO ne19_contents(content_id,attachment_id,logical_handle,byte_length,overall_digest,chunk_count)
|
|
573
589
|
VALUES (?,?,?,NULL,NULL,NULL)`).run(input.contentId, input.attachmentId, input.logicalHandle);
|
|
574
|
-
const stored = (0, database_ts_1.recordStatement)(connection, "SELECT attachment_id,logical_handle FROM
|
|
590
|
+
const stored = (0, database_ts_1.recordStatement)(connection, "SELECT attachment_id,logical_handle FROM ne19_contents WHERE content_id=?")
|
|
575
591
|
.get(input.contentId);
|
|
576
592
|
if (stored === undefined || text(stored, "attachment_id") !== input.attachmentId || text(stored, "logical_handle") !== input.logicalHandle) {
|
|
577
593
|
throw (0, errors_ts_1.sqliteError)("record-command-conflict", "admit-content", `Content ${input.contentId} conflicts with its durable admission`);
|
|
@@ -594,13 +610,13 @@ function stageAttachmentMetadata(connection, input) {
|
|
|
594
610
|
const byteCount = attachment.canonicalBytes.byteLength + attachment.logicalInventoryBytes.byteLength;
|
|
595
611
|
assertBoundedBatch("stage-attachment", 1 + attachment.contents.length, byteCount);
|
|
596
612
|
(0, transaction_ts_1.withImmediateTransaction)(connection, input.deadlineEpochMs, "stage-attachment", () => {
|
|
597
|
-
(0, database_ts_1.recordStatement)(connection, `INSERT OR IGNORE INTO
|
|
613
|
+
(0, database_ts_1.recordStatement)(connection, `INSERT OR IGNORE INTO ne19_attachments(attachment_id,owner_kind,owner_run_id,owner_attempt_id,family,family_revision,logical_identity,canonical_payload,canonical_digest,logical_inventory,inventory_digest)
|
|
598
614
|
VALUES (?,?,?,?,?,?,?,?,?,?,?)`).run(attachment.attachmentId, attachment.ownerKind, attachment.ownerRunId, attachment.ownerAttemptId ?? null, attachment.family, attachment.familyRevision, attachment.logicalIdentity, attachment.canonicalBytes, attachment.canonicalDigest, attachment.logicalInventoryBytes, attachment.inventoryDigest);
|
|
599
615
|
for (const content of attachment.contents)
|
|
600
|
-
(0, database_ts_1.recordStatement)(connection, `INSERT OR IGNORE INTO
|
|
616
|
+
(0, database_ts_1.recordStatement)(connection, `INSERT OR IGNORE INTO ne19_contents(content_id,attachment_id,logical_handle,byte_length,overall_digest,chunk_count)
|
|
601
617
|
VALUES (?,?,?,?,?,?)`).run(content.contentId, attachment.attachmentId, content.logicalHandle, content.byteLength, content.digest, content.chunkCount);
|
|
602
618
|
const stored = (0, database_ts_1.recordStatement)(connection, `SELECT owner_kind,owner_run_id,owner_attempt_id,family,family_revision,logical_identity,
|
|
603
|
-
canonical_payload,canonical_digest,logical_inventory,inventory_digest FROM
|
|
619
|
+
canonical_payload,canonical_digest,logical_inventory,inventory_digest FROM ne19_attachments WHERE attachment_id=?`)
|
|
604
620
|
.get(attachment.attachmentId);
|
|
605
621
|
if (stored === undefined || text(stored, "owner_kind") !== attachment.ownerKind || text(stored, "owner_run_id") !== attachment.ownerRunId ||
|
|
606
622
|
optionalText(stored, "owner_attempt_id") !== attachment.ownerAttemptId || text(stored, "family") !== attachment.family ||
|
|
@@ -610,7 +626,7 @@ function stageAttachmentMetadata(connection, input) {
|
|
|
610
626
|
throw (0, errors_ts_1.sqliteError)("record-command-conflict", "stage-attachment", `attachment ${attachment.attachmentId} conflicts with its durable retry`);
|
|
611
627
|
for (const content of attachment.contents) {
|
|
612
628
|
const persisted = (0, database_ts_1.recordStatement)(connection, `SELECT attachment_id,logical_handle,byte_length,overall_digest,chunk_count
|
|
613
|
-
FROM
|
|
629
|
+
FROM ne19_contents WHERE content_id=?`).get(content.contentId);
|
|
614
630
|
if (persisted === undefined || text(persisted, "attachment_id") !== attachment.attachmentId || text(persisted, "logical_handle") !== content.logicalHandle ||
|
|
615
631
|
integer(persisted, "byte_length") !== content.byteLength || text(persisted, "overall_digest") !== content.digest || integer(persisted, "chunk_count") !== content.chunkCount)
|
|
616
632
|
throw (0, errors_ts_1.sqliteError)("record-command-conflict", "stage-attachment", `content ${content.contentId} metadata conflicts with its durable retry`);
|
|
@@ -686,31 +702,31 @@ function assertFinalInputStored(connection, input) {
|
|
|
686
702
|
text(header, "core_digest") !== input.runCoreDigest || !bytesEqual(bytes(header, "core_payload"), input.runCoreBytes)) {
|
|
687
703
|
throw (0, errors_ts_1.sqliteError)("record-command-conflict", "finalize-run", `Run ${input.runId} conflicts with committed finalization`);
|
|
688
704
|
}
|
|
689
|
-
const record = (0, database_ts_1.recordStatement)(connection, "SELECT record_payload,record_digest FROM
|
|
705
|
+
const record = (0, database_ts_1.recordStatement)(connection, "SELECT record_payload,record_digest FROM ne19_record_metadata WHERE singleton=1").get();
|
|
690
706
|
if (text(record, "record_digest") !== input.recordCoreDigest || !bytesEqual(bytes(record, "record_payload"), input.recordCoreBytes)) {
|
|
691
707
|
throw (0, errors_ts_1.sqliteError)("record-command-conflict", "finalize-run", "Project RecordDocument conflicts with committed finalization");
|
|
692
708
|
}
|
|
693
|
-
const counts = (0, database_ts_1.recordStatement)(connection, `SELECT (SELECT count(*) FROM
|
|
694
|
-
(SELECT count(*) FROM
|
|
695
|
-
(SELECT count(*) FROM
|
|
709
|
+
const counts = (0, database_ts_1.recordStatement)(connection, `SELECT (SELECT count(*) FROM ne19_slots WHERE run_id=?) slots,
|
|
710
|
+
(SELECT count(*) FROM ne19_attempts WHERE origin_run_id=?) attempts,(SELECT count(*) FROM ne19_members WHERE target_run_id=?) members,
|
|
711
|
+
(SELECT count(*) FROM ne19_attachments WHERE owner_run_id=?) attachments`).get(input.runId, input.runId, input.runId, input.runId);
|
|
696
712
|
if (integer(counts, "slots") !== input.slots.length || integer(counts, "attempts") !== input.attempts.length ||
|
|
697
713
|
integer(counts, "members") !== input.members.length || integer(counts, "attachments") !== input.attachments.length) {
|
|
698
714
|
throw (0, errors_ts_1.sqliteError)("record-command-conflict", "finalize-run", "committed inventory differs from retry input");
|
|
699
715
|
}
|
|
700
716
|
for (const slot of input.slots) {
|
|
701
|
-
const stored = (0, database_ts_1.recordStatement)(connection, "SELECT ordinal,core_payload,core_digest FROM
|
|
717
|
+
const stored = (0, database_ts_1.recordStatement)(connection, "SELECT ordinal,core_payload,core_digest FROM ne19_slots WHERE run_id=? AND slot_id=?").get(input.runId, slot.slotId);
|
|
702
718
|
if (stored === undefined || integer(stored, "ordinal") !== slot.ordinal || text(stored, "core_digest") !== slot.coreDigest || !bytesEqual(bytes(stored, "core_payload"), slot.coreBytes)) {
|
|
703
719
|
throw (0, errors_ts_1.sqliteError)("record-command-conflict", "finalize-run", `Slot ${slot.slotId} conflicts with committed finalization`);
|
|
704
720
|
}
|
|
705
721
|
}
|
|
706
722
|
for (const attempt of input.attempts) {
|
|
707
|
-
const stored = (0, database_ts_1.recordStatement)(connection, "SELECT attempt_locator,core_payload,core_digest FROM
|
|
723
|
+
const stored = (0, database_ts_1.recordStatement)(connection, "SELECT attempt_locator,core_payload,core_digest FROM ne19_attempts WHERE origin_run_id=? AND attempt_id=?").get(input.runId, attempt.attemptId);
|
|
708
724
|
if (stored === undefined || text(stored, "attempt_locator") !== attempt.attemptLocator || text(stored, "core_digest") !== attempt.coreDigest || !bytesEqual(bytes(stored, "core_payload"), attempt.coreBytes)) {
|
|
709
725
|
throw (0, errors_ts_1.sqliteError)("record-command-conflict", "finalize-run", `Attempt ${attempt.attemptId} conflicts with committed finalization`);
|
|
710
726
|
}
|
|
711
727
|
}
|
|
712
728
|
for (const member of input.members) {
|
|
713
|
-
const stored = (0, database_ts_1.recordStatement)(connection, "SELECT origin_run_id,attempt_id,action,core_payload,core_digest FROM
|
|
729
|
+
const stored = (0, database_ts_1.recordStatement)(connection, "SELECT origin_run_id,attempt_id,action,core_payload,core_digest FROM ne19_members WHERE target_run_id=? AND slot_id=?").get(input.runId, member.slotId);
|
|
714
730
|
if (stored === undefined || optionalText(stored, "origin_run_id") !== member.originRunId || optionalText(stored, "attempt_id") !== member.attemptId ||
|
|
715
731
|
text(stored, "action") !== member.action || text(stored, "core_digest") !== member.coreDigest || !bytesEqual(bytes(stored, "core_payload"), member.coreBytes)) {
|
|
716
732
|
throw (0, errors_ts_1.sqliteError)("record-command-conflict", "finalize-run", `Member ${member.slotId} conflicts with committed finalization`);
|
|
@@ -718,7 +734,7 @@ function assertFinalInputStored(connection, input) {
|
|
|
718
734
|
}
|
|
719
735
|
for (const attachment of input.attachments) {
|
|
720
736
|
const stored = (0, database_ts_1.recordStatement)(connection, `SELECT owner_kind,owner_run_id,owner_attempt_id,family,family_revision,logical_identity,canonical_payload,canonical_digest,logical_inventory,inventory_digest
|
|
721
|
-
FROM
|
|
737
|
+
FROM ne19_attachments WHERE attachment_id=? AND owner_run_id=?`).get(attachment.attachmentId, input.runId);
|
|
722
738
|
if (stored === undefined || text(stored, "owner_kind") !== attachment.ownerKind || text(stored, "owner_run_id") !== attachment.ownerRunId ||
|
|
723
739
|
optionalText(stored, "owner_attempt_id") !== attachment.ownerAttemptId || text(stored, "family") !== attachment.family ||
|
|
724
740
|
integer(stored, "family_revision") !== attachment.familyRevision ||
|
|
@@ -727,11 +743,11 @@ function assertFinalInputStored(connection, input) {
|
|
|
727
743
|
!bytesEqual(bytes(stored, "logical_inventory"), attachment.logicalInventoryBytes)) {
|
|
728
744
|
throw (0, errors_ts_1.sqliteError)("record-command-conflict", "finalize-run", `Attachment ${attachment.attachmentId} conflicts with committed finalization`);
|
|
729
745
|
}
|
|
730
|
-
const count = (0, database_ts_1.recordStatement)(connection, "SELECT count(*) AS count FROM
|
|
746
|
+
const count = (0, database_ts_1.recordStatement)(connection, "SELECT count(*) AS count FROM ne19_contents WHERE attachment_id=?").get(attachment.attachmentId);
|
|
731
747
|
if (integer(count, "count") !== attachment.contents.length)
|
|
732
748
|
throw (0, errors_ts_1.sqliteError)("record-command-conflict", "finalize-run", `Attachment ${attachment.attachmentId} Content inventory differs`);
|
|
733
749
|
for (const content of attachment.contents) {
|
|
734
|
-
const persisted = (0, database_ts_1.recordStatement)(connection, "SELECT logical_handle,byte_length,overall_digest,chunk_count FROM
|
|
750
|
+
const persisted = (0, database_ts_1.recordStatement)(connection, "SELECT logical_handle,byte_length,overall_digest,chunk_count FROM ne19_contents WHERE content_id=? AND attachment_id=?")
|
|
735
751
|
.get(content.contentId, attachment.attachmentId);
|
|
736
752
|
if (persisted === undefined || text(persisted, "logical_handle") !== content.logicalHandle || integer(persisted, "byte_length") !== content.byteLength ||
|
|
737
753
|
text(persisted, "overall_digest") !== content.digest || integer(persisted, "chunk_count") !== content.chunkCount) {
|
|
@@ -793,8 +809,8 @@ function stageSealEntries(connection, input) {
|
|
|
793
809
|
if (integer(current, "candidate_seal_staged_count") !== stagedBefore) {
|
|
794
810
|
throw (0, errors_ts_1.sqliteError)("record-command-conflict", "prepare-seal", "Seal staged prefix changed before batch transaction");
|
|
795
811
|
}
|
|
796
|
-
const insert = (0, database_ts_1.recordStatement)(connection, "INSERT OR IGNORE INTO
|
|
797
|
-
const read = (0, database_ts_1.recordStatement)(connection, "SELECT entry_kind,logical_identity,digest FROM
|
|
812
|
+
const insert = (0, database_ts_1.recordStatement)(connection, "INSERT OR IGNORE INTO ne19_run_seal_entries(run_id,ordinal,entry_kind,logical_identity,digest) VALUES (?,?,?,?,?)");
|
|
813
|
+
const read = (0, database_ts_1.recordStatement)(connection, "SELECT entry_kind,logical_identity,digest FROM ne19_run_seal_entries WHERE run_id=? AND ordinal=?");
|
|
798
814
|
batch.forEach((entry, index) => {
|
|
799
815
|
const ordinal = input.startOrdinal + index;
|
|
800
816
|
insert.run(input.runId, ordinal, entry.kind, entry.logicalIdentity, entry.digest);
|
|
@@ -805,7 +821,7 @@ function stageSealEntries(connection, input) {
|
|
|
805
821
|
}
|
|
806
822
|
});
|
|
807
823
|
const next = input.startOrdinal + batch.length;
|
|
808
|
-
const advanced = (0, database_ts_1.recordStatement)(connection, `UPDATE
|
|
824
|
+
const advanced = (0, database_ts_1.recordStatement)(connection, `UPDATE ne19_runs SET candidate_seal_staged_count=?
|
|
809
825
|
WHERE run_id=? AND status='sealing' AND candidate_seal_staged_count=?`).run(Math.max(stagedBefore, next), input.runId, stagedBefore);
|
|
810
826
|
if (Number(advanced.changes) !== 1)
|
|
811
827
|
throw (0, errors_ts_1.sqliteError)("record-command-conflict", "prepare-seal", "Seal staged prefix changed during batch transaction");
|
|
@@ -815,7 +831,7 @@ function stageSealEntries(connection, input) {
|
|
|
815
831
|
}
|
|
816
832
|
/** Reads the durable identity shared by every Run, including after a project move. */
|
|
817
833
|
function readRecordCore(connection) {
|
|
818
|
-
const row = (0, database_ts_1.recordStatement)(connection, "SELECT record_payload,record_digest FROM
|
|
834
|
+
const row = (0, database_ts_1.recordStatement)(connection, "SELECT record_payload,record_digest FROM ne19_record_metadata WHERE singleton=1").get();
|
|
819
835
|
if (row === undefined || row.record_payload === null)
|
|
820
836
|
return undefined;
|
|
821
837
|
const payload = bytes(row, "record_payload");
|
|
@@ -828,14 +844,15 @@ function preserveRecordCore(connection, input) {
|
|
|
828
844
|
throw (0, errors_ts_1.sqliteError)("record-command-conflict", "publish-record-core", "Existing Record identity cannot be replaced");
|
|
829
845
|
}
|
|
830
846
|
if (existing === undefined) {
|
|
831
|
-
(0, database_ts_1.recordStatement)(connection, "UPDATE
|
|
847
|
+
(0, database_ts_1.recordStatement)(connection, "UPDATE ne19_record_metadata SET record_payload=?,record_digest=? WHERE singleton=1").run(input.recordCoreBytes, input.recordCoreDigest);
|
|
832
848
|
}
|
|
833
849
|
}
|
|
834
850
|
/** One bounded transaction that publishes final Core/metadata but not a Seal fence. */
|
|
835
851
|
function stageRunFinalMetadata(connection, input) {
|
|
836
852
|
validateFinalInput(input);
|
|
853
|
+
const experimentId = validatedRunExperimentId(input.runCoreBytes, input.runId);
|
|
837
854
|
const header = runRow(connection, input.runId);
|
|
838
|
-
if (header === undefined || text(header, "writer_generation") !== input.writerGeneration || text(header, "started_at") !== input.startedAt) {
|
|
855
|
+
if (header === undefined || text(header, "experiment_id") !== experimentId || text(header, "writer_generation") !== input.writerGeneration || text(header, "started_at") !== input.startedAt) {
|
|
839
856
|
throw (0, errors_ts_1.sqliteError)("record-command-conflict", "finalize-run", `Run ${input.runId} admission fence is missing or changed`);
|
|
840
857
|
}
|
|
841
858
|
if (text(header, "status") === "open") {
|
|
@@ -844,23 +861,23 @@ function stageRunFinalMetadata(connection, input) {
|
|
|
844
861
|
if (text(current, "status") !== "open")
|
|
845
862
|
throw (0, errors_ts_1.sqliteError)("record-command-conflict", "stage-final-metadata", "Run final metadata fence changed");
|
|
846
863
|
preserveRecordCore(connection, input);
|
|
847
|
-
(0, database_ts_1.recordStatement)(connection, "UPDATE
|
|
864
|
+
(0, database_ts_1.recordStatement)(connection, "UPDATE ne19_runs SET core_payload=?,core_digest=? WHERE run_id=? AND status='open'").run(input.runCoreBytes, input.runCoreDigest, input.runId);
|
|
848
865
|
for (const slot of input.slots)
|
|
849
|
-
(0, database_ts_1.recordStatement)(connection, "INSERT OR IGNORE INTO
|
|
866
|
+
(0, database_ts_1.recordStatement)(connection, "INSERT OR IGNORE INTO ne19_slots(run_id,slot_id,ordinal,core_payload,core_digest) VALUES (?,?,?,?,?)").run(input.runId, slot.slotId, slot.ordinal, slot.coreBytes, slot.coreDigest);
|
|
850
867
|
for (const attempt of input.attempts)
|
|
851
|
-
(0, database_ts_1.recordStatement)(connection, "UPDATE
|
|
868
|
+
(0, database_ts_1.recordStatement)(connection, "UPDATE ne19_attempts SET core_payload=?,core_digest=? WHERE origin_run_id=? AND attempt_id=?").run(attempt.coreBytes, attempt.coreDigest, input.runId, attempt.attemptId);
|
|
852
869
|
for (const member of input.members)
|
|
853
|
-
(0, database_ts_1.recordStatement)(connection, "INSERT OR REPLACE INTO
|
|
870
|
+
(0, database_ts_1.recordStatement)(connection, "INSERT OR REPLACE INTO ne19_members(target_run_id,slot_id,origin_run_id,attempt_id,action,core_payload,core_digest) VALUES (?,?,?,?,?,?,?)")
|
|
854
871
|
.run(input.runId, member.slotId, member.originRunId ?? null, member.attemptId ?? null, member.action, member.coreBytes, member.coreDigest);
|
|
855
872
|
for (const attachment of input.attachments) {
|
|
856
|
-
(0, database_ts_1.recordStatement)(connection, `UPDATE
|
|
873
|
+
(0, database_ts_1.recordStatement)(connection, `UPDATE ne19_attachments SET logical_identity=?,canonical_payload=?,canonical_digest=?,logical_inventory=?,inventory_digest=?
|
|
857
874
|
WHERE attachment_id=? AND owner_run_id=? AND NOT (owner_kind='attempt' AND EXISTS
|
|
858
|
-
(SELECT 1 FROM
|
|
875
|
+
(SELECT 1 FROM ne19_attempts WHERE origin_run_id=ne19_attachments.owner_run_id AND attempt_id=ne19_attachments.owner_attempt_id AND publication_state='published'))`).run(attachment.logicalIdentity, attachment.canonicalBytes, attachment.canonicalDigest, attachment.logicalInventoryBytes, attachment.inventoryDigest, attachment.attachmentId, input.runId);
|
|
859
876
|
for (const content of attachment.contents)
|
|
860
|
-
(0, database_ts_1.recordStatement)(connection, `UPDATE
|
|
861
|
-
WHERE content_id=? AND attachment_id=? AND NOT EXISTS (SELECT 1 FROM
|
|
877
|
+
(0, database_ts_1.recordStatement)(connection, `UPDATE ne19_contents SET byte_length=?,overall_digest=?,chunk_count=?
|
|
878
|
+
WHERE content_id=? AND attachment_id=? AND NOT EXISTS (SELECT 1 FROM ne19_attachments a JOIN ne19_attempts at
|
|
862
879
|
ON at.origin_run_id=a.owner_run_id AND at.attempt_id=a.owner_attempt_id
|
|
863
|
-
WHERE a.attachment_id=
|
|
880
|
+
WHERE a.attachment_id=ne19_contents.attachment_id AND a.owner_kind='attempt' AND at.publication_state='published')`)
|
|
864
881
|
.run(content.byteLength, content.digest, content.chunkCount, content.contentId, attachment.attachmentId);
|
|
865
882
|
}
|
|
866
883
|
bumpMutationSequence(connection, input.runId);
|
|
@@ -879,25 +896,25 @@ function stageRunPublicationMetadata(connection, input) {
|
|
|
879
896
|
(0, transaction_ts_1.withImmediateTransaction)(connection, input.deadlineEpochMs, "publish-attempt-metadata", () => {
|
|
880
897
|
assertRunFence(connection, input.runId, input.writerGeneration, "publish-attempt-metadata");
|
|
881
898
|
preserveRecordCore(connection, input);
|
|
882
|
-
(0, database_ts_1.recordStatement)(connection, "UPDATE
|
|
899
|
+
(0, database_ts_1.recordStatement)(connection, "UPDATE ne19_runs SET core_payload=?,core_digest=? WHERE run_id=? AND status='open'").run(input.runCoreBytes, input.runCoreDigest, input.runId);
|
|
883
900
|
for (const slot of input.slots)
|
|
884
|
-
(0, database_ts_1.recordStatement)(connection, "INSERT OR REPLACE INTO
|
|
901
|
+
(0, database_ts_1.recordStatement)(connection, "INSERT OR REPLACE INTO ne19_slots(run_id,slot_id,ordinal,core_payload,core_digest) VALUES (?,?,?,?,?)").run(input.runId, slot.slotId, slot.ordinal, slot.coreBytes, slot.coreDigest);
|
|
885
902
|
for (const attempt of input.attempts)
|
|
886
|
-
(0, database_ts_1.recordStatement)(connection, `UPDATE
|
|
903
|
+
(0, database_ts_1.recordStatement)(connection, `UPDATE ne19_attempts SET core_payload=?,core_digest=?,
|
|
887
904
|
publication_state=CASE WHEN publication_state='staging' THEN 'sealing' ELSE publication_state END
|
|
888
905
|
WHERE origin_run_id=? AND attempt_id=?`).run(attempt.coreBytes, attempt.coreDigest, input.runId, attempt.attemptId);
|
|
889
906
|
for (const member of input.members)
|
|
890
|
-
(0, database_ts_1.recordStatement)(connection, "INSERT OR REPLACE INTO
|
|
907
|
+
(0, database_ts_1.recordStatement)(connection, "INSERT OR REPLACE INTO ne19_members(target_run_id,slot_id,origin_run_id,attempt_id,action,core_payload,core_digest) VALUES (?,?,?,?,?,?,?)")
|
|
891
908
|
.run(input.runId, member.slotId, member.originRunId ?? null, member.attemptId ?? null, member.action, member.coreBytes, member.coreDigest);
|
|
892
909
|
for (const attachment of input.attachments) {
|
|
893
|
-
(0, database_ts_1.recordStatement)(connection, `UPDATE
|
|
910
|
+
(0, database_ts_1.recordStatement)(connection, `UPDATE ne19_attachments SET logical_identity=?,canonical_payload=?,canonical_digest=?,logical_inventory=?,inventory_digest=?
|
|
894
911
|
WHERE attachment_id=? AND owner_run_id=? AND NOT (owner_kind='attempt' AND EXISTS
|
|
895
|
-
(SELECT 1 FROM
|
|
912
|
+
(SELECT 1 FROM ne19_attempts WHERE origin_run_id=ne19_attachments.owner_run_id AND attempt_id=ne19_attachments.owner_attempt_id AND publication_state='published'))`).run(attachment.logicalIdentity, attachment.canonicalBytes, attachment.canonicalDigest, attachment.logicalInventoryBytes, attachment.inventoryDigest, attachment.attachmentId, input.runId);
|
|
896
913
|
for (const content of attachment.contents)
|
|
897
|
-
(0, database_ts_1.recordStatement)(connection, `UPDATE
|
|
898
|
-
WHERE content_id=? AND attachment_id=? AND NOT EXISTS (SELECT 1 FROM
|
|
914
|
+
(0, database_ts_1.recordStatement)(connection, `UPDATE ne19_contents SET byte_length=?,overall_digest=?,chunk_count=?
|
|
915
|
+
WHERE content_id=? AND attachment_id=? AND NOT EXISTS (SELECT 1 FROM ne19_attachments a JOIN ne19_attempts at
|
|
899
916
|
ON at.origin_run_id=a.owner_run_id AND at.attempt_id=a.owner_attempt_id
|
|
900
|
-
WHERE a.attachment_id=
|
|
917
|
+
WHERE a.attachment_id=ne19_contents.attachment_id AND a.owner_kind='attempt' AND at.publication_state='published')`)
|
|
901
918
|
.run(content.byteLength, content.digest, content.chunkCount, content.contentId, attachment.attachmentId);
|
|
902
919
|
}
|
|
903
920
|
bumpMutationSequence(connection, input.runId);
|
|
@@ -953,7 +970,7 @@ function fenceRunFinalization(connection, input) {
|
|
|
953
970
|
if (text(before, "status") === "open") {
|
|
954
971
|
(0, transaction_ts_1.withImmediateTransaction)(connection, input.deadlineEpochMs, "fence-finalization", () => {
|
|
955
972
|
assertRunFence(connection, input.runId, input.writerGeneration, "fence-finalization");
|
|
956
|
-
const changed = (0, database_ts_1.recordStatement)(connection, `UPDATE
|
|
973
|
+
const changed = (0, database_ts_1.recordStatement)(connection, `UPDATE ne19_runs SET status='sealing',candidate_seal_identity=?,candidate_seal_entry_count=?
|
|
957
974
|
WHERE run_id=? AND status='open' AND writer_generation=? AND mutation_sequence=?`).run(input.expectedLogicalSealIdentity, input.expectedSealEntryCount, input.runId, input.writerGeneration, input.mutationSequence);
|
|
958
975
|
if (Number(changed.changes) !== 1)
|
|
959
976
|
throw (0, errors_ts_1.sqliteError)("record-command-conflict", "fence-finalization", "Run staging changed before finalization fence");
|
|
@@ -988,13 +1005,13 @@ function stageAttachmentReferences(connection, input) {
|
|
|
988
1005
|
assertAttachmentFence(connection, input.runId, input.attachmentId, "stage-references");
|
|
989
1006
|
let changed = false;
|
|
990
1007
|
for (const reference of input.references) {
|
|
991
|
-
const stored = (0, database_ts_1.recordStatement)(connection, `SELECT target_owner_kind,target_family,canonical_payload,reference_digest FROM
|
|
1008
|
+
const stored = (0, database_ts_1.recordStatement)(connection, `SELECT target_owner_kind,target_family,canonical_payload,reference_digest FROM ne19_attachment_references
|
|
992
1009
|
WHERE attachment_id=? AND ordinal=?`).get(input.attachmentId, reference.ordinal);
|
|
993
1010
|
if (stored === undefined) {
|
|
994
|
-
const count = (0, database_ts_1.recordStatement)(connection, "SELECT count(*) AS count FROM
|
|
1011
|
+
const count = (0, database_ts_1.recordStatement)(connection, "SELECT count(*) AS count FROM ne19_attachment_references WHERE attachment_id=?").get(input.attachmentId);
|
|
995
1012
|
if (reference.ordinal !== integer(count, "count"))
|
|
996
1013
|
throw (0, errors_ts_1.sqliteError)("record-command-conflict", "stage-references", "reference batch does not extend the committed prefix");
|
|
997
|
-
(0, database_ts_1.recordStatement)(connection, `INSERT INTO
|
|
1014
|
+
(0, database_ts_1.recordStatement)(connection, `INSERT INTO ne19_attachment_references(attachment_id,ordinal,target_owner_kind,target_family,canonical_payload,reference_digest)
|
|
998
1015
|
VALUES (?,?,?,?,?,?)`).run(input.attachmentId, reference.ordinal, reference.owner, reference.family, reference.canonicalBytes, reference.referenceDigest);
|
|
999
1016
|
changed = true;
|
|
1000
1017
|
}
|
|
@@ -1020,15 +1037,19 @@ function stageCollectionItems(connection, input) {
|
|
|
1020
1037
|
assertRunFence(connection, input.runId, input.writerGeneration, "stage-collection-items");
|
|
1021
1038
|
assertAttachmentFence(connection, input.runId, input.attachmentId, "stage-collection-items");
|
|
1022
1039
|
let changed = false;
|
|
1040
|
+
// The immediate transaction owns this prefix until commit. Counting for
|
|
1041
|
+
// every appended item rescans a growing collection quadratically.
|
|
1042
|
+
const count = (0, database_ts_1.recordStatement)(connection, "SELECT count(*) AS count FROM ne19_collection_items WHERE attachment_id=?").get(input.attachmentId);
|
|
1043
|
+
let nextOrdinal = integer(count, "count");
|
|
1023
1044
|
for (const item of input.items) {
|
|
1024
|
-
const stored = (0, database_ts_1.recordStatement)(connection, `SELECT logical_identity,canonical_payload,canonical_digest FROM
|
|
1045
|
+
const stored = (0, database_ts_1.recordStatement)(connection, `SELECT logical_identity,canonical_payload,canonical_digest FROM ne19_collection_items
|
|
1025
1046
|
WHERE attachment_id=? AND ordinal=?`).get(input.attachmentId, item.ordinal);
|
|
1026
1047
|
if (stored === undefined) {
|
|
1027
|
-
|
|
1028
|
-
if (item.ordinal !== integer(count, "count"))
|
|
1048
|
+
if (item.ordinal !== nextOrdinal)
|
|
1029
1049
|
throw (0, errors_ts_1.sqliteError)("record-command-conflict", "stage-collection-items", "collection batch does not extend the committed prefix");
|
|
1030
|
-
(0, database_ts_1.recordStatement)(connection, `INSERT INTO
|
|
1050
|
+
(0, database_ts_1.recordStatement)(connection, `INSERT INTO ne19_collection_items(attachment_id,ordinal,logical_identity,canonical_payload,canonical_digest)
|
|
1031
1051
|
VALUES (?,?,?,?,?)`).run(input.attachmentId, item.ordinal, item.logicalIdentity, item.canonicalBytes, item.canonicalDigest);
|
|
1052
|
+
nextOrdinal += 1;
|
|
1032
1053
|
changed = true;
|
|
1033
1054
|
}
|
|
1034
1055
|
else if (text(stored, "logical_identity") !== item.logicalIdentity || text(stored, "canonical_digest") !== item.canonicalDigest ||
|
|
@@ -1095,13 +1116,13 @@ function assertSealedRetryExact(connection, input) {
|
|
|
1095
1116
|
});
|
|
1096
1117
|
for (const attachment of input.attachments) {
|
|
1097
1118
|
const counts = (0, database_ts_1.recordStatement)(connection, `SELECT
|
|
1098
|
-
(SELECT count(*) FROM
|
|
1099
|
-
(SELECT count(*) FROM
|
|
1119
|
+
(SELECT count(*) FROM ne19_attachment_references WHERE attachment_id=?) reference_count,
|
|
1120
|
+
(SELECT count(*) FROM ne19_collection_items WHERE attachment_id=?) item_count`).get(attachment.attachmentId, attachment.attachmentId);
|
|
1100
1121
|
if (integer(counts, "reference_count") !== attachment.references.length || integer(counts, "item_count") !== attachment.collectionItems.length) {
|
|
1101
1122
|
throw (0, errors_ts_1.sqliteError)("record-command-conflict", "persist-sealed-run", `Attachment ${attachment.attachmentId} retry inventory differs`);
|
|
1102
1123
|
}
|
|
1103
1124
|
for (const reference of attachment.references) {
|
|
1104
|
-
const row = (0, database_ts_1.recordStatement)(connection, `SELECT target_owner_kind,target_family,canonical_payload,reference_digest FROM
|
|
1125
|
+
const row = (0, database_ts_1.recordStatement)(connection, `SELECT target_owner_kind,target_family,canonical_payload,reference_digest FROM ne19_attachment_references
|
|
1105
1126
|
WHERE attachment_id=? AND ordinal=?`).get(attachment.attachmentId, reference.ordinal);
|
|
1106
1127
|
if (row === undefined || ownerKind(row, "target_owner_kind") !== reference.owner || text(row, "target_family") !== reference.family ||
|
|
1107
1128
|
text(row, "reference_digest") !== reference.referenceDigest || !bytesEqual(bytes(row, "canonical_payload"), reference.canonicalBytes)) {
|
|
@@ -1109,7 +1130,7 @@ function assertSealedRetryExact(connection, input) {
|
|
|
1109
1130
|
}
|
|
1110
1131
|
}
|
|
1111
1132
|
for (const item of attachment.collectionItems) {
|
|
1112
|
-
const row = (0, database_ts_1.recordStatement)(connection, `SELECT logical_identity,canonical_payload,canonical_digest FROM
|
|
1133
|
+
const row = (0, database_ts_1.recordStatement)(connection, `SELECT logical_identity,canonical_payload,canonical_digest FROM ne19_collection_items
|
|
1113
1134
|
WHERE attachment_id=? AND ordinal=?`).get(attachment.attachmentId, item.ordinal);
|
|
1114
1135
|
if (row === undefined || text(row, "logical_identity") !== item.logicalIdentity || text(row, "canonical_digest") !== item.canonicalDigest ||
|
|
1115
1136
|
!bytesEqual(bytes(row, "canonical_payload"), item.canonicalBytes)) {
|
|
@@ -1117,11 +1138,11 @@ function assertSealedRetryExact(connection, input) {
|
|
|
1117
1138
|
}
|
|
1118
1139
|
}
|
|
1119
1140
|
for (const content of attachment.contents) {
|
|
1120
|
-
const count = (0, database_ts_1.recordStatement)(connection, "SELECT count(*) AS count FROM
|
|
1141
|
+
const count = (0, database_ts_1.recordStatement)(connection, "SELECT count(*) AS count FROM ne19_content_chunks WHERE content_id=?").get(content.contentId);
|
|
1121
1142
|
if (integer(count, "count") !== content.chunks.length)
|
|
1122
1143
|
throw (0, errors_ts_1.sqliteError)("record-command-conflict", "persist-sealed-run", `Content ${content.contentId} retry chunk count differs`);
|
|
1123
1144
|
for (const chunk of content.chunks) {
|
|
1124
|
-
const row = (0, database_ts_1.recordStatement)(connection, "SELECT bytes,chunk_digest FROM
|
|
1145
|
+
const row = (0, database_ts_1.recordStatement)(connection, "SELECT bytes,chunk_digest FROM ne19_content_chunks WHERE content_id=? AND ordinal=?")
|
|
1125
1146
|
.get(content.contentId, chunk.ordinal);
|
|
1126
1147
|
if (row === undefined || text(row, "chunk_digest") !== chunk.chunkDigest || !bytesEqual(bytes(row, "bytes"), chunk.bytes)) {
|
|
1127
1148
|
throw (0, errors_ts_1.sqliteError)("record-command-conflict", "persist-sealed-run", `Content chunk ${content.contentId}/${chunk.ordinal} retry differs`);
|
|
@@ -1146,7 +1167,7 @@ function persistSealedRun(connection, input) {
|
|
|
1146
1167
|
verifyStoredSeal(connection, input.runId, expectedEntries, expectedIdentity);
|
|
1147
1168
|
return readSealedRunSummary(connection, input.runId);
|
|
1148
1169
|
}
|
|
1149
|
-
beginRun(connection, input);
|
|
1170
|
+
beginRun(connection, { ...input, experimentId: validatedRunExperimentId(input.runCoreBytes, input.runId) });
|
|
1150
1171
|
for (const attempt of input.attempts)
|
|
1151
1172
|
admitAttempt(connection, {
|
|
1152
1173
|
runId: input.runId,
|
|
@@ -1264,7 +1285,7 @@ function publishRunSeal(connection, input) {
|
|
|
1264
1285
|
throw (0, errors_ts_1.sqliteError)("record-seal-incomplete", "seal-run", "Seal candidate inventory is not completely staged");
|
|
1265
1286
|
}
|
|
1266
1287
|
(0, transaction_ts_1.withImmediateTransaction)(connection, input.deadlineEpochMs, "seal-run", () => {
|
|
1267
|
-
const changed = (0, database_ts_1.recordStatement)(connection, `UPDATE
|
|
1288
|
+
const changed = (0, database_ts_1.recordStatement)(connection, `UPDATE ne19_runs SET status='sealed',logical_seal_identity=?
|
|
1268
1289
|
WHERE run_id=? AND status='sealing' AND writer_generation=? AND candidate_seal_identity=?
|
|
1269
1290
|
AND candidate_seal_staged_count=candidate_seal_entry_count`).run(input.expectedLogicalSealIdentity, input.runId, input.writerGeneration, input.expectedLogicalSealIdentity);
|
|
1270
1291
|
if (Number(changed.changes) !== 1)
|
|
@@ -1283,7 +1304,7 @@ function verifyStoredSealStreaming(connection, runId, identity, expectedCount) {
|
|
|
1283
1304
|
if (actual.count !== expectedCount || actual.identity !== identity) {
|
|
1284
1305
|
throw (0, errors_ts_1.sqliteError)("record-seal-incomplete", "verify-seal", `Run ${runId} exact Seal identity or count differs from its closure`);
|
|
1285
1306
|
}
|
|
1286
|
-
const statement = (0, database_ts_1.recordStatement)(connection, `SELECT entry_kind,logical_identity,digest FROM
|
|
1307
|
+
const statement = (0, database_ts_1.recordStatement)(connection, `SELECT entry_kind,logical_identity,digest FROM ne19_run_seal_entries
|
|
1287
1308
|
WHERE run_id=? AND ordinal=?`);
|
|
1288
1309
|
let ordinal = 0;
|
|
1289
1310
|
for (const row of (0, database_ts_1.recordStatement)(connection, `SELECT ordinal,entry_kind,logical_identity,digest
|
|
@@ -1303,7 +1324,7 @@ function verifyStoredSealStreaming(connection, runId, identity, expectedCount) {
|
|
|
1303
1324
|
}
|
|
1304
1325
|
ordinal += 1;
|
|
1305
1326
|
}
|
|
1306
|
-
const storedCount = (0, database_ts_1.recordStatement)(connection, "SELECT count(*) AS count FROM
|
|
1327
|
+
const storedCount = (0, database_ts_1.recordStatement)(connection, "SELECT count(*) AS count FROM ne19_run_seal_entries WHERE run_id=?").get(runId);
|
|
1307
1328
|
if (ordinal !== expectedCount || integer(storedCount, "count") !== ordinal) {
|
|
1308
1329
|
throw (0, errors_ts_1.sqliteError)("record-seal-incomplete", "verify-seal", `Run ${runId} exact Seal does not match its closure`);
|
|
1309
1330
|
}
|
|
@@ -1327,10 +1348,10 @@ function verifyAllSealedRuns(connection, requireSealedOnly = false, deadlineEpoc
|
|
|
1327
1348
|
};
|
|
1328
1349
|
checkDeadline();
|
|
1329
1350
|
const admission = (0, database_ts_1.recordStatement)(connection, `SELECT
|
|
1330
|
-
(SELECT count(*) FROM
|
|
1331
|
-
(SELECT count(*) FROM
|
|
1332
|
-
(SELECT count(*) FROM
|
|
1333
|
-
(SELECT count(*) FROM
|
|
1351
|
+
(SELECT count(*) FROM ne19_runs) run_count,
|
|
1352
|
+
(SELECT count(*) FROM ne19_runs)+(SELECT count(*) FROM ne19_slots)+(SELECT count(*) FROM ne19_attempts)+(SELECT count(*) FROM ne19_members)+
|
|
1353
|
+
(SELECT count(*) FROM ne19_attachments)+(SELECT count(*) FROM ne19_attachment_references)+(SELECT count(*) FROM ne19_collection_items)+
|
|
1354
|
+
(SELECT count(*) FROM ne19_contents)+(SELECT count(*) FROM ne19_content_chunks)+(SELECT count(*) FROM ne19_run_seal_entries) row_count`).get();
|
|
1334
1355
|
if (integer(admission, "run_count") > types_ts_1.RECORD_SQLITE_MAX_VALIDATION_RUNS || integer(admission, "row_count") > types_ts_1.RECORD_SQLITE_MAX_VALIDATION_ROWS) {
|
|
1335
1356
|
throw (0, errors_ts_1.sqliteError)("record-resource-limit-exceeded", "verify-database", "Record validation inventory exceeds its hostile-input ceiling");
|
|
1336
1357
|
}
|
|
@@ -1342,7 +1363,7 @@ function verifyAllSealedRuns(connection, requireSealedOnly = false, deadlineEpoc
|
|
|
1342
1363
|
const foreignKeys = (0, database_ts_1.recordStatement)(connection, "PRAGMA foreign_key_check").all();
|
|
1343
1364
|
if (foreignKeys.length !== 0)
|
|
1344
1365
|
throw (0, errors_ts_1.sqliteError)("record-database-invalid", "verify-database", "foreign key check failed");
|
|
1345
|
-
const runRows = (0, database_ts_1.recordStatement)(connection, "SELECT run_id,status,logical_seal_identity FROM
|
|
1366
|
+
const runRows = (0, database_ts_1.recordStatement)(connection, "SELECT run_id,status,logical_seal_identity FROM ne19_runs ORDER BY run_id")
|
|
1346
1367
|
.iterate();
|
|
1347
1368
|
let sealed = 0;
|
|
1348
1369
|
for (const row of runRows) {
|
|
@@ -1365,7 +1386,7 @@ function verifyAllSealedRuns(connection, requireSealedOnly = false, deadlineEpoc
|
|
|
1365
1386
|
return sealed;
|
|
1366
1387
|
}
|
|
1367
1388
|
function verifyRunPayloadClosures(connection, runId, verifyPayloadBytes = true) {
|
|
1368
|
-
const attempts = (0, database_ts_1.recordStatement)(connection, "SELECT attempt_id,attempt_locator FROM
|
|
1389
|
+
const attempts = (0, database_ts_1.recordStatement)(connection, "SELECT attempt_id,attempt_locator FROM ne19_attempts WHERE origin_run_id=?")
|
|
1369
1390
|
.iterate(runId);
|
|
1370
1391
|
for (const attempt of attempts) {
|
|
1371
1392
|
const attemptId = text(attempt, "attempt_id");
|
|
@@ -1378,7 +1399,7 @@ function verifyRunPayloadClosures(connection, runId, verifyPayloadBytes = true)
|
|
|
1378
1399
|
}
|
|
1379
1400
|
}
|
|
1380
1401
|
const attachments = (0, database_ts_1.recordStatement)(connection, `SELECT attachment_id,owner_kind,owner_run_id,owner_attempt_id,family,family_revision,
|
|
1381
|
-
logical_identity,canonical_digest,logical_inventory,inventory_digest FROM
|
|
1402
|
+
logical_identity,canonical_digest,logical_inventory,inventory_digest FROM ne19_attachments WHERE owner_run_id=?`)
|
|
1382
1403
|
.iterate(runId);
|
|
1383
1404
|
for (const attachment of attachments) {
|
|
1384
1405
|
const attachmentId = text(attachment, "attachment_id");
|
|
@@ -1397,8 +1418,8 @@ function verifyRunPayloadClosures(connection, runId, verifyPayloadBytes = true)
|
|
|
1397
1418
|
throw (0, errors_ts_1.sqliteError)("record-seal-incomplete", "verify-seal", `attachment ${attachmentId} logical identity is invalid`);
|
|
1398
1419
|
}
|
|
1399
1420
|
for (const [label, counts] of [
|
|
1400
|
-
["reference", (0, database_ts_1.recordStatement)(connection, "SELECT count(*) AS count,min(ordinal) AS minimum,max(ordinal) AS maximum FROM
|
|
1401
|
-
["collection item", (0, database_ts_1.recordStatement)(connection, "SELECT count(*) AS count,min(ordinal) AS minimum,max(ordinal) AS maximum FROM
|
|
1421
|
+
["reference", (0, database_ts_1.recordStatement)(connection, "SELECT count(*) AS count,min(ordinal) AS minimum,max(ordinal) AS maximum FROM ne19_attachment_references WHERE attachment_id=?").get(attachmentId)],
|
|
1422
|
+
["collection item", (0, database_ts_1.recordStatement)(connection, "SELECT count(*) AS count,min(ordinal) AS minimum,max(ordinal) AS maximum FROM ne19_collection_items WHERE attachment_id=?").get(attachmentId)],
|
|
1402
1423
|
]) {
|
|
1403
1424
|
const decoded = counts;
|
|
1404
1425
|
const count = integer(decoded, "count");
|
|
@@ -1407,8 +1428,8 @@ function verifyRunPayloadClosures(connection, runId, verifyPayloadBytes = true)
|
|
|
1407
1428
|
}
|
|
1408
1429
|
}
|
|
1409
1430
|
}
|
|
1410
|
-
const items = (0, database_ts_1.recordStatement)(connection, `SELECT i.attachment_id,i.ordinal,i.logical_identity,i.canonical_digest FROM
|
|
1411
|
-
JOIN
|
|
1431
|
+
const items = (0, database_ts_1.recordStatement)(connection, `SELECT i.attachment_id,i.ordinal,i.logical_identity,i.canonical_digest FROM ne19_collection_items i
|
|
1432
|
+
JOIN ne19_attachments a ON a.attachment_id=i.attachment_id WHERE a.owner_run_id=?`).iterate(runId);
|
|
1412
1433
|
for (const item of items) {
|
|
1413
1434
|
const expected = (0, seal_ts_1.collectionItemLogicalIdentity)(integer(item, "ordinal"), text(item, "canonical_digest"));
|
|
1414
1435
|
if (text(item, "logical_identity") !== expected) {
|
|
@@ -1416,16 +1437,16 @@ function verifyRunPayloadClosures(connection, runId, verifyPayloadBytes = true)
|
|
|
1416
1437
|
}
|
|
1417
1438
|
}
|
|
1418
1439
|
const coverage = (0, database_ts_1.recordStatement)(connection, `SELECT
|
|
1419
|
-
(SELECT count(*) FROM
|
|
1420
|
-
(SELECT count(*) FROM
|
|
1421
|
-
(SELECT count(*) FROM
|
|
1440
|
+
(SELECT count(*) FROM ne19_slots WHERE run_id=?) slot_count,
|
|
1441
|
+
(SELECT count(*) FROM ne19_members WHERE target_run_id=?) member_count,
|
|
1442
|
+
(SELECT count(*) FROM ne19_slots s LEFT JOIN ne19_members m ON m.target_run_id=s.run_id AND m.slot_id=s.slot_id
|
|
1422
1443
|
WHERE s.run_id=? AND m.slot_id IS NULL) missing_count`).get(runId, runId, runId);
|
|
1423
1444
|
if (integer(coverage, "slot_count") !== integer(coverage, "member_count") || integer(coverage, "missing_count") !== 0) {
|
|
1424
1445
|
throw (0, errors_ts_1.sqliteError)("record-seal-incomplete", "verify-seal", `Run ${runId} does not have exactly one Member per Slot`);
|
|
1425
1446
|
}
|
|
1426
1447
|
const references = (0, database_ts_1.recordStatement)(connection, `SELECT r.attachment_id,r.ordinal,r.target_owner_kind,r.target_family,
|
|
1427
|
-
a.owner_kind source_owner_kind,a.owner_run_id,a.owner_attempt_id FROM
|
|
1428
|
-
JOIN
|
|
1448
|
+
a.owner_kind source_owner_kind,a.owner_run_id,a.owner_attempt_id FROM ne19_attachment_references r
|
|
1449
|
+
JOIN ne19_attachments a ON a.attachment_id=r.attachment_id WHERE a.owner_run_id=?`).iterate(runId);
|
|
1429
1450
|
for (const reference of references) {
|
|
1430
1451
|
const targetOwner = text(reference, "target_owner_kind");
|
|
1431
1452
|
const sourceOwner = text(reference, "source_owner_kind");
|
|
@@ -1433,16 +1454,16 @@ function verifyRunPayloadClosures(connection, runId, verifyPayloadBytes = true)
|
|
|
1433
1454
|
throw (0, errors_ts_1.sqliteError)("record-seal-incomplete", "verify-seal", `run-owned attachment ${text(reference, "attachment_id")} cannot resolve an attempt reference`);
|
|
1434
1455
|
}
|
|
1435
1456
|
const target = targetOwner === "run"
|
|
1436
|
-
? (0, database_ts_1.recordStatement)(connection, `SELECT count(*) AS count FROM
|
|
1457
|
+
? (0, database_ts_1.recordStatement)(connection, `SELECT count(*) AS count FROM ne19_attachments WHERE owner_kind='run' AND owner_run_id=? AND family=?`)
|
|
1437
1458
|
.get(text(reference, "owner_run_id"), text(reference, "target_family"))
|
|
1438
|
-
: (0, database_ts_1.recordStatement)(connection, `SELECT count(*) AS count FROM
|
|
1459
|
+
: (0, database_ts_1.recordStatement)(connection, `SELECT count(*) AS count FROM ne19_attachments WHERE owner_kind='attempt' AND owner_run_id=? AND owner_attempt_id=? AND family=?`)
|
|
1439
1460
|
.get(text(reference, "owner_run_id"), text(reference, "owner_attempt_id"), text(reference, "target_family"));
|
|
1440
1461
|
if (integer(target, "count") !== 1) {
|
|
1441
1462
|
throw (0, errors_ts_1.sqliteError)("record-seal-incomplete", "verify-seal", `reference ${text(reference, "attachment_id")}/${integer(reference, "ordinal")} target family is missing`);
|
|
1442
1463
|
}
|
|
1443
1464
|
}
|
|
1444
|
-
const contents = (0, database_ts_1.recordStatement)(connection, `SELECT c.content_id,c.attachment_id,c.logical_handle,c.byte_length,c.overall_digest,c.chunk_count FROM
|
|
1445
|
-
JOIN
|
|
1465
|
+
const contents = (0, database_ts_1.recordStatement)(connection, `SELECT c.content_id,c.attachment_id,c.logical_handle,c.byte_length,c.overall_digest,c.chunk_count FROM ne19_contents c
|
|
1466
|
+
JOIN ne19_attachments a ON a.attachment_id=c.attachment_id WHERE a.owner_run_id=?`).iterate(runId);
|
|
1446
1467
|
for (const content of contents) {
|
|
1447
1468
|
const contentId = text(content, "content_id");
|
|
1448
1469
|
const expectedContentId = (0, seal_ts_1.contentId)(text(content, "attachment_id"), text(content, "logical_handle"));
|
|
@@ -1452,7 +1473,7 @@ function verifyRunPayloadClosures(connection, runId, verifyPayloadBytes = true)
|
|
|
1452
1473
|
const hash = (0, node_crypto_1.createHash)("sha256");
|
|
1453
1474
|
let byteLength = 0;
|
|
1454
1475
|
let ordinal = 0;
|
|
1455
|
-
const chunks = (0, database_ts_1.recordStatement)(connection, "SELECT ordinal,bytes,chunk_digest FROM
|
|
1476
|
+
const chunks = (0, database_ts_1.recordStatement)(connection, "SELECT ordinal,bytes,chunk_digest FROM ne19_content_chunks WHERE content_id=? ORDER BY ordinal")
|
|
1456
1477
|
.iterate(contentId);
|
|
1457
1478
|
for (const chunk of chunks) {
|
|
1458
1479
|
if (integer(chunk, "ordinal") !== ordinal)
|
|
@@ -1470,13 +1491,13 @@ function verifyRunPayloadClosures(connection, runId, verifyPayloadBytes = true)
|
|
|
1470
1491
|
}
|
|
1471
1492
|
else {
|
|
1472
1493
|
const aggregate = (0, database_ts_1.recordStatement)(connection, `SELECT count(*) AS count,min(ordinal) AS minimum,max(ordinal) AS maximum,
|
|
1473
|
-
coalesce(sum(length(bytes)),0) AS byte_length FROM
|
|
1494
|
+
coalesce(sum(length(bytes)),0) AS byte_length FROM ne19_content_chunks WHERE content_id=?`).get(contentId);
|
|
1474
1495
|
const chunkCount = integer(content, "chunk_count");
|
|
1475
1496
|
if (integer(aggregate, "count") !== chunkCount || integer(aggregate, "byte_length") !== integer(content, "byte_length") ||
|
|
1476
1497
|
(chunkCount > 0 && (optionalInteger(aggregate, "minimum") !== 0 || optionalInteger(aggregate, "maximum") !== chunkCount - 1))) {
|
|
1477
1498
|
throw (0, errors_ts_1.sqliteError)("record-seal-incomplete", "verify-seal", `content ${contentId} durable chunk closure is invalid`);
|
|
1478
1499
|
}
|
|
1479
|
-
for (const chunk of (0, database_ts_1.recordStatement)(connection, "SELECT chunk_digest FROM
|
|
1500
|
+
for (const chunk of (0, database_ts_1.recordStatement)(connection, "SELECT chunk_digest FROM ne19_content_chunks WHERE content_id=?").iterate(contentId)) {
|
|
1480
1501
|
requireDigest(text(chunk, "chunk_digest"), `content ${contentId} chunk digest`);
|
|
1481
1502
|
}
|
|
1482
1503
|
}
|
|
@@ -1486,30 +1507,30 @@ function verifyRunPayloadClosures(connection, runId, verifyPayloadBytes = true)
|
|
|
1486
1507
|
function readSealedRunSummary(connection, runId) {
|
|
1487
1508
|
const row = (0, database_ts_1.recordStatement)(connection, `SELECT r.run_id,r.writer_generation,r.started_at,
|
|
1488
1509
|
coalesce(r.logical_seal_identity,'published:' || (SELECT max(p.published_revision)
|
|
1489
|
-
FROM
|
|
1490
|
-
(SELECT count(*) FROM
|
|
1491
|
-
CASE WHEN EXISTS (SELECT 1 FROM
|
|
1492
|
-
(SELECT count(*) FROM
|
|
1493
|
-
(SELECT count(*) FROM
|
|
1494
|
-
ELSE (SELECT count(*) FROM
|
|
1495
|
-
(SELECT count(*) FROM
|
|
1496
|
-
(NOT EXISTS (SELECT 1 FROM
|
|
1497
|
-
(SELECT 1 FROM
|
|
1498
|
-
(SELECT count(*) FROM
|
|
1499
|
-
(a.owner_kind='run' OR NOT EXISTS (SELECT 1 FROM
|
|
1500
|
-
(SELECT 1 FROM
|
|
1501
|
-
(SELECT count(*) FROM
|
|
1510
|
+
FROM ne19_attempt_publications p WHERE p.origin_run_id=r.run_id)) logical_seal_identity,
|
|
1511
|
+
(SELECT count(*) FROM ne19_slots WHERE run_id=r.run_id) slot_count,
|
|
1512
|
+
CASE WHEN EXISTS (SELECT 1 FROM ne19_run_resources WHERE run_id=r.run_id) THEN
|
|
1513
|
+
(SELECT count(*) FROM ne19_run_slot_bindings WHERE target_run_id=r.run_id)+
|
|
1514
|
+
(SELECT count(*) FROM ne19_run_slot_absences WHERE run_id=r.run_id)
|
|
1515
|
+
ELSE (SELECT count(*) FROM ne19_members WHERE target_run_id=r.run_id) END member_count,
|
|
1516
|
+
(SELECT count(*) FROM ne19_attempts a WHERE a.origin_run_id=r.run_id AND
|
|
1517
|
+
(NOT EXISTS (SELECT 1 FROM ne19_run_resources WHERE run_id=r.run_id) OR EXISTS
|
|
1518
|
+
(SELECT 1 FROM ne19_attempt_publications p WHERE p.origin_run_id=a.origin_run_id AND p.attempt_id=a.attempt_id))) attempt_count,
|
|
1519
|
+
(SELECT count(*) FROM ne19_attachments a WHERE a.owner_run_id=r.run_id AND a.canonical_payload IS NOT NULL AND
|
|
1520
|
+
(a.owner_kind='run' OR NOT EXISTS (SELECT 1 FROM ne19_run_resources WHERE run_id=r.run_id) OR EXISTS
|
|
1521
|
+
(SELECT 1 FROM ne19_attempt_publications p WHERE p.origin_run_id=a.owner_run_id AND p.attempt_id=a.owner_attempt_id))) attachment_count,
|
|
1522
|
+
(SELECT count(*) FROM ne19_contents c JOIN ne19_attachments a ON a.attachment_id=c.attachment_id
|
|
1502
1523
|
WHERE a.owner_run_id=r.run_id AND a.canonical_payload IS NOT NULL AND
|
|
1503
|
-
(a.owner_kind='run' OR NOT EXISTS (SELECT 1 FROM
|
|
1504
|
-
(SELECT 1 FROM
|
|
1505
|
-
(SELECT coalesce(sum(c.byte_length),0) FROM
|
|
1524
|
+
(a.owner_kind='run' OR NOT EXISTS (SELECT 1 FROM ne19_run_resources WHERE run_id=r.run_id) OR EXISTS
|
|
1525
|
+
(SELECT 1 FROM ne19_attempt_publications p WHERE p.origin_run_id=a.owner_run_id AND p.attempt_id=a.owner_attempt_id))) content_count,
|
|
1526
|
+
(SELECT coalesce(sum(c.byte_length),0) FROM ne19_contents c JOIN ne19_attachments a ON a.attachment_id=c.attachment_id
|
|
1506
1527
|
WHERE a.owner_run_id=r.run_id AND a.canonical_payload IS NOT NULL AND
|
|
1507
|
-
(a.owner_kind='run' OR NOT EXISTS (SELECT 1 FROM
|
|
1508
|
-
(SELECT 1 FROM
|
|
1509
|
-
(SELECT count(*) FROM
|
|
1510
|
-
FROM
|
|
1511
|
-
(SELECT 1 FROM
|
|
1512
|
-
AND (r.status='sealed' OR EXISTS (SELECT 1 FROM
|
|
1528
|
+
(a.owner_kind='run' OR NOT EXISTS (SELECT 1 FROM ne19_run_resources WHERE run_id=r.run_id) OR EXISTS
|
|
1529
|
+
(SELECT 1 FROM ne19_attempt_publications p WHERE p.origin_run_id=a.owner_run_id AND p.attempt_id=a.owner_attempt_id))) content_bytes,
|
|
1530
|
+
(SELECT count(*) FROM ne19_run_seal_entries WHERE run_id=r.run_id) seal_count
|
|
1531
|
+
FROM ne19_runs r WHERE r.run_id=? AND NOT EXISTS
|
|
1532
|
+
(SELECT 1 FROM ne19_run_deletion_tombstones d WHERE d.run_id=r.run_id)
|
|
1533
|
+
AND (r.status='sealed' OR EXISTS (SELECT 1 FROM ne19_attempt_publications p WHERE p.origin_run_id=r.run_id))`).get(runId);
|
|
1513
1534
|
if (row === undefined)
|
|
1514
1535
|
return undefined;
|
|
1515
1536
|
return Object.freeze({ runId: text(row, "run_id"), writerGeneration: text(row, "writer_generation"),
|
|
@@ -1520,19 +1541,65 @@ function readSealedRunSummary(connection, runId) {
|
|
|
1520
1541
|
}
|
|
1521
1542
|
/** Pinned publication identity, plus a metadata-only count; no Seal hashing. */
|
|
1522
1543
|
function readSealedRunCutoff(connection, identity) {
|
|
1523
|
-
const row = (0, database_ts_1.recordStatement)(connection, `SELECT count(*) count FROM
|
|
1524
|
-
WHERE NOT EXISTS (SELECT 1 FROM
|
|
1525
|
-
AND (status='sealed' OR EXISTS (SELECT 1 FROM
|
|
1544
|
+
const row = (0, database_ts_1.recordStatement)(connection, `SELECT count(*) count FROM ne19_runs r
|
|
1545
|
+
WHERE NOT EXISTS (SELECT 1 FROM ne19_run_deletion_tombstones d WHERE d.run_id=r.run_id)
|
|
1546
|
+
AND (status='sealed' OR EXISTS (SELECT 1 FROM ne19_attempt_publications p WHERE p.origin_run_id=r.run_id))`).get();
|
|
1526
1547
|
return Object.freeze({ identity, runCount: integer(row, "count") });
|
|
1527
1548
|
}
|
|
1528
1549
|
/** Filter lightweight Run metadata before loading any selected Core or payload. */
|
|
1550
|
+
function findSourceBarrierCandidate(connection, request, cutoffRevision) {
|
|
1551
|
+
requireIdentity(request.experimentId, "experimentId");
|
|
1552
|
+
requireIdentity(request.evalId, "evalId");
|
|
1553
|
+
if (!Number.isSafeInteger(request.attemptOrdinal) || request.attemptOrdinal < 0) {
|
|
1554
|
+
throw (0, errors_ts_1.sqliteError)("record-content-invalid", "find-source-barrier", "Attempt ordinal must be non-negative");
|
|
1555
|
+
}
|
|
1556
|
+
// Resource identity and expected membership, including empty active Runs,
|
|
1557
|
+
// select the barrier before any Core or policy evidence is loaded.
|
|
1558
|
+
const current = rows(connection, `SELECT r.run_id,r.created_revision
|
|
1559
|
+
FROM ne19_run_resources r
|
|
1560
|
+
WHERE r.experiment_id=? AND r.created_revision<=? AND r.run_id<>?
|
|
1561
|
+
AND NOT EXISTS (SELECT 1 FROM ne19_run_deletion_tombstones d WHERE d.run_id=r.run_id)
|
|
1562
|
+
AND EXISTS (SELECT 1 FROM ne19_run_expected_slots s
|
|
1563
|
+
WHERE s.eval_id=? AND s.attempt_ordinal=? AND s.run_id=r.run_id)
|
|
1564
|
+
ORDER BY r.created_revision DESC,r.run_id COLLATE BINARY DESC LIMIT 1`, request.experimentId, cutoffRevision, request.excludeRunId ?? "", request.evalId, request.attemptOrdinal)[0];
|
|
1565
|
+
if (current !== undefined)
|
|
1566
|
+
return Object.freeze({ runId: text(current, "run_id"), createdRevision: integer(current, "created_revision") });
|
|
1567
|
+
// Legacy Runs deliberately have no fabricated resource/revision. Inspect
|
|
1568
|
+
// only their indexed Experiment's expected rows, never unrelated Core.
|
|
1569
|
+
// Malformed expected rows remain candidates so validation cannot fall back.
|
|
1570
|
+
const legacy = rows(connection, `SELECT r.run_id FROM ne19_runs r
|
|
1571
|
+
WHERE r.experiment_id=? AND r.status='sealed' AND r.run_id<>?
|
|
1572
|
+
AND NOT EXISTS (SELECT 1 FROM ne19_run_resources rr WHERE rr.run_id=r.run_id)
|
|
1573
|
+
AND NOT EXISTS (SELECT 1 FROM ne19_run_deletion_tombstones d WHERE d.run_id=r.run_id)
|
|
1574
|
+
AND EXISTS (SELECT 1 FROM ne19_slots s WHERE s.run_id=r.run_id AND
|
|
1575
|
+
CASE WHEN json_valid(CAST(s.core_payload AS TEXT)) THEN
|
|
1576
|
+
CASE WHEN json_type(CAST(s.core_payload AS TEXT),'$.evalId') IS NOT 'text' OR
|
|
1577
|
+
json_type(CAST(s.core_payload AS TEXT),'$.attemptOrdinal') IS NOT 'integer' THEN 1
|
|
1578
|
+
ELSE (json_extract(CAST(s.core_payload AS TEXT),'$.evalId')=? AND
|
|
1579
|
+
json_extract(CAST(s.core_payload AS TEXT),'$.attemptOrdinal')=?) END
|
|
1580
|
+
ELSE 1 END)
|
|
1581
|
+
ORDER BY r.run_id COLLATE BINARY DESC LIMIT 1`, request.experimentId, request.excludeRunId ?? "", request.evalId, request.attemptOrdinal)[0];
|
|
1582
|
+
return legacy === undefined ? undefined : Object.freeze({ runId: text(legacy, "run_id"), createdRevision: 0 });
|
|
1583
|
+
}
|
|
1584
|
+
/** Locate adoption proofs for one exact Attempt without scanning Run Core. */
|
|
1585
|
+
function findAcceptedAttemptRunIds(connection, request, cutoffRevision) {
|
|
1586
|
+
const selected = rows(connection, `SELECT b.target_run_id FROM ne19_run_slot_bindings b
|
|
1587
|
+
JOIN ne19_run_resources r ON r.run_id=b.target_run_id
|
|
1588
|
+
WHERE b.attempt_id=? AND b.origin_run_id=? AND b.action='accepted'
|
|
1589
|
+
AND r.experiment_id=? AND b.binding_revision<=? AND b.binding_revision<=?
|
|
1590
|
+
AND NOT EXISTS (SELECT 1 FROM ne19_run_deletion_tombstones d WHERE d.run_id=b.target_run_id)
|
|
1591
|
+
ORDER BY b.target_run_id LIMIT ?`, request.attemptId, request.originRunId, request.experimentId, request.bindingRevision, cutoffRevision, types_ts_1.RECORD_SQLITE_MAX_VALIDATION_RUNS + 1);
|
|
1592
|
+
if (selected.length > types_ts_1.RECORD_SQLITE_MAX_VALIDATION_RUNS) {
|
|
1593
|
+
throw (0, errors_ts_1.sqliteError)("record-resource-limit-exceeded", "find-accepted-attempt-runs", "Attempt exceeds its adoption proof ceiling");
|
|
1594
|
+
}
|
|
1595
|
+
return Object.freeze(selected.map((row) => text(row, "target_run_id")));
|
|
1596
|
+
}
|
|
1529
1597
|
function findExperimentRunIds(connection, experimentId) {
|
|
1530
1598
|
requireIdentity(experimentId, "experimentId");
|
|
1531
|
-
const selected = rows(connection, `SELECT r.run_id FROM
|
|
1532
|
-
|
|
1533
|
-
|
|
1534
|
-
AND
|
|
1535
|
-
AND (r.status='sealed' OR EXISTS (SELECT 1 FROM ne18_attempt_publications p WHERE p.origin_run_id=r.run_id))
|
|
1599
|
+
const selected = rows(connection, `SELECT r.run_id FROM ne19_runs r
|
|
1600
|
+
WHERE r.experiment_id=?
|
|
1601
|
+
AND NOT EXISTS (SELECT 1 FROM ne19_run_deletion_tombstones d WHERE d.run_id=r.run_id)
|
|
1602
|
+
AND (r.status='sealed' OR EXISTS (SELECT 1 FROM ne19_attempt_publications p WHERE p.origin_run_id=r.run_id))
|
|
1536
1603
|
ORDER BY r.run_id LIMIT ?`, experimentId, types_ts_1.RECORD_SQLITE_MAX_VALIDATION_RUNS + 1);
|
|
1537
1604
|
if (selected.length > types_ts_1.RECORD_SQLITE_MAX_VALIDATION_RUNS) {
|
|
1538
1605
|
throw (0, errors_ts_1.sqliteError)("record-resource-limit-exceeded", "find-experiment-runs", "Experiment exceeds its Run ceiling");
|
|
@@ -1543,10 +1610,10 @@ function listSealedRunSummaries(connection, afterRunId = "", pageSize = 100) {
|
|
|
1543
1610
|
if (!Number.isSafeInteger(pageSize) || pageSize < 1 || pageSize > 256) {
|
|
1544
1611
|
throw (0, errors_ts_1.sqliteError)("record-resource-limit-exceeded", "list-sealed-runs", "page size must be between 1 and 256");
|
|
1545
1612
|
}
|
|
1546
|
-
const runIds = rows(connection, `SELECT run_id FROM
|
|
1547
|
-
AND NOT EXISTS (SELECT 1 FROM
|
|
1613
|
+
const runIds = rows(connection, `SELECT run_id FROM ne19_runs WHERE run_id>?
|
|
1614
|
+
AND NOT EXISTS (SELECT 1 FROM ne19_run_deletion_tombstones d WHERE d.run_id=ne19_runs.run_id)
|
|
1548
1615
|
AND (status='sealed' OR EXISTS
|
|
1549
|
-
(SELECT 1 FROM
|
|
1616
|
+
(SELECT 1 FROM ne19_attempt_publications p WHERE p.origin_run_id=ne19_runs.run_id)) ORDER BY run_id LIMIT ?`, afterRunId, pageSize);
|
|
1550
1617
|
return Object.freeze(runIds.map((row) => {
|
|
1551
1618
|
const summary = readSealedRunSummary(connection, text(row, "run_id"));
|
|
1552
1619
|
if (summary === undefined)
|
|
@@ -1568,11 +1635,11 @@ function readSealedRunSummaryPage(connection, afterRunId = "", pageSize = 100, e
|
|
|
1568
1635
|
cutoffHash.update("[");
|
|
1569
1636
|
let runCount = 0;
|
|
1570
1637
|
const inventory = (0, database_ts_1.recordStatement)(connection, `SELECT run_id,
|
|
1571
|
-
coalesce(logical_seal_identity,'published:' || (SELECT max(p.published_revision) FROM
|
|
1572
|
-
WHERE p.origin_run_id=
|
|
1573
|
-
FROM
|
|
1638
|
+
coalesce(logical_seal_identity,'published:' || (SELECT max(p.published_revision) FROM ne19_attempt_publications p
|
|
1639
|
+
WHERE p.origin_run_id=ne19_runs.run_id)) logical_seal_identity
|
|
1640
|
+
FROM ne19_runs WHERE NOT EXISTS (SELECT 1 FROM ne19_run_deletion_tombstones d WHERE d.run_id=ne19_runs.run_id)
|
|
1574
1641
|
AND (status='sealed' OR EXISTS
|
|
1575
|
-
(SELECT 1 FROM
|
|
1642
|
+
(SELECT 1 FROM ne19_attempt_publications p WHERE p.origin_run_id=ne19_runs.run_id))
|
|
1576
1643
|
ORDER BY run_id`).iterate();
|
|
1577
1644
|
for (const row of inventory) {
|
|
1578
1645
|
if (runCount >= types_ts_1.RECORD_SQLITE_MAX_VALIDATION_RUNS) {
|
|
@@ -1594,10 +1661,10 @@ function readSealedRunSummaryPage(connection, afterRunId = "", pageSize = 100, e
|
|
|
1594
1661
|
if (expectedCutoffIdentity !== undefined && expectedCutoffIdentity !== identity) {
|
|
1595
1662
|
throw (0, errors_ts_1.sqliteError)("record-command-conflict", "page-sealed-runs", "sealed cutoff changed; restart pagination");
|
|
1596
1663
|
}
|
|
1597
|
-
const pageRows = rows(connection, `SELECT run_id FROM
|
|
1598
|
-
AND NOT EXISTS (SELECT 1 FROM
|
|
1664
|
+
const pageRows = rows(connection, `SELECT run_id FROM ne19_runs WHERE run_id>?
|
|
1665
|
+
AND NOT EXISTS (SELECT 1 FROM ne19_run_deletion_tombstones d WHERE d.run_id=ne19_runs.run_id)
|
|
1599
1666
|
AND (status='sealed' OR EXISTS
|
|
1600
|
-
(SELECT 1 FROM
|
|
1667
|
+
(SELECT 1 FROM ne19_attempt_publications p WHERE p.origin_run_id=ne19_runs.run_id)) ORDER BY run_id LIMIT ?`, afterRunId, pageSize + 1);
|
|
1601
1668
|
const selected = pageRows.slice(0, pageSize);
|
|
1602
1669
|
const summaries = selected.map((row) => {
|
|
1603
1670
|
const summary = readSealedRunSummary(connection, text(row, "run_id"));
|
|
@@ -1614,15 +1681,15 @@ function readSealedRunSummaryPage(connection, afterRunId = "", pageSize = 100, e
|
|
|
1614
1681
|
});
|
|
1615
1682
|
}
|
|
1616
1683
|
/** Indexed, bounded locator projection. No Core or attachment payload is selected. */
|
|
1617
|
-
function findAttemptLocatorCandidates(connection, locator, maximumCandidateRuns) {
|
|
1684
|
+
function findAttemptLocatorCandidates(connection, locator, maximumCandidateRuns, includeTargets = true) {
|
|
1618
1685
|
if (!(0, attempt_locator_ts_1.parseAttemptLocator)(locator).valid) {
|
|
1619
1686
|
throw (0, errors_ts_1.sqliteError)("record-content-invalid", "find-attempt-locator", "Attempt locator is malformed");
|
|
1620
1687
|
}
|
|
1621
1688
|
if (!Number.isSafeInteger(maximumCandidateRuns) || maximumCandidateRuns < 1 || maximumCandidateRuns > 256) {
|
|
1622
1689
|
throw (0, errors_ts_1.sqliteError)("record-resource-limit-exceeded", "find-attempt-locator", "candidate Run limit must be between 1 and 256");
|
|
1623
1690
|
}
|
|
1624
|
-
const matching = rows(connection, `SELECT a.origin_run_id,a.attempt_id FROM
|
|
1625
|
-
JOIN
|
|
1691
|
+
const matching = rows(connection, `SELECT a.origin_run_id,a.attempt_id FROM ne19_attempts a
|
|
1692
|
+
JOIN ne19_runs origin ON origin.run_id=a.origin_run_id
|
|
1626
1693
|
WHERE a.attempt_locator=? ORDER BY a.origin_run_id,a.attempt_id LIMIT ?`, locator, maximumCandidateRuns + 1);
|
|
1627
1694
|
const identities = new Set();
|
|
1628
1695
|
const candidates = [];
|
|
@@ -1635,15 +1702,17 @@ function findAttemptLocatorCandidates(connection, locator, maximumCandidateRuns)
|
|
|
1635
1702
|
for (const row of matching) {
|
|
1636
1703
|
const originRunId = text(row, "origin_run_id");
|
|
1637
1704
|
const attemptId = text(row, "attempt_id");
|
|
1638
|
-
const published = (0, database_ts_1.recordStatement)(connection, `SELECT 1 FROM
|
|
1639
|
-
((r.status='sealed' AND NOT EXISTS (SELECT 1 FROM
|
|
1640
|
-
EXISTS (SELECT 1 FROM
|
|
1705
|
+
const published = (0, database_ts_1.recordStatement)(connection, `SELECT 1 FROM ne19_runs r WHERE r.run_id=? AND
|
|
1706
|
+
((r.status='sealed' AND NOT EXISTS (SELECT 1 FROM ne19_run_resources rr WHERE rr.run_id=r.run_id)) OR
|
|
1707
|
+
EXISTS (SELECT 1 FROM ne19_attempt_publications p WHERE p.origin_run_id=r.run_id AND p.attempt_id=?))`).get(originRunId, attemptId);
|
|
1641
1708
|
if (published === undefined)
|
|
1642
1709
|
continue;
|
|
1643
1710
|
identities.add((0, seal_ts_1.hashCanonicalTuple)("niceeval.record.attempt-candidate/v1", [originRunId, attemptId]));
|
|
1644
1711
|
add({ locator, originRunId, attemptId, relation: "origin", runId: originRunId });
|
|
1645
|
-
|
|
1646
|
-
|
|
1712
|
+
if (!includeTargets)
|
|
1713
|
+
continue;
|
|
1714
|
+
const targets = rows(connection, `SELECT DISTINCT m.target_run_id FROM ne19_members m
|
|
1715
|
+
JOIN ne19_runs target ON target.run_id=m.target_run_id AND target.status='sealed'
|
|
1647
1716
|
WHERE m.origin_run_id=? AND m.attempt_id=? ORDER BY m.target_run_id LIMIT ?`, originRunId, attemptId, maximumCandidateRuns - candidates.length + 1);
|
|
1648
1717
|
for (const target of targets)
|
|
1649
1718
|
add({ locator, originRunId, attemptId, relation: "target", runId: text(target, "target_run_id") });
|
|
@@ -1660,12 +1729,12 @@ function readCollectionItemPage(connection, attachmentId, afterOrdinal, pageSize
|
|
|
1660
1729
|
let pageBytes = 0;
|
|
1661
1730
|
let hasMore = false;
|
|
1662
1731
|
const pageRows = (0, database_ts_1.recordStatement)(connection, `SELECT i.ordinal,i.logical_identity,i.canonical_payload,i.canonical_digest,
|
|
1663
|
-
EXISTS(SELECT 1 FROM
|
|
1664
|
-
FROM
|
|
1665
|
-
JOIN
|
|
1732
|
+
EXISTS(SELECT 1 FROM ne19_collection_items more WHERE more.attachment_id=i.attachment_id AND more.ordinal>i.ordinal) AS has_more
|
|
1733
|
+
FROM ne19_collection_items i
|
|
1734
|
+
JOIN ne19_attachments a ON a.attachment_id=i.attachment_id JOIN ne19_runs r ON r.run_id=a.owner_run_id
|
|
1666
1735
|
WHERE i.attachment_id=? AND i.ordinal>? AND
|
|
1667
|
-
((r.status='sealed' AND (NOT EXISTS (SELECT 1 FROM
|
|
1668
|
-
(a.owner_kind='attempt' AND EXISTS (SELECT 1 FROM
|
|
1736
|
+
((r.status='sealed' AND (NOT EXISTS (SELECT 1 FROM ne19_run_resources rr WHERE rr.run_id=r.run_id) OR a.owner_kind='run')) OR
|
|
1737
|
+
(a.owner_kind='attempt' AND EXISTS (SELECT 1 FROM ne19_attempt_publications p
|
|
1669
1738
|
WHERE p.origin_run_id=a.owner_run_id AND p.attempt_id=a.owner_attempt_id)))
|
|
1670
1739
|
ORDER BY i.ordinal LIMIT ?`)
|
|
1671
1740
|
.iterate(attachmentId, afterOrdinal, pageSize);
|
|
@@ -1714,14 +1783,14 @@ function memoRecordRead(read, defer) {
|
|
|
1714
1783
|
}
|
|
1715
1784
|
function readPublishedSealedRun(connection, runId, defer) {
|
|
1716
1785
|
const run = (0, database_ts_1.recordStatement)(connection, `SELECT run_id,writer_generation,started_at,status,
|
|
1717
|
-
coalesce(logical_seal_identity,'published:' || (SELECT max(p.published_revision) FROM
|
|
1718
|
-
WHERE p.origin_run_id=
|
|
1719
|
-
(SELECT p.closure_payload FROM
|
|
1786
|
+
coalesce(logical_seal_identity,'published:' || (SELECT max(p.published_revision) FROM ne19_attempt_publications p
|
|
1787
|
+
WHERE p.origin_run_id=ne19_runs.run_id)) logical_seal_identity,core_payload,core_digest,
|
|
1788
|
+
(SELECT p.closure_payload FROM ne19_attempt_publications p WHERE p.origin_run_id=ne19_runs.run_id
|
|
1720
1789
|
ORDER BY p.published_revision DESC LIMIT 1) publication_closure
|
|
1721
|
-
FROM
|
|
1722
|
-
AND NOT EXISTS (SELECT 1 FROM
|
|
1790
|
+
FROM ne19_runs WHERE run_id=?
|
|
1791
|
+
AND NOT EXISTS (SELECT 1 FROM ne19_run_deletion_tombstones d WHERE d.run_id=ne19_runs.run_id)
|
|
1723
1792
|
AND (status='sealed' OR EXISTS
|
|
1724
|
-
(SELECT 1 FROM
|
|
1793
|
+
(SELECT 1 FROM ne19_attempt_publications p WHERE p.origin_run_id=ne19_runs.run_id))`).get(runId);
|
|
1725
1794
|
if (run === undefined)
|
|
1726
1795
|
return undefined;
|
|
1727
1796
|
let runCoreBytes;
|
|
@@ -1746,30 +1815,30 @@ function readPublishedSealedRun(connection, runId, defer) {
|
|
|
1746
1815
|
runCoreDigest = digestBytes(runCoreBytes);
|
|
1747
1816
|
}
|
|
1748
1817
|
const admission = (0, database_ts_1.recordStatement)(connection, `SELECT
|
|
1749
|
-
1+(SELECT count(*) FROM
|
|
1750
|
-
(SELECT count(*) FROM
|
|
1751
|
-
(SELECT count(*) FROM
|
|
1752
|
-
(SELECT count(*) FROM
|
|
1753
|
-
coalesce(length(r.core_payload),(SELECT max(length(p.closure_payload)) FROM
|
|
1754
|
-
(SELECT coalesce(sum(length(core_payload)),0) FROM
|
|
1755
|
-
(SELECT coalesce(sum(length(core_payload)),0) FROM
|
|
1756
|
-
(SELECT coalesce(sum(length(core_payload)),0) FROM
|
|
1757
|
-
(SELECT coalesce(sum(length(canonical_payload)+length(logical_inventory)),0) FROM
|
|
1758
|
-
(SELECT coalesce(sum(length(rr.canonical_payload)),0) FROM
|
|
1759
|
-
FROM
|
|
1760
|
-
(SELECT 1 FROM
|
|
1818
|
+
1+(SELECT count(*) FROM ne19_slots WHERE run_id=?)+(SELECT count(*) FROM ne19_attempts WHERE origin_run_id=?)+
|
|
1819
|
+
(SELECT count(*) FROM ne19_members WHERE target_run_id=?)+(SELECT count(*) FROM ne19_attachments WHERE owner_run_id=?)+
|
|
1820
|
+
(SELECT count(*) FROM ne19_attachment_references rr JOIN ne19_attachments aa ON aa.attachment_id=rr.attachment_id WHERE aa.owner_run_id=?)+
|
|
1821
|
+
(SELECT count(*) FROM ne19_contents cc JOIN ne19_attachments aa ON aa.attachment_id=cc.attachment_id WHERE aa.owner_run_id=?) row_count,
|
|
1822
|
+
coalesce(length(r.core_payload),(SELECT max(length(p.closure_payload)) FROM ne19_attempt_publications p WHERE p.origin_run_id=r.run_id),0)+
|
|
1823
|
+
(SELECT coalesce(sum(length(core_payload)),0) FROM ne19_slots WHERE run_id=?)+
|
|
1824
|
+
(SELECT coalesce(sum(length(core_payload)),0) FROM ne19_attempts WHERE origin_run_id=?)+
|
|
1825
|
+
(SELECT coalesce(sum(length(core_payload)),0) FROM ne19_members WHERE target_run_id=?)+
|
|
1826
|
+
(SELECT coalesce(sum(length(canonical_payload)+length(logical_inventory)),0) FROM ne19_attachments WHERE owner_run_id=?)+
|
|
1827
|
+
(SELECT coalesce(sum(length(rr.canonical_payload)),0) FROM ne19_attachment_references rr JOIN ne19_attachments aa ON aa.attachment_id=rr.attachment_id WHERE aa.owner_run_id=?) byte_count
|
|
1828
|
+
FROM ne19_runs r WHERE r.run_id=? AND (r.status='sealed' OR EXISTS
|
|
1829
|
+
(SELECT 1 FROM ne19_attempt_publications p WHERE p.origin_run_id=r.run_id))`).get(runId, runId, runId, runId, runId, runId, runId, runId, runId, runId, runId, runId);
|
|
1761
1830
|
assertBoundedBatch("read-sealed-run-core", integer(admission, "row_count"), integer(admission, "byte_count"));
|
|
1762
|
-
const record = (0, database_ts_1.recordStatement)(connection, "SELECT record_payload,record_digest FROM
|
|
1763
|
-
const slots = rows(connection, "SELECT slot_id,ordinal,core_payload,core_digest FROM
|
|
1831
|
+
const record = (0, database_ts_1.recordStatement)(connection, "SELECT record_payload,record_digest FROM ne19_record_metadata WHERE singleton=1").get();
|
|
1832
|
+
const slots = rows(connection, "SELECT slot_id,ordinal,core_payload,core_digest FROM ne19_slots WHERE run_id=? ORDER BY ordinal", runId)
|
|
1764
1833
|
.map((row) => Object.freeze({ slotId: text(row, "slot_id"), ordinal: integer(row, "ordinal"), coreBytes: transferableBytes(bytes(row, "core_payload")), coreDigest: text(row, "core_digest") }));
|
|
1765
|
-
const publicationResource = (0, database_ts_1.recordStatement)(connection, "SELECT created_revision FROM
|
|
1834
|
+
const publicationResource = (0, database_ts_1.recordStatement)(connection, "SELECT created_revision FROM ne19_run_resources WHERE run_id=?").get(runId);
|
|
1766
1835
|
const publicationManaged = publicationResource !== undefined;
|
|
1767
1836
|
const attempts = rows(connection, publicationManaged
|
|
1768
|
-
? `SELECT a.attempt_id,a.attempt_locator,a.core_payload,a.core_digest,p.published_revision FROM
|
|
1769
|
-
JOIN
|
|
1770
|
-
WHERE a.origin_run_id=? AND EXISTS (SELECT 1 FROM
|
|
1837
|
+
? `SELECT a.attempt_id,a.attempt_locator,a.core_payload,a.core_digest,p.published_revision FROM ne19_attempts a
|
|
1838
|
+
JOIN ne19_attempt_publications p ON p.origin_run_id=a.origin_run_id AND p.attempt_id=a.attempt_id
|
|
1839
|
+
WHERE a.origin_run_id=? AND EXISTS (SELECT 1 FROM ne19_attempt_publications p
|
|
1771
1840
|
WHERE p.origin_run_id=a.origin_run_id AND p.attempt_id=a.attempt_id) ORDER BY a.attempt_id`
|
|
1772
|
-
: "SELECT attempt_id,attempt_locator,core_payload,core_digest FROM
|
|
1841
|
+
: "SELECT attempt_id,attempt_locator,core_payload,core_digest FROM ne19_attempts WHERE origin_run_id=? ORDER BY attempt_id", runId)
|
|
1773
1842
|
.map((row) => {
|
|
1774
1843
|
if (!(row.core_payload instanceof Uint8Array))
|
|
1775
1844
|
throw (0, errors_ts_1.sqliteError)("record-database-invalid", "read-published-run-core", `Attempt ${text(row, "attempt_id")} Core is not published`);
|
|
@@ -1782,21 +1851,22 @@ function readPublishedSealedRun(connection, runId, defer) {
|
|
|
1782
1851
|
...rows(connection, `SELECT 'binding' publication_kind,b.slot_id,b.origin_run_id,b.attempt_id,b.action,b.attempt_publication_revision,b.binding_revision,
|
|
1783
1852
|
m.origin_run_id member_origin_run_id,m.attempt_id member_attempt_id,m.action member_action,
|
|
1784
1853
|
m.core_payload,m.core_digest,p.published_revision
|
|
1785
|
-
FROM
|
|
1786
|
-
LEFT JOIN
|
|
1787
|
-
LEFT JOIN
|
|
1854
|
+
FROM ne19_run_slot_bindings b
|
|
1855
|
+
LEFT JOIN ne19_members m ON m.target_run_id=b.target_run_id AND m.slot_id=b.slot_id
|
|
1856
|
+
LEFT JOIN ne19_attempt_publications p ON p.attempt_id=b.attempt_id AND p.origin_run_id=b.origin_run_id
|
|
1788
1857
|
AND p.published_revision=b.attempt_publication_revision
|
|
1789
1858
|
WHERE b.target_run_id=?`, runId),
|
|
1790
1859
|
...rows(connection, `SELECT 'absence' publication_kind,a.slot_id,NULL origin_run_id,NULL attempt_id,
|
|
1791
1860
|
NULL action,NULL attempt_publication_revision,NULL member_origin_run_id,NULL member_attempt_id,
|
|
1792
1861
|
NULL member_action,NULL core_payload,NULL core_digest,NULL published_revision,a.reason absence_reason
|
|
1793
|
-
FROM
|
|
1862
|
+
FROM ne19_run_slot_absences a
|
|
1794
1863
|
WHERE a.run_id=?`, runId),
|
|
1795
1864
|
].sort((left, right) => text(left, "slot_id").localeCompare(text(right, "slot_id")))
|
|
1796
|
-
: rows(connection, "SELECT slot_id,origin_run_id,attempt_id,action,core_payload,core_digest FROM
|
|
1865
|
+
: rows(connection, "SELECT slot_id,origin_run_id,attempt_id,action,core_payload,core_digest FROM ne19_members WHERE target_run_id=? ORDER BY slot_id", runId);
|
|
1797
1866
|
const members = memberRows
|
|
1798
1867
|
.map((row) => {
|
|
1799
1868
|
const attemptId = optionalText(row, "attempt_id");
|
|
1869
|
+
let referenceCore;
|
|
1800
1870
|
if (publicationManaged) {
|
|
1801
1871
|
const kind = text(row, "publication_kind");
|
|
1802
1872
|
if (kind === "absence") {
|
|
@@ -1811,14 +1881,28 @@ function readPublishedSealedRun(connection, runId, defer) {
|
|
|
1811
1881
|
coreDigest: projected.coreDigest,
|
|
1812
1882
|
});
|
|
1813
1883
|
}
|
|
1884
|
+
const projectReference = (row.action === "carried" || row.action === "accepted") && row.core_payload == null;
|
|
1814
1885
|
const bindingInvalid = kind === "binding" && (attemptId === undefined
|
|
1815
1886
|
|| optionalInteger(row, "published_revision") !== optionalInteger(row, "attempt_publication_revision")
|
|
1816
|
-
|| optionalText(row, "member_origin_run_id") !== optionalText(row, "origin_run_id")
|
|
1817
|
-
|
|
1818
|
-
|
|
1887
|
+
|| !projectReference && (optionalText(row, "member_origin_run_id") !== optionalText(row, "origin_run_id")
|
|
1888
|
+
|| optionalText(row, "member_attempt_id") !== attemptId
|
|
1889
|
+
|| optionalText(row, "member_action") !== optionalText(row, "action")));
|
|
1819
1890
|
if (bindingInvalid) {
|
|
1820
1891
|
throw (0, errors_ts_1.sqliteError)("record-database-invalid", "read-published-run", `Published Slot ${text(row, "slot_id")} does not close over one matching Member`);
|
|
1821
1892
|
}
|
|
1893
|
+
if (projectReference) {
|
|
1894
|
+
const decoded = (0, core_ts_1.decodeMemberDocument)({
|
|
1895
|
+
slotId: text(row, "slot_id"), action: text(row, "action"),
|
|
1896
|
+
attempt: { originRunId: text(row, "origin_run_id"), attemptId },
|
|
1897
|
+
});
|
|
1898
|
+
if (effect_1.Result.isFailure(decoded))
|
|
1899
|
+
throw (0, errors_ts_1.sqliteError)("record-database-invalid", "read-published-run", "Reference binding cannot project a Member");
|
|
1900
|
+
const encoded = (0, core_ts_1.encodeMemberDocument)(decoded.success);
|
|
1901
|
+
if (effect_1.Result.isFailure(encoded))
|
|
1902
|
+
throw (0, errors_ts_1.sqliteError)("record-database-invalid", "read-published-run", "Reference Member cannot be encoded");
|
|
1903
|
+
const projectedBytes = (0, limits_ts_1.encodeRecordJsonUtf8)(encoded.success);
|
|
1904
|
+
referenceCore = { bytes: projectedBytes, digest: digestBytes(projectedBytes) };
|
|
1905
|
+
}
|
|
1822
1906
|
}
|
|
1823
1907
|
return Object.freeze({ slotId: text(row, "slot_id"),
|
|
1824
1908
|
...(publicationManaged && attemptId !== undefined ? { bindingRevision: integer(row, "binding_revision") } : {}), ...(optionalText(row, "origin_run_id") === undefined ? {} : { originRunId: optionalText(row, "origin_run_id") }),
|
|
@@ -1826,34 +1910,34 @@ function readPublishedSealedRun(connection, runId, defer) {
|
|
|
1826
1910
|
...(publicationManaged && attemptId !== undefined
|
|
1827
1911
|
? { publicationIdentity: Object.freeze({ originRunId: text(row, "origin_run_id"), attemptId, revision: integer(row, "published_revision") }) }
|
|
1828
1912
|
: {}),
|
|
1829
|
-
coreBytes: transferableBytes(bytes(row, "core_payload")), coreDigest: text(row, "core_digest") });
|
|
1913
|
+
coreBytes: transferableBytes(referenceCore?.bytes ?? bytes(row, "core_payload")), coreDigest: referenceCore?.digest ?? text(row, "core_digest") });
|
|
1830
1914
|
});
|
|
1831
1915
|
const attachmentRows = rows(connection, `SELECT attachment_id,owner_kind,owner_run_id,owner_attempt_id,family,family_revision,
|
|
1832
1916
|
logical_identity,canonical_digest,inventory_digest
|
|
1833
|
-
FROM
|
|
1834
|
-
(owner_kind='run' OR EXISTS (SELECT 1 FROM
|
|
1917
|
+
FROM ne19_attachments a WHERE owner_run_id=?${publicationManaged ? ` AND canonical_payload IS NOT NULL AND
|
|
1918
|
+
(owner_kind='run' OR EXISTS (SELECT 1 FROM ne19_attempt_publications p
|
|
1835
1919
|
WHERE p.origin_run_id=a.owner_run_id AND p.attempt_id=a.owner_attempt_id))` : ""} ORDER BY attachment_id`, runId);
|
|
1836
1920
|
const attachments = attachmentRows.map((row) => {
|
|
1837
1921
|
const attachmentId = text(row, "attachment_id");
|
|
1838
1922
|
const payload = memoRecordRead(() => {
|
|
1839
|
-
const stored = (0, database_ts_1.recordStatement)(connection, `SELECT canonical_payload,logical_inventory FROM
|
|
1923
|
+
const stored = (0, database_ts_1.recordStatement)(connection, `SELECT canonical_payload,logical_inventory FROM ne19_attachments WHERE attachment_id=?`)
|
|
1840
1924
|
.get(attachmentId);
|
|
1841
1925
|
return { canonicalBytes: transferableBytes(bytes(stored, "canonical_payload")),
|
|
1842
1926
|
logicalInventoryBytes: transferableBytes(bytes(stored, "logical_inventory")) };
|
|
1843
1927
|
}, defer);
|
|
1844
1928
|
const references = memoRecordRead(() => Object.freeze(rows(connection, `SELECT ordinal,target_owner_kind,target_family,canonical_payload,reference_digest
|
|
1845
|
-
FROM
|
|
1929
|
+
FROM ne19_attachment_references WHERE attachment_id=? ORDER BY ordinal`, attachmentId).map((reference) => Object.freeze({
|
|
1846
1930
|
ordinal: integer(reference, "ordinal"), owner: ownerKind(reference, "target_owner_kind"), family: text(reference, "target_family"),
|
|
1847
1931
|
canonicalBytes: transferableBytes(bytes(reference, "canonical_payload")), referenceDigest: text(reference, "reference_digest"),
|
|
1848
1932
|
}))), defer);
|
|
1849
1933
|
const contents = memoRecordRead(() => Object.freeze(rows(connection, `SELECT content_id,logical_handle,byte_length,overall_digest,chunk_count
|
|
1850
|
-
FROM
|
|
1934
|
+
FROM ne19_contents WHERE attachment_id=? ORDER BY content_id`, attachmentId).map((content) => Object.freeze({
|
|
1851
1935
|
contentId: text(content, "content_id"), logicalHandle: text(content, "logical_handle"), byteLength: integer(content, "byte_length"),
|
|
1852
1936
|
digest: text(content, "overall_digest"), chunkCount: integer(content, "chunk_count"),
|
|
1853
1937
|
}))), defer);
|
|
1854
1938
|
const collection = memoRecordRead(() => {
|
|
1855
1939
|
const aggregate = (0, database_ts_1.recordStatement)(connection, `SELECT count(*) item_count,coalesce(sum(length(canonical_payload)),0) item_bytes
|
|
1856
|
-
FROM
|
|
1940
|
+
FROM ne19_collection_items WHERE attachment_id=?`).get(attachmentId);
|
|
1857
1941
|
return { count: integer(aggregate, "item_count"), byteLength: integer(aggregate, "item_bytes") };
|
|
1858
1942
|
}, defer);
|
|
1859
1943
|
return Object.freeze({ attachmentId, ownerKind: ownerKind(row, "owner_kind"), ownerRunId: text(row, "owner_run_id"),
|
|
@@ -1877,19 +1961,19 @@ function readSealedRunCore(connection, runId, defer) {
|
|
|
1877
1961
|
/** Fixed, decoded projection sufficient to rebuild sealed Core and attachment metadata. */
|
|
1878
1962
|
function readSealedRunDocument(connection, runId) {
|
|
1879
1963
|
const run = (0, database_ts_1.recordStatement)(connection, `SELECT run_id,writer_generation,started_at,logical_seal_identity,core_payload,core_digest
|
|
1880
|
-
FROM
|
|
1964
|
+
FROM ne19_runs WHERE run_id=? AND status='sealed'`).get(runId);
|
|
1881
1965
|
if (run === undefined)
|
|
1882
1966
|
return undefined;
|
|
1883
1967
|
const whole = (0, database_ts_1.recordStatement)(connection, `SELECT count(*) row_count,coalesce(sum(length(i.canonical_payload)),0) byte_count
|
|
1884
|
-
FROM
|
|
1968
|
+
FROM ne19_collection_items i JOIN ne19_attachments a ON a.attachment_id=i.attachment_id WHERE a.owner_run_id=?`).get(runId);
|
|
1885
1969
|
assertBoundedBatch("read-sealed-run-document", integer(whole, "row_count"), integer(whole, "byte_count"));
|
|
1886
|
-
const record = (0, database_ts_1.recordStatement)(connection, "SELECT record_payload,record_digest FROM
|
|
1970
|
+
const record = (0, database_ts_1.recordStatement)(connection, "SELECT record_payload,record_digest FROM ne19_record_metadata WHERE singleton=1")
|
|
1887
1971
|
.get();
|
|
1888
|
-
const slots = rows(connection, "SELECT slot_id,ordinal,core_payload,core_digest FROM
|
|
1972
|
+
const slots = rows(connection, "SELECT slot_id,ordinal,core_payload,core_digest FROM ne19_slots WHERE run_id=? ORDER BY ordinal", runId)
|
|
1889
1973
|
.map((row) => Object.freeze({ slotId: text(row, "slot_id"), ordinal: integer(row, "ordinal"), coreBytes: transferableBytes(bytes(row, "core_payload")), coreDigest: text(row, "core_digest") }));
|
|
1890
|
-
const attempts = rows(connection, "SELECT attempt_id,attempt_locator,core_payload,core_digest FROM
|
|
1974
|
+
const attempts = rows(connection, "SELECT attempt_id,attempt_locator,core_payload,core_digest FROM ne19_attempts WHERE origin_run_id=? ORDER BY attempt_id", runId)
|
|
1891
1975
|
.map((row) => Object.freeze({ attemptId: text(row, "attempt_id"), attemptLocator: text(row, "attempt_locator"), coreBytes: transferableBytes(bytes(row, "core_payload")), coreDigest: text(row, "core_digest") }));
|
|
1892
|
-
const members = rows(connection, `SELECT slot_id,origin_run_id,attempt_id,action,core_payload,core_digest FROM
|
|
1976
|
+
const members = rows(connection, `SELECT slot_id,origin_run_id,attempt_id,action,core_payload,core_digest FROM ne19_members
|
|
1893
1977
|
WHERE target_run_id=? ORDER BY slot_id`, runId).map((row) => Object.freeze({
|
|
1894
1978
|
slotId: text(row, "slot_id"),
|
|
1895
1979
|
...(optionalText(row, "origin_run_id") === undefined ? {} : { originRunId: optionalText(row, "origin_run_id") }),
|
|
@@ -1899,12 +1983,12 @@ function readSealedRunDocument(connection, runId) {
|
|
|
1899
1983
|
coreDigest: text(row, "core_digest"),
|
|
1900
1984
|
}));
|
|
1901
1985
|
const attachmentRows = rows(connection, `SELECT attachment_id,owner_kind,owner_run_id,owner_attempt_id,family,family_revision,
|
|
1902
|
-
logical_identity,canonical_payload,canonical_digest,logical_inventory,inventory_digest FROM
|
|
1986
|
+
logical_identity,canonical_payload,canonical_digest,logical_inventory,inventory_digest FROM ne19_attachments
|
|
1903
1987
|
WHERE owner_run_id=? ORDER BY attachment_id`, runId);
|
|
1904
1988
|
const attachments = attachmentRows.map((row) => {
|
|
1905
1989
|
const attachmentId = text(row, "attachment_id");
|
|
1906
1990
|
const references = rows(connection, `SELECT ordinal,target_owner_kind,target_family,
|
|
1907
|
-
canonical_payload,reference_digest FROM
|
|
1991
|
+
canonical_payload,reference_digest FROM ne19_attachment_references WHERE attachment_id=? ORDER BY ordinal`, attachmentId)
|
|
1908
1992
|
.map((reference) => Object.freeze({
|
|
1909
1993
|
ordinal: integer(reference, "ordinal"),
|
|
1910
1994
|
owner: ownerKind(reference, "target_owner_kind"),
|
|
@@ -1913,14 +1997,14 @@ function readSealedRunDocument(connection, runId) {
|
|
|
1913
1997
|
referenceDigest: text(reference, "reference_digest"),
|
|
1914
1998
|
}));
|
|
1915
1999
|
const collectionItems = rows(connection, `SELECT ordinal,logical_identity,canonical_payload,canonical_digest
|
|
1916
|
-
FROM
|
|
2000
|
+
FROM ne19_collection_items WHERE attachment_id=? ORDER BY ordinal`, attachmentId).map((item) => Object.freeze({
|
|
1917
2001
|
ordinal: integer(item, "ordinal"),
|
|
1918
2002
|
logicalIdentity: text(item, "logical_identity"),
|
|
1919
2003
|
canonicalBytes: transferableBytes(bytes(item, "canonical_payload")),
|
|
1920
2004
|
canonicalDigest: text(item, "canonical_digest"),
|
|
1921
2005
|
}));
|
|
1922
2006
|
const contents = rows(connection, `SELECT content_id,logical_handle,byte_length,overall_digest,chunk_count
|
|
1923
|
-
FROM
|
|
2007
|
+
FROM ne19_contents WHERE attachment_id=? ORDER BY content_id`, attachmentId).map((content) => Object.freeze({
|
|
1924
2008
|
contentId: text(content, "content_id"),
|
|
1925
2009
|
logicalHandle: text(content, "logical_handle"),
|
|
1926
2010
|
byteLength: integer(content, "byte_length"),
|
|
@@ -1975,9 +2059,9 @@ function appendContentChunks(connection, input) {
|
|
|
1975
2059
|
}
|
|
1976
2060
|
(0, transaction_ts_1.withImmediateTransaction)(connection, input.deadlineEpochMs, "append-content-chunks", () => {
|
|
1977
2061
|
assertRunFence(connection, input.runId, input.writerGeneration, "append-content-chunks");
|
|
1978
|
-
const metadata = (0, database_ts_1.recordStatement)(connection, `SELECT a.owner_run_id,a.owner_kind,r.status,at.publication_state FROM
|
|
1979
|
-
JOIN
|
|
1980
|
-
LEFT JOIN
|
|
2062
|
+
const metadata = (0, database_ts_1.recordStatement)(connection, `SELECT a.owner_run_id,a.owner_kind,r.status,at.publication_state FROM ne19_contents c
|
|
2063
|
+
JOIN ne19_attachments a ON a.attachment_id=c.attachment_id JOIN ne19_runs r ON r.run_id=a.owner_run_id
|
|
2064
|
+
LEFT JOIN ne19_attempts at ON at.origin_run_id=a.owner_run_id AND at.attempt_id=a.owner_attempt_id
|
|
1981
2065
|
WHERE c.content_id=?`).get(input.contentId);
|
|
1982
2066
|
if (metadata === undefined || text(metadata, "owner_run_id") !== input.runId || text(metadata, "status") !== "open" ||
|
|
1983
2067
|
(text(metadata, "owner_kind") === "attempt" && optionalText(metadata, "publication_state") === "published")) {
|
|
@@ -1985,13 +2069,13 @@ function appendContentChunks(connection, input) {
|
|
|
1985
2069
|
}
|
|
1986
2070
|
let changed = false;
|
|
1987
2071
|
for (const chunk of input.chunks) {
|
|
1988
|
-
const stored = (0, database_ts_1.recordStatement)(connection, "SELECT bytes,chunk_digest FROM
|
|
2072
|
+
const stored = (0, database_ts_1.recordStatement)(connection, "SELECT bytes,chunk_digest FROM ne19_content_chunks WHERE content_id=? AND ordinal=?")
|
|
1989
2073
|
.get(input.contentId, chunk.ordinal);
|
|
1990
2074
|
if (stored === undefined) {
|
|
1991
|
-
const count = (0, database_ts_1.recordStatement)(connection, "SELECT count(*) AS count FROM
|
|
2075
|
+
const count = (0, database_ts_1.recordStatement)(connection, "SELECT count(*) AS count FROM ne19_content_chunks WHERE content_id=?").get(input.contentId);
|
|
1992
2076
|
if (chunk.ordinal !== integer(count, "count"))
|
|
1993
2077
|
throw (0, errors_ts_1.sqliteError)("record-command-conflict", "append-content-chunks", "Content batch does not extend the committed prefix");
|
|
1994
|
-
(0, database_ts_1.recordStatement)(connection, "INSERT INTO
|
|
2078
|
+
(0, database_ts_1.recordStatement)(connection, "INSERT INTO ne19_content_chunks(content_id,ordinal,bytes,chunk_digest) VALUES (?,?,?,?)")
|
|
1995
2079
|
.run(input.contentId, chunk.ordinal, chunk.bytes, chunk.chunkDigest);
|
|
1996
2080
|
changed = true;
|
|
1997
2081
|
}
|
|
@@ -2013,12 +2097,12 @@ function readContentChunkPage(connection, contentId, afterOrdinal, pageSize) {
|
|
|
2013
2097
|
let pageBytes = 0;
|
|
2014
2098
|
let hasMore = false;
|
|
2015
2099
|
const pageRows = (0, database_ts_1.recordStatement)(connection, `SELECT c.ordinal,c.bytes,c.chunk_digest,
|
|
2016
|
-
EXISTS(SELECT 1 FROM
|
|
2017
|
-
FROM
|
|
2018
|
-
JOIN
|
|
2019
|
-
JOIN
|
|
2020
|
-
((r.status='sealed' AND (NOT EXISTS (SELECT 1 FROM
|
|
2021
|
-
(a.owner_kind='attempt' AND EXISTS (SELECT 1 FROM
|
|
2100
|
+
EXISTS(SELECT 1 FROM ne19_content_chunks more WHERE more.content_id=c.content_id AND more.ordinal>c.ordinal) AS has_more
|
|
2101
|
+
FROM ne19_content_chunks c
|
|
2102
|
+
JOIN ne19_contents n ON n.content_id=c.content_id JOIN ne19_attachments a ON a.attachment_id=n.attachment_id
|
|
2103
|
+
JOIN ne19_runs r ON r.run_id=a.owner_run_id WHERE c.content_id=? AND c.ordinal>? AND
|
|
2104
|
+
((r.status='sealed' AND (NOT EXISTS (SELECT 1 FROM ne19_run_resources rr WHERE rr.run_id=r.run_id) OR a.owner_kind='run')) OR
|
|
2105
|
+
(a.owner_kind='attempt' AND EXISTS (SELECT 1 FROM ne19_attempt_publications p
|
|
2022
2106
|
WHERE p.origin_run_id=a.owner_run_id AND p.attempt_id=a.owner_attempt_id)))
|
|
2023
2107
|
ORDER BY c.ordinal LIMIT ?`).iterate(contentId, afterOrdinal, pageSize);
|
|
2024
2108
|
for (const row of pageRows) {
|