@kontextmind/kxm 0.7.23 → 0.7.25

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.
@@ -16261,6 +16261,7 @@ var VnextSchemaRegistry = class {
16261
16261
  migrationReceiptValidator;
16262
16262
  permissionDiffValidator;
16263
16263
  runEventValidator;
16264
+ driveReceiptValidator;
16264
16265
  constructor(schemasDir = DEFAULT_SCHEMA_DIR) {
16265
16266
  this.schemasDir = resolve(schemasDir);
16266
16267
  this.ajv = new import__.Ajv2020({ allErrors: true, strict: true, strictRequired: false });
@@ -16277,6 +16278,7 @@ var VnextSchemaRegistry = class {
16277
16278
  const migrationReceiptFile = "migration-receipt.schema.json";
16278
16279
  const permissionDiffFile = "permission-diff.schema.json";
16279
16280
  const runEventFile = "run-event.schema.json";
16281
+ const driveReceiptFile = "drive-receipt.schema.json";
16280
16282
  this.ajv.addSchema(readJsonObject(join2(this.schemasDir, localBindingsFile)));
16281
16283
  this.ajv.addSchema(readJsonObject(join2(this.schemasDir, templateProvenanceFile)));
16282
16284
  this.ajv.addSchema(readJsonObject(join2(this.schemasDir, initOperationFile)));
@@ -16285,6 +16287,7 @@ var VnextSchemaRegistry = class {
16285
16287
  this.ajv.addSchema(readJsonObject(join2(this.schemasDir, migrationReceiptFile)));
16286
16288
  this.ajv.addSchema(readJsonObject(join2(this.schemasDir, permissionDiffFile)));
16287
16289
  this.ajv.addSchema(readJsonObject(join2(this.schemasDir, runEventFile)));
16290
+ this.ajv.addSchema(readJsonObject(join2(this.schemasDir, driveReceiptFile)));
16288
16291
  for (const [kind, definition] of Object.entries(RESOURCE_SCHEMA)) {
16289
16292
  const validator = this.ajv.getSchema(`https://schemas.kxm.dev/vnext/${definition.file}`);
16290
16293
  if (!validator) throw new Error(`schema did not compile: ${definition.file}`);
@@ -16298,6 +16301,7 @@ var VnextSchemaRegistry = class {
16298
16301
  const migrationReceiptValidator = this.ajv.getSchema(`https://schemas.kxm.dev/vnext/${migrationReceiptFile}`);
16299
16302
  const permissionDiffValidator = this.ajv.getSchema(`https://schemas.kxm.dev/vnext/${permissionDiffFile}`);
16300
16303
  const runEventValidator = this.ajv.getSchema(`https://schemas.kxm.dev/vnext/${runEventFile}`);
16304
+ const driveReceiptValidator = this.ajv.getSchema(`https://schemas.kxm.dev/vnext/${driveReceiptFile}`);
16301
16305
  if (!localBindingsValidator) throw new Error(`schema did not compile: ${localBindingsFile}`);
16302
16306
  if (!templateProvenanceValidator) throw new Error(`schema did not compile: ${templateProvenanceFile}`);
16303
16307
  if (!initOperationValidator) throw new Error(`schema did not compile: ${initOperationFile}`);
@@ -16306,6 +16310,7 @@ var VnextSchemaRegistry = class {
16306
16310
  if (!migrationReceiptValidator) throw new Error(`schema did not compile: ${migrationReceiptFile}`);
16307
16311
  if (!permissionDiffValidator) throw new Error(`schema did not compile: ${permissionDiffFile}`);
16308
16312
  if (!runEventValidator) throw new Error(`schema did not compile: ${runEventFile}`);
16313
+ if (!driveReceiptValidator) throw new Error(`schema did not compile: ${driveReceiptFile}`);
16309
16314
  this.localBindingsValidator = localBindingsValidator;
16310
16315
  this.templateProvenanceValidator = templateProvenanceValidator;
16311
16316
  this.initOperationValidator = initOperationValidator;
@@ -16314,6 +16319,7 @@ var VnextSchemaRegistry = class {
16314
16319
  this.migrationReceiptValidator = migrationReceiptValidator;
16315
16320
  this.permissionDiffValidator = permissionDiffValidator;
16316
16321
  this.runEventValidator = runEventValidator;
16322
+ this.driveReceiptValidator = driveReceiptValidator;
16317
16323
  }
16318
16324
  validate(kind, value, file) {
16319
16325
  const definition = RESOURCE_SCHEMA[kind];
@@ -16346,6 +16352,9 @@ var VnextSchemaRegistry = class {
16346
16352
  validatePermissionDiff(value, file) {
16347
16353
  return this.validateAuxiliary(value, file, "kxm.permission-diff.v1", this.permissionDiffValidator);
16348
16354
  }
16355
+ validateDriveReceipt(value, file) {
16356
+ return this.validateAuxiliary(value, file, "kxm.drive-receipt.v1", this.driveReceiptValidator);
16357
+ }
16349
16358
  validateAuxiliary(value, file, identity, validator) {
16350
16359
  if (value.schema !== identity) {
16351
16360
  return [issue2("schema", "schema_identity_mismatch", file, `expected ${identity}, received ${String(value.schema)}`)];
@@ -16366,6 +16375,25 @@ function validateRunEvent(value, file) {
16366
16375
  )]);
16367
16376
  }
16368
16377
  }
16378
+ function validateDriveReceipt(value, file) {
16379
+ const registry = cachedRunEventRegistry ??= new VnextSchemaRegistry();
16380
+ if (!value || typeof value !== "object" || Array.isArray(value) || value.schema !== "kxm.drive-receipt.v1") {
16381
+ throw new VnextConfigError([issue2(
16382
+ "schema",
16383
+ "drive_receipt_invalid",
16384
+ file,
16385
+ "expected kxm.drive-receipt.v1"
16386
+ )]);
16387
+ }
16388
+ if (!registry.driveReceiptValidator(value)) {
16389
+ throw new VnextConfigError([issue2(
16390
+ "schema",
16391
+ "drive_receipt_invalid",
16392
+ file,
16393
+ registry.ajv.errorsText(registry.driveReceiptValidator.errors, { separator: "; " })
16394
+ )]);
16395
+ }
16396
+ }
16369
16397
  function schemaIssue(file, error) {
16370
16398
  const location = error.instancePath || "/";
16371
16399
  const suffix = error.params && "additionalProperty" in error.params ? ` (${String(error.params.additionalProperty)})` : "";
@@ -17817,7 +17845,36 @@ var VnextRuntimeRegistry = class {
17817
17845
  }
17818
17846
  };
17819
17847
  var VNEXT_RUN_EVENT_SCHEMA = "kxm.run-event.v1";
17820
- var VNEXT_EVENT_STORE_SCHEMA_VERSION = 3;
17848
+ function hashVnextDriveLog(events) {
17849
+ const body = events.map((event) => `${event.eventId}:${event.sequence}`).join("\n");
17850
+ return `sha256:${createHash3("sha256").update(body, "utf8").digest("hex")}`;
17851
+ }
17852
+ function verifyVnextDriveReceipt(receipt, events, foldedStatus, binding) {
17853
+ const reasons = [];
17854
+ if (receipt.runId !== binding.runId) {
17855
+ reasons.push(`runId ${receipt.runId} != binding ${binding.runId}`);
17856
+ }
17857
+ if (receipt.driveId !== binding.driveId) {
17858
+ reasons.push(`driveId ${receipt.driveId} != binding ${binding.driveId}`);
17859
+ }
17860
+ const last = events[events.length - 1];
17861
+ const currentLast = last?.sequence ?? 0;
17862
+ if (receipt.lastSequence !== currentLast) {
17863
+ reasons.push(`lastSequence ${receipt.lastSequence} != log ${currentLast}`);
17864
+ }
17865
+ const prefix = events.filter((event) => event.sequence >= 1 && event.sequence <= receipt.lastSequence);
17866
+ if (hashVnextDriveLog(prefix) !== receipt.logHash) {
17867
+ reasons.push("logHash mismatch");
17868
+ }
17869
+ if (receipt.settlement.status !== foldedStatus) {
17870
+ reasons.push(`settlement.status ${receipt.settlement.status} != folded ${foldedStatus}`);
17871
+ }
17872
+ if (reasons.length === 0) return { verified: true };
17873
+ return { verified: false, divergence: reasons.join("; ") };
17874
+ }
17875
+ var VNEXT_EVENT_STORE_SCHEMA_VERSION = 4;
17876
+ var VNEXT_DRIVE_RECEIPT_SCHEMA = "kxm.drive-receipt.v1";
17877
+ var DRIVE_RECEIPT_MAX_BYTES = 8 * 1024;
17821
17878
  var EVENT_STORE_TABLES = {
17822
17879
  runs: ["run_id", "project_id", "home_runtime_id", "workflow_id", "prompt_sha256", "status", "config_revision", "memory_revision", "executor_policy_revision", "tool_policy_revision", "created_at", "updated_at"],
17823
17880
  events: ["project_id", "run_id", "sequence", "event_id", "event_type", "command_id", "occurred_at", "recorded_at", "monotonic_ns", "config_revision", "memory_revision", "executor_policy_revision", "tool_policy_revision", "payload", "schema", "home_runtime_id"],
@@ -17896,7 +17953,8 @@ var EVENT_STORE_TABLES = {
17896
17953
  "outcome",
17897
17954
  "settled_event_id",
17898
17955
  "content_hash"
17899
- ]
17956
+ ],
17957
+ drive_receipts: ["drive_id", "run_id", "project_id", "opened_sequence", "last_sequence", "closed_at", "schema", "receipt"]
17900
17958
  };
17901
17959
  var EVENT_STORE_SCHEMA = `
17902
17960
  CREATE TABLE runs (
@@ -18038,7 +18096,40 @@ CREATE TABLE gate_evidence (
18038
18096
  ) STRICT;
18039
18097
  CREATE UNIQUE INDEX gate_evidence_key ON gate_evidence(run_id, step_id, step_attempt, evidence_key) WHERE evidence_key IS NOT NULL;
18040
18098
  CREATE INDEX gate_evidence_run ON gate_evidence(run_id);
18099
+ CREATE TABLE drive_receipts (
18100
+ drive_id TEXT PRIMARY KEY,
18101
+ run_id TEXT NOT NULL,
18102
+ project_id TEXT NOT NULL,
18103
+ opened_sequence INTEGER NOT NULL,
18104
+ last_sequence INTEGER NOT NULL,
18105
+ closed_at TEXT NOT NULL,
18106
+ schema TEXT NOT NULL,
18107
+ receipt TEXT NOT NULL
18108
+ ) STRICT;
18109
+ CREATE INDEX drive_receipts_run ON drive_receipts(run_id);
18041
18110
  `;
18111
+ var DRIVE_RECEIPTS_DDL = `
18112
+ CREATE TABLE IF NOT EXISTS drive_receipts (
18113
+ drive_id TEXT PRIMARY KEY,
18114
+ run_id TEXT NOT NULL,
18115
+ project_id TEXT NOT NULL,
18116
+ opened_sequence INTEGER NOT NULL,
18117
+ last_sequence INTEGER NOT NULL,
18118
+ closed_at TEXT NOT NULL,
18119
+ schema TEXT NOT NULL,
18120
+ receipt TEXT NOT NULL
18121
+ ) STRICT;
18122
+ CREATE INDEX IF NOT EXISTS drive_receipts_run ON drive_receipts(run_id);
18123
+ `;
18124
+ var EVENT_STORE_MIGRATIONS = [
18125
+ {
18126
+ fromVersion: 3,
18127
+ toVersion: 4,
18128
+ migrate(database) {
18129
+ database.exec(DRIVE_RECEIPTS_DDL);
18130
+ }
18131
+ }
18132
+ ];
18042
18133
  var VnextRunEventStore = class {
18043
18134
  path;
18044
18135
  database;
@@ -18047,7 +18138,8 @@ var VnextRunEventStore = class {
18047
18138
  this.database = openDatabase(this.path, "run event store", {
18048
18139
  schema: EVENT_STORE_SCHEMA,
18049
18140
  version: VNEXT_EVENT_STORE_SCHEMA_VERSION,
18050
- tables: EVENT_STORE_TABLES
18141
+ tables: EVENT_STORE_TABLES,
18142
+ migrations: EVENT_STORE_MIGRATIONS
18051
18143
  });
18052
18144
  }
18053
18145
  close() {
@@ -18204,6 +18296,38 @@ var VnextRunEventStore = class {
18204
18296
  ON CONFLICT(run_id) DO UPDATE SET last_sequence = excluded.last_sequence, state = excluded.state
18205
18297
  `).run(row.runId, row.lastSequence, row.state);
18206
18298
  }
18299
+ insertDriveReceipt(receipt) {
18300
+ validateDriveReceipt(receipt, "drive-receipt");
18301
+ const canonical = vnextCanonicalJson(receipt);
18302
+ if (Buffer.byteLength(canonical, "utf8") > DRIVE_RECEIPT_MAX_BYTES) {
18303
+ throw runtimeError("drive_receipt_invalid", receipt.driveId, `drive receipt exceeds ${DRIVE_RECEIPT_MAX_BYTES} bytes`);
18304
+ }
18305
+ const result = this.database.prepare(`
18306
+ INSERT INTO drive_receipts (drive_id, run_id, project_id, opened_sequence, last_sequence, closed_at, schema, receipt)
18307
+ VALUES (?, ?, ?, ?, ?, ?, ?, ?)
18308
+ ON CONFLICT(drive_id) DO NOTHING
18309
+ `).run(
18310
+ receipt.driveId,
18311
+ receipt.runId,
18312
+ receipt.projectId,
18313
+ receipt.openedSequence,
18314
+ receipt.lastSequence,
18315
+ receipt.closedAt,
18316
+ receipt.schema,
18317
+ canonical
18318
+ );
18319
+ return { inserted: Number(result.changes) === 1 };
18320
+ }
18321
+ driveReceipt(driveId) {
18322
+ const row = this.database.prepare("SELECT receipt FROM drive_receipts WHERE drive_id = ?").get(driveId);
18323
+ return row ? parseDriveReceipt(row.receipt) : void 0;
18324
+ }
18325
+ driveReceiptsForRun(runId, limit = 20) {
18326
+ const rows = this.database.prepare(`
18327
+ SELECT receipt FROM drive_receipts WHERE run_id = ? ORDER BY closed_at DESC, drive_id DESC LIMIT ?
18328
+ `).all(runId, limit);
18329
+ return rows.map((row) => parseDriveReceipt(row.receipt));
18330
+ }
18207
18331
  insertCapability(row) {
18208
18332
  this.database.prepare(`
18209
18333
  INSERT INTO attempt_capabilities (attempt_id, run_id, assignment_id, step_id, step_attempt, producer_id, capability_hash, state)
@@ -18438,6 +18562,11 @@ var VnextRunEventStore = class {
18438
18562
  }
18439
18563
  }
18440
18564
  };
18565
+ function parseDriveReceipt(raw) {
18566
+ const parsed = JSON.parse(raw);
18567
+ validateDriveReceipt(parsed, "drive-receipt");
18568
+ return parsed;
18569
+ }
18441
18570
  function runFromRow(row) {
18442
18571
  if (typeof row.memory_revision !== "string" || row.memory_revision.length === 0) {
18443
18572
  throw runtimeError("runtime_schema_shape_invalid", row.run_id, "memory_revision is required");
@@ -18833,6 +18962,16 @@ var ATTEMPT_EDGES = {
18833
18962
  executing: /* @__PURE__ */ new Set(["settling"]),
18834
18963
  settling: /* @__PURE__ */ new Set(["terminal"])
18835
18964
  };
18965
+ function effectiveRunDurationBudget(planLimits, projectLimits) {
18966
+ const workflow = planLimits?.maxRunDurationMs;
18967
+ const project = projectLimits?.maxRunDurationMs;
18968
+ if (workflow === void 0 && project === void 0) return void 0;
18969
+ if (workflow !== void 0 && project !== void 0) {
18970
+ return { budgetMs: Math.min(workflow, project), source: "both" };
18971
+ }
18972
+ if (workflow !== void 0) return { budgetMs: workflow, source: "workflow" };
18973
+ return { budgetMs: project, source: "project" };
18974
+ }
18836
18975
  function emptyPanel() {
18837
18976
  return { order: [], assignments: /* @__PURE__ */ Object.create(null) };
18838
18977
  }
@@ -19064,7 +19203,10 @@ function foldVnextRunState(run, plan, events, options = {}) {
19064
19203
  foldRunStatus(state, plan, event);
19065
19204
  break;
19066
19205
  case "run.cancel_requested":
19067
- foldCancelRequested(state, event);
19206
+ foldCancelRequested(state, event, plan, options);
19207
+ break;
19208
+ case "run.drive_opened":
19209
+ foldDriveOpened(state, event);
19068
19210
  break;
19069
19211
  case "step.entered":
19070
19212
  foldStepEntered(state, plan, event);
@@ -19190,6 +19332,9 @@ function foldRunStatus(state, plan, event) {
19190
19332
  if ((status === "running" || status === "cancelling") && !plan) {
19191
19333
  throw runtimeError("run_plan_missing", state.runId, `status ${status} requires a pinned run plan`);
19192
19334
  }
19335
+ if (status === "running" && state.runningSince === void 0) {
19336
+ state.runningSince = event.occurredAt;
19337
+ }
19193
19338
  if (TERMINAL_RUN.has(status)) {
19194
19339
  assertTerminalRunStatus(state, plan, status, event);
19195
19340
  if (typeof event.payload.reason === "string") state.terminalReason = event.payload.reason;
@@ -19277,10 +19422,47 @@ function isProvenFailure(state, plan) {
19277
19422
  const used = state.stepAttempts[stepId] ?? 0;
19278
19423
  return Boolean(step && used >= step.maxAttempts);
19279
19424
  }
19280
- function foldCancelRequested(state, event) {
19425
+ function foldDriveOpened(state, event) {
19426
+ if (state.status !== "running" && state.status !== "blocked_uncertain") {
19427
+ throw runtimeError("run_events_illegal", state.runId, "run.drive_opened is only legal while running or blocked_uncertain");
19428
+ }
19429
+ const driveId = stringPayload(event, "driveId");
19430
+ const mode = stringPayload(event, "mode");
19431
+ if (mode !== "simulated" && mode !== "live") {
19432
+ throw runtimeError("run_events_illegal", state.runId, "run.drive_opened mode must be simulated or live");
19433
+ }
19434
+ state.drive = { driveId, mode, openedSequence: event.sequence };
19435
+ }
19436
+ function foldCancelRequested(state, event, plan, options) {
19281
19437
  if (state.cancelRequested || TERMINAL_RUN.has(state.status)) {
19282
19438
  throw runtimeError("run_events_illegal", state.runId, "duplicate run.cancel_requested is not legal");
19283
19439
  }
19440
+ if (event.payload.reason === "budget_run_duration") {
19441
+ const budget = event.payload.budget;
19442
+ if (!budget || typeof budget !== "object" || Array.isArray(budget)) {
19443
+ throw runtimeError("run_events_illegal", state.runId, "budget_run_duration requires a budget payload");
19444
+ }
19445
+ const body = budget;
19446
+ const budgetMs = body.budgetMs;
19447
+ const elapsedMs = body.elapsedMs;
19448
+ const source = body.source;
19449
+ if (typeof budgetMs !== "number" || !Number.isInteger(budgetMs) || budgetMs < 0) {
19450
+ throw runtimeError("run_events_illegal", state.runId, "budget_run_duration budgetMs is invalid");
19451
+ }
19452
+ if (typeof elapsedMs !== "number" || !Number.isInteger(elapsedMs) || elapsedMs < 0) {
19453
+ throw runtimeError("run_events_illegal", state.runId, "budget_run_duration elapsedMs is invalid");
19454
+ }
19455
+ if (source !== "workflow" && source !== "project" && source !== "both") {
19456
+ throw runtimeError("run_events_illegal", state.runId, "budget_run_duration source is invalid");
19457
+ }
19458
+ const expected = effectiveRunDurationBudget(plan?.limits, options.projectLimits);
19459
+ if (!expected || expected.budgetMs !== budgetMs || expected.source !== source) {
19460
+ throw runtimeError("run_events_illegal", state.runId, "budget_run_duration budgetMs does not match the plan");
19461
+ }
19462
+ if (elapsedMs < budgetMs) {
19463
+ throw runtimeError("run_events_illegal", state.runId, "budget_run_duration elapsedMs is below budgetMs");
19464
+ }
19465
+ }
19284
19466
  state.cancelRequested = true;
19285
19467
  if (event.commandId) state.cancelCommandId = event.commandId;
19286
19468
  }
@@ -19925,7 +20107,9 @@ function freezeState(state) {
19925
20107
  transitionsUsed: state.transitionsUsed,
19926
20108
  cancelRequested: state.cancelRequested,
19927
20109
  ...state.terminalReason !== void 0 ? { terminalReason: state.terminalReason } : {},
19928
- ...state.terminalReason !== void 0 && state.status === "failed" ? { failureReason: state.terminalReason } : {}
20110
+ ...state.terminalReason !== void 0 && state.status === "failed" ? { failureReason: state.terminalReason } : {},
20111
+ ...state.drive !== void 0 ? { drive: Object.freeze({ ...state.drive }) } : {},
20112
+ ...state.runningSince !== void 0 ? { runningSince: state.runningSince } : {}
19929
20113
  };
19930
20114
  return Object.freeze(frozen);
19931
20115
  }
@@ -21815,7 +21999,8 @@ function foldStoredVnextRun(context, run) {
21815
21999
  const step = envelope.plan.steps[stepId];
21816
22000
  if (!step || step.kind !== "gate") return void 0;
21817
22001
  return envelope.gates.definitions[step.gate]?.kind;
21818
- }
22002
+ },
22003
+ projectLimits: envelope.projectLimits
21819
22004
  } : {});
21820
22005
  if (envelope) verifyVnextGateEvidence(context.eventStore, run, envelope, events, state);
21821
22006
  assertStoredProjection(context, run);
@@ -21922,10 +22107,17 @@ function cancelVnextRun(context, runId, options = {}) {
21922
22107
  };
21923
22108
  const cancelReason = options.reason ?? "operator_cancel";
21924
22109
  const activeAttempt = Boolean(folded.currentStep?.attemptId) || vnextFoldPanelAttemptIds(folded.currentStep).length > 0;
21925
- push("run.cancel_requested", {
22110
+ const cancelPayload = {
21926
22111
  actor: { kind: "runtime", id: context.homeRuntimeId },
21927
22112
  reason: cancelReason
21928
- });
22113
+ };
22114
+ if (cancelReason === "budget_run_duration") {
22115
+ if (!options.budget) {
22116
+ throw runtimeError("run_events_illegal", runId, "budget_run_duration requires a budget payload");
22117
+ }
22118
+ cancelPayload.budget = options.budget;
22119
+ }
22120
+ push("run.cancel_requested", cancelPayload);
21929
22121
  let status = "cancelled";
21930
22122
  if (folded.status === "running" && activeAttempt) {
21931
22123
  status = "cancelling";
@@ -23262,7 +23454,7 @@ function recordGateNoStartInTransaction(context, run, envelope, stepId, observat
23262
23454
  const cancelled = observation.stopCause === "cancel";
23263
23455
  const now = (/* @__PURE__ */ new Date()).toISOString();
23264
23456
  const seq = sequencer(context, run, now);
23265
- if (cancelled) ensureOperatorCancel(seq, ids.state, run);
23457
+ const cancelReason = cancelled ? ensureOperatorCancel(seq, ids.state, run, context) : void 0;
23266
23458
  const observationId = newVnextObservationId();
23267
23459
  const observed = seq.push("effect.observed", {
23268
23460
  effect: { id: ids.effectId, policy: { class: ids.gateKind === "artifacts-exist" ? "read-only" : "unknown", sharedMutable: false } },
@@ -23294,7 +23486,7 @@ function recordGateNoStartInTransaction(context, run, envelope, stepId, observat
23294
23486
  seq.push("attempt.status_changed", { attemptId: ids.attemptId, status: "terminal" });
23295
23487
  seq.push("assignment.terminal", { assignmentId: ids.assignmentId, outcome: "cancelled", status: "terminal" });
23296
23488
  seq.push("step.status_changed", { stepId, status: "cancelled", previousStatus: "running" });
23297
- seq.push("run.status_changed", { status: "cancelled", reason: "operator_cancel", stepId });
23489
+ seq.push("run.status_changed", { status: "cancelled", reason: cancelReason ?? "operator_cancel", stepId });
23298
23490
  } else {
23299
23491
  seq.push("assignment.result_recorded", { assignmentId: ids.assignmentId, resultClass: "producer_rejected", status: "result_recorded" });
23300
23492
  seq.push("attempt.status_changed", { attemptId: ids.attemptId, status: "terminal" });
@@ -23348,7 +23540,7 @@ function recordGateCancelObservedInTransaction(context, run, envelope, stepId, o
23348
23540
  }
23349
23541
  const now = (/* @__PURE__ */ new Date()).toISOString();
23350
23542
  const seq = sequencer(context, run, now);
23351
- ensureOperatorCancel(seq, ids.state, run);
23543
+ const cancelReason = ensureOperatorCancel(seq, ids.state, run, context);
23352
23544
  if (ids.gateKind === "artifacts-exist") {
23353
23545
  seq.push("assignment.executing", { assignmentId: ids.assignmentId, stepId, stepAttempt: ids.stepAttempt, attemptId: ids.attemptId, status: "executing" });
23354
23546
  seq.push("attempt.status_changed", { attemptId: ids.attemptId, assignmentId: ids.assignmentId, stepId, stepAttempt: ids.stepAttempt, status: "executing" });
@@ -23391,7 +23583,7 @@ function recordGateCancelObservedInTransaction(context, run, envelope, stepId, o
23391
23583
  seq.push("attempt.status_changed", { attemptId: ids.attemptId, status: "terminal" });
23392
23584
  seq.push("assignment.terminal", { assignmentId: ids.assignmentId, outcome: "cancelled", status: "terminal" });
23393
23585
  seq.push("step.status_changed", { stepId, status: "cancelled", previousStatus: "running" });
23394
- seq.push("run.status_changed", { status: "cancelled", reason: "operator_cancel", stepId });
23586
+ seq.push("run.status_changed", { status: "cancelled", reason: cancelReason, stepId });
23395
23587
  for (const event of seq.events) context.eventStore.appendEvent(event);
23396
23588
  context.eventStore.insertGateObservation(observationRow);
23397
23589
  context.eventStore.settleCapability(ids.attemptId, "settled");
@@ -23476,8 +23668,8 @@ function requireIntent(context, run, envelope, stepId) {
23476
23668
  state: folded
23477
23669
  };
23478
23670
  }
23479
- function ensureOperatorCancel(seq, state, run) {
23480
- if (state.status === "cancelling") return;
23671
+ function ensureOperatorCancel(seq, state, run, context) {
23672
+ if (state.status === "cancelling") return cancelReasonFromLog(context, run.runId);
23481
23673
  if (state.status !== "running") {
23482
23674
  throw runtimeError("run_events_illegal", run.runId, "cancelled gate proof requires a running or cancelling run");
23483
23675
  }
@@ -23486,6 +23678,17 @@ function ensureOperatorCancel(seq, state, run) {
23486
23678
  reason: "operator_cancel"
23487
23679
  });
23488
23680
  seq.push("run.status_changed", { status: "cancelling", reason: "operator_cancel" });
23681
+ return "operator_cancel";
23682
+ }
23683
+ function cancelReasonFromLog(context, runId) {
23684
+ const events = context.eventStore.events(runId, 0, 1e6);
23685
+ for (let index = events.length - 1; index >= 0; index -= 1) {
23686
+ const event = events[index];
23687
+ if (event.eventType === "run.cancel_requested" && typeof event.payload.reason === "string") {
23688
+ return event.payload.reason;
23689
+ }
23690
+ }
23691
+ return "operator_cancel";
23489
23692
  }
23490
23693
  function sequencer(context, run, now) {
23491
23694
  let sequence = context.eventStore.nextSequence(run.runId);
@@ -23824,6 +24027,8 @@ async function driveAdmitted(context, runId, producer, token, options = {}) {
23824
24027
  }
23825
24028
  let latest = { state: foldStoredVnextRun(context, requireRun(context, runId)) };
23826
24029
  while (latest.state.status === "running") {
24030
+ const overBudget = cancelRunDurationIfExceeded(context, runId);
24031
+ if (overBudget) return overBudget;
23827
24032
  const before = context.eventStore.runState(runId)?.lastSequence;
23828
24033
  latest = await stepLocked(context, runId, producer, token);
23829
24034
  if (latest.handoff) return latest;
@@ -23839,6 +24044,111 @@ async function driveAdmitted(context, runId, producer, token, options = {}) {
23839
24044
  function newDriveId(runId, token, runtimeId, monotonicNs) {
23840
24045
  return `drv_${createHash10("sha256").update(`${runId}\0${token}\0${runtimeId}\0${monotonicNs}`, "utf8").digest("hex").slice(0, 24)}`;
23841
24046
  }
24047
+ function driveErrorSummary(error) {
24048
+ const raw = error instanceof VnextConfigError ? error.issues[0]?.code : void 0;
24049
+ const className = raw && /^[a-z][a-z0-9]*(?:[-_][a-z0-9]+)*$/.test(raw) ? raw : "drive-failure";
24050
+ return { class: className, component: "vnext-engine", retryable: false };
24051
+ }
24052
+ function receiptHandoff(handoff) {
24053
+ return {
24054
+ reason: handoff.reason,
24055
+ detail: handoff.detail,
24056
+ ...handoff.field !== void 0 ? { field: handoff.field } : {},
24057
+ ...handoff.stepId !== void 0 ? { stepId: handoff.stepId } : {}
24058
+ };
24059
+ }
24060
+ function appendDriveOpened(context, runId, driveId, mode) {
24061
+ return context.eventStore.transaction(() => {
24062
+ const run = requireRun(context, runId);
24063
+ const now = (/* @__PURE__ */ new Date()).toISOString();
24064
+ const sequence = context.eventStore.nextSequence(runId);
24065
+ const event = {
24066
+ ...vnextEventBase(context, run, now, vnextMonotonicNs()),
24067
+ eventId: newVnextEventId(),
24068
+ eventType: "run.drive_opened",
24069
+ sequence,
24070
+ payload: { driveId, mode }
24071
+ };
24072
+ context.eventStore.appendEvent(event);
24073
+ const next = foldStoredVnextRun(context, run);
24074
+ persistVnextRunState(context, runId, next, sequence);
24075
+ return { sequence, occurredAt: now };
24076
+ });
24077
+ }
24078
+ function recordDriveReceipt(context, session, closeInfo) {
24079
+ if (isVnextRuntimeContextClosed(context)) return;
24080
+ try {
24081
+ const run = context.eventStore.run(session.runId);
24082
+ if (!run) return;
24083
+ const state = foldStoredVnextRun(context, run);
24084
+ const events = context.eventStore.events(session.runId, 0, 1e6);
24085
+ if (events.length === 0) return;
24086
+ const opened = state.drive;
24087
+ const openedEvent = opened ? events.find((event) => event.sequence === opened.openedSequence && event.eventType === "run.drive_opened") : events.find((event) => event.eventType === "run.drive_opened" && event.payload.driveId === session.driveId);
24088
+ const last = events[events.length - 1];
24089
+ const openedSequence = opened?.openedSequence ?? openedEvent?.sequence;
24090
+ if (openedSequence === void 0) return;
24091
+ const closedAt = (/* @__PURE__ */ new Date()).toISOString();
24092
+ const receipt = {
24093
+ schema: VNEXT_DRIVE_RECEIPT_SCHEMA,
24094
+ driveId: session.driveId,
24095
+ runId: session.runId,
24096
+ projectId: run.projectId,
24097
+ homeRuntimeId: session.homeRuntimeId,
24098
+ mode: session.mode,
24099
+ openedAt: openedEvent?.occurredAt ?? session.openedAt,
24100
+ openedSequence,
24101
+ closedAt,
24102
+ lastSequence: last.sequence,
24103
+ logHash: hashVnextDriveLog(events.filter((event) => event.sequence >= 1 && event.sequence <= last.sequence)),
24104
+ settlement: {
24105
+ kind: closeInfo.kind,
24106
+ status: state.status,
24107
+ reason: closeInfo.reason ?? state.terminalReason ?? "",
24108
+ ...closeInfo.kind === "handoff" && closeInfo.handoff ? { handoff: receiptHandoff(closeInfo.handoff) } : {},
24109
+ ...closeInfo.error !== void 0 ? { error: closeInfo.error } : {}
24110
+ },
24111
+ budget: driveReceiptBudget(context, run.runId, state, events, closedAt),
24112
+ producer: { id: closeInfo.producerId, closed: closeInfo.producerClosed }
24113
+ };
24114
+ context.eventStore.insertDriveReceipt(receipt);
24115
+ } catch {
24116
+ }
24117
+ }
24118
+ function vnextDrivePollProjection(context, runId, state) {
24119
+ if (!state.drive) return void 0;
24120
+ const events = context.eventStore.events(runId, 0, 1e6);
24121
+ const openedEvent = events.find((event) => event.sequence === state.drive.openedSequence);
24122
+ let receipt = null;
24123
+ let unreadable = false;
24124
+ try {
24125
+ receipt = context.eventStore.driveReceipt(state.drive.driveId) ?? null;
24126
+ } catch {
24127
+ unreadable = true;
24128
+ }
24129
+ const projection = {
24130
+ driveId: state.drive.driveId,
24131
+ mode: state.drive.mode,
24132
+ openedAt: openedEvent?.occurredAt ?? "",
24133
+ receipt: unreadable ? null : receipt,
24134
+ verified: false
24135
+ };
24136
+ if (unreadable) {
24137
+ projection.divergence = "receipt unreadable";
24138
+ return projection;
24139
+ }
24140
+ if (!receipt) {
24141
+ projection.divergence = "no receipt";
24142
+ return projection;
24143
+ }
24144
+ const checked = verifyVnextDriveReceipt(receipt, events, state.status, {
24145
+ runId,
24146
+ driveId: state.drive.driveId
24147
+ });
24148
+ projection.verified = checked.verified;
24149
+ if (checked.divergence !== void 0) projection.divergence = checked.divergence;
24150
+ return projection;
24151
+ }
23842
24152
  function inflightAttemptId(state) {
23843
24153
  const leftover = unreconciledPanelAttemptId(state);
23844
24154
  if (leftover) return leftover;
@@ -23986,25 +24296,50 @@ var VnextRunScheduler = class _VnextRunScheduler {
23986
24296
  throw error;
23987
24297
  }
23988
24298
  const driveId = newDriveId(runId, token, this.context.homeRuntimeId, vnextMonotonicNs());
24299
+ const openedMeta = appendDriveOpened(this.context, runId, driveId, options.mode);
24300
+ const startedState = foldStoredVnextRun(this.context, requireRun(this.context, runId));
24301
+ const deadlineAt = driveDeadlineAt(this.context, runId, startedState);
23989
24302
  const session = {
23990
24303
  driveId,
23991
24304
  runId,
23992
24305
  token,
23993
24306
  homeRuntimeId: this.context.homeRuntimeId,
23994
24307
  mode: options.mode,
23995
- openedAt: (/* @__PURE__ */ new Date()).toISOString(),
24308
+ openedAt: openedMeta.occurredAt,
24309
+ producerId: producer.id,
23996
24310
  controller: new AbortController(),
23997
- settled
24311
+ settled,
24312
+ ...deadlineAt !== void 0 ? { deadlineAt } : {}
23998
24313
  };
23999
24314
  attachVnextDriveSession(this.context.eventStore.path, runId, token, session);
24000
24315
  opened = true;
24001
24316
  resolveOpen({ driveId, settled });
24002
24317
  try {
24003
24318
  const result = await driveAdmitted(this.context, runId, producer, token, driveOptions);
24319
+ const kind = result.handoff ? "handoff" : isTerminalRunStatus(result.state.status) ? "terminal" : "unsettled";
24320
+ recordDriveReceipt(this.context, session, {
24321
+ kind,
24322
+ ...result.state.terminalReason !== void 0 ? { reason: result.state.terminalReason } : result.handoff ? { reason: result.handoff.reason } : {},
24323
+ ...result.handoff ? { handoff: result.handoff } : {},
24324
+ producerId: producer.id,
24325
+ producerClosed: false
24326
+ });
24004
24327
  pending.resolve(result);
24005
24328
  return result;
24006
24329
  } catch (error) {
24007
24330
  recordBareDriveFailure(this.context, runId);
24331
+ let foldedStatus;
24332
+ try {
24333
+ foldedStatus = foldStoredVnextRun(this.context, requireRun(this.context, runId)).status;
24334
+ } catch {
24335
+ foldedStatus = void 0;
24336
+ }
24337
+ recordDriveReceipt(this.context, session, {
24338
+ kind: foldedStatus !== void 0 && isTerminalRunStatus(foldedStatus) ? "terminal" : "unsettled",
24339
+ error: driveErrorSummary(error),
24340
+ producerId: producer.id,
24341
+ producerClosed: false
24342
+ });
24008
24343
  pending.reject(error);
24009
24344
  throw error;
24010
24345
  }
@@ -24053,11 +24388,13 @@ async function stepLocked(context, runId, producer, token) {
24053
24388
  throw runtimeError("run_events_illegal", prepared.run.runId, "prepared gate is not artifacts-exist");
24054
24389
  }
24055
24390
  registerVnextAttemptController(context.eventStore.path, runId, { attemptId: prepared.attemptId, controller: prepared.controller });
24391
+ const clearBudget = armRunDurationBudgetTimer(context, runId);
24056
24392
  try {
24057
24393
  const observation = evaluateArtifactsGate(context, definition);
24058
24394
  vnextGateDispatchSeams.afterEvaluate?.(prepared);
24059
24395
  return context.eventStore.transaction(() => settlePreparedGate(context, prepared, observation));
24060
24396
  } finally {
24397
+ clearBudget();
24061
24398
  unregisterVnextAttemptController(context.eventStore.path, runId, prepared.attemptId);
24062
24399
  }
24063
24400
  }
@@ -24088,6 +24425,7 @@ async function runPreparedCommandGate(context, prepared, definition, token) {
24088
24425
  });
24089
24426
  armVnextGateHold(storePath, prepared.run.runId, token, prepared.attemptId, () => observer.requestStop("cancel"));
24090
24427
  registerVnextAttemptController(storePath, prepared.run.runId, { attemptId: prepared.attemptId, controller: prepared.controller });
24428
+ const clearBudget = armRunDurationBudgetTimer(context, prepared.run.runId);
24091
24429
  const unhookClose = registerVnextRuntimeCloseHook(context, () => {
24092
24430
  try {
24093
24431
  markVnextGateHoldUnsettled(storePath, prepared.run.runId, token, prepared.attemptId);
@@ -24128,6 +24466,7 @@ async function runPreparedCommandGate(context, prepared, definition, token) {
24128
24466
  return commitCommandUncertainty(context, prepared, token, outcome.reason, outcome.observation);
24129
24467
  } finally {
24130
24468
  unhookClose();
24469
+ clearBudget();
24131
24470
  unregisterVnextAttemptController(storePath, prepared.run.runId, prepared.attemptId);
24132
24471
  }
24133
24472
  }
@@ -24753,8 +25092,10 @@ async function drivePanel(context, panel, producer) {
24753
25092
  const pending = /* @__PURE__ */ new Map();
24754
25093
  let stopBirths = false;
24755
25094
  let settlementFailed = false;
25095
+ const budgetClears = /* @__PURE__ */ new Map();
24756
25096
  const register = (member) => {
24757
25097
  registerVnextAttemptController(context.eventStore.path, runId, { attemptId: member.attemptId, controller: member.controller });
25098
+ budgetClears.set(member.attemptId, armRunDurationBudgetTimer(context, runId));
24758
25099
  owned.set(member.attemptId, member);
24759
25100
  };
24760
25101
  const abortOwned = () => {
@@ -24937,6 +25278,7 @@ async function drivePanel(context, panel, producer) {
24937
25278
  throw error;
24938
25279
  } finally {
24939
25280
  for (const attemptId of owned.keys()) {
25281
+ budgetClears.get(attemptId)?.();
24940
25282
  unregisterVnextAttemptController(context.eventStore.path, runId, attemptId);
24941
25283
  }
24942
25284
  }
@@ -25116,7 +25458,7 @@ function joinPanel(context, panel) {
25116
25458
  };
25117
25459
  const cancelRun = () => {
25118
25460
  push("step.status_changed", { stepId: panel.stepId, status: "cancelled", previousStatus: "running" });
25119
- push("run.status_changed", { status: "cancelled", reason: "operator_cancel" });
25461
+ push("run.status_changed", { status: "cancelled", reason: cancelReasonFromLog2(context, run.runId) });
25120
25462
  for (const event of events) context.eventStore.appendEvent(event);
25121
25463
  const next2 = foldStoredVnextRun(context, run);
25122
25464
  persistVnextRunState(context, run.runId, next2, events[events.length - 1].sequence);
@@ -25223,16 +25565,124 @@ function transitionBudgetFailure(plan, state, fromStepId, outcome) {
25223
25565
  }
25224
25566
  return void 0;
25225
25567
  }
25226
- function unsupportedLimit(envelope) {
25227
- if (envelope.plan.limits.maxRunDurationMs !== void 0) {
25228
- return { reason: "limit_unsupported", field: "limits.maxRunDurationMs", detail: "duration budget enforcement is not available in this slice" };
25568
+ var MAX_TIMER_DELAY_MS = 2147483647;
25569
+ function elapsedMsBetween(fromIso, toIso) {
25570
+ const from = Date.parse(fromIso);
25571
+ const to = Date.parse(toIso);
25572
+ if (!Number.isFinite(from) || !Number.isFinite(to)) return 0;
25573
+ return Math.max(0, Math.trunc(to - from));
25574
+ }
25575
+ function declaredRunDurationBudget(context, runId) {
25576
+ const run = context.eventStore.run(runId);
25577
+ if (!run) return void 0;
25578
+ try {
25579
+ const envelope = loadVnextRunPlanEnvelope(context.eventStore, run);
25580
+ return effectiveRunDurationBudget(envelope.plan.limits, envelope.projectLimits);
25581
+ } catch {
25582
+ return void 0;
25229
25583
  }
25584
+ }
25585
+ function runDurationOverrunPayload(context, runId, nowIso = (/* @__PURE__ */ new Date()).toISOString()) {
25586
+ const declared = declaredRunDurationBudget(context, runId);
25587
+ if (!declared) return void 0;
25588
+ const run = context.eventStore.run(runId);
25589
+ if (!run) return void 0;
25590
+ const state = foldStoredVnextRun(context, run);
25591
+ if (!state.runningSince) return void 0;
25592
+ if (isTerminalRunStatus(state.status) || state.status === "cancelling") return void 0;
25593
+ const elapsedMs = elapsedMsBetween(state.runningSince, nowIso);
25594
+ if (elapsedMs < declared.budgetMs) return void 0;
25595
+ return { budgetMs: declared.budgetMs, elapsedMs, source: declared.source };
25596
+ }
25597
+ function cancelRunDurationIfExceeded(context, runId) {
25598
+ if (isVnextRuntimeContextClosed(context)) return void 0;
25599
+ const payload = runDurationOverrunPayload(context, runId);
25600
+ if (!payload) return void 0;
25601
+ cancelVnextRun(context, runId, { reason: "budget_run_duration", budget: payload });
25602
+ return { state: foldStoredVnextRun(context, requireRun(context, runId)) };
25603
+ }
25604
+ function driveDeadlineAt(context, runId, state) {
25605
+ const declared = declaredRunDurationBudget(context, runId);
25606
+ if (!declared || !state.runningSince) return void 0;
25607
+ const start = Date.parse(state.runningSince);
25608
+ if (!Number.isFinite(start)) return void 0;
25609
+ return new Date(start + declared.budgetMs).toISOString();
25610
+ }
25611
+ function driveReceiptBudget(context, runId, state, events, closedAt) {
25612
+ const declared = declaredRunDurationBudget(context, runId);
25613
+ if (!declared) return null;
25614
+ const elapsedMs = state.runningSince ? elapsedMsBetween(state.runningSince, closedAt) : 0;
25615
+ const overrun = events.some((event) => event.eventType === "run.cancel_requested" && event.payload.reason === "budget_run_duration");
25616
+ return {
25617
+ budgetMs: declared.budgetMs,
25618
+ source: declared.source,
25619
+ elapsedMs,
25620
+ overrun
25621
+ };
25622
+ }
25623
+ function cancelReasonFromLog2(context, runId) {
25624
+ const events = context.eventStore.events(runId, 0, 1e6);
25625
+ for (let index = events.length - 1; index >= 0; index -= 1) {
25626
+ const event = events[index];
25627
+ if (event.eventType === "run.cancel_requested" && typeof event.payload.reason === "string") {
25628
+ return event.payload.reason;
25629
+ }
25630
+ }
25631
+ return "operator_cancel";
25632
+ }
25633
+ function armRunDurationBudgetTimer(context, runId) {
25634
+ const declared = declaredRunDurationBudget(context, runId);
25635
+ if (!declared) return () => void 0;
25636
+ const run = context.eventStore.run(runId);
25637
+ if (!run) return () => void 0;
25638
+ const state = foldStoredVnextRun(context, run);
25639
+ if (!state.runningSince) return () => void 0;
25640
+ const startMs = Date.parse(state.runningSince);
25641
+ if (!Number.isFinite(startMs)) return () => void 0;
25642
+ const deadlineMs = startMs + declared.budgetMs;
25643
+ let timer;
25644
+ let cleared = false;
25645
+ const fire = () => {
25646
+ timer = void 0;
25647
+ if (cleared || isVnextRuntimeContextClosed(context)) return;
25648
+ const nowIso = (/* @__PURE__ */ new Date()).toISOString();
25649
+ const elapsedMs = elapsedMsBetween(state.runningSince, nowIso);
25650
+ if (elapsedMs < declared.budgetMs) {
25651
+ arm(declared.budgetMs - elapsedMs);
25652
+ return;
25653
+ }
25654
+ try {
25655
+ cancelVnextRun(context, runId, {
25656
+ reason: "budget_run_duration",
25657
+ budget: { budgetMs: declared.budgetMs, elapsedMs, source: declared.source }
25658
+ });
25659
+ } catch {
25660
+ }
25661
+ };
25662
+ const arm = (remaining) => {
25663
+ if (cleared) return;
25664
+ const delay = Math.min(Math.max(0, remaining), MAX_TIMER_DELAY_MS);
25665
+ timer = setTimeout(fire, delay);
25666
+ timer.unref();
25667
+ };
25668
+ const unhook = registerVnextRuntimeCloseHook(context, () => {
25669
+ cleared = true;
25670
+ if (timer !== void 0) clearTimeout(timer);
25671
+ timer = void 0;
25672
+ });
25673
+ arm(deadlineMs - Date.now());
25674
+ return () => {
25675
+ if (cleared) return;
25676
+ cleared = true;
25677
+ if (timer !== void 0) clearTimeout(timer);
25678
+ timer = void 0;
25679
+ unhook();
25680
+ };
25681
+ }
25682
+ function unsupportedLimit(envelope) {
25230
25683
  if (envelope.plan.limits.maxAgentTimeMs !== void 0) {
25231
25684
  return { reason: "limit_unsupported", field: "limits.maxAgentTimeMs", detail: "agent-time budget enforcement is not available in this slice" };
25232
25685
  }
25233
- if (envelope.projectLimits.maxRunDurationMs !== void 0) {
25234
- return { reason: "limit_unsupported", field: "project.limits.maxRunDurationMs", detail: "duration budget enforcement is not available in this slice" };
25235
- }
25236
25686
  if (envelope.projectLimits.maxAgentTimeMs !== void 0) {
25237
25687
  return { reason: "limit_unsupported", field: "project.limits.maxAgentTimeMs", detail: "agent-time budget enforcement is not available in this slice" };
25238
25688
  }
@@ -26248,6 +26698,19 @@ async function waitForDriveSessions(settled, graceMs) {
26248
26698
  if (timeout !== void 0) clearTimeout(timeout);
26249
26699
  }
26250
26700
  }
26701
+ async function driveSessionStillPending(settled) {
26702
+ let pending = true;
26703
+ void settled.then(
26704
+ () => {
26705
+ pending = false;
26706
+ },
26707
+ () => {
26708
+ pending = false;
26709
+ }
26710
+ );
26711
+ await Promise.resolve();
26712
+ return pending;
26713
+ }
26251
26714
  async function startVnextRuntimeSupervisor(options = {}) {
26252
26715
  const now = options.now ?? (() => (/* @__PURE__ */ new Date()).toISOString());
26253
26716
  const paths = vnextRuntimePaths(options.stateRoot !== void 0 ? { stateRoot: options.stateRoot } : {});
@@ -26351,7 +26814,9 @@ async function startVnextRuntimeSupervisorInner(paths, requestedPortOption, now)
26351
26814
  const bundle = loadVnextProject(projectRoot, {});
26352
26815
  if (request.method === "GET" && !sub) {
26353
26816
  const projected = rebuildVnextRunProjection(context, runId);
26354
- sendJson(response, 200, { ok: true, run: projected });
26817
+ const folded = foldStoredVnextRun(context, projected);
26818
+ const drive = vnextDrivePollProjection(context, runId, folded);
26819
+ sendJson(response, 200, { ok: true, run: projected, ...drive !== void 0 ? { drive } : {} });
26355
26820
  return;
26356
26821
  }
26357
26822
  if (request.method === "POST" && sub === "drive") {
@@ -26394,7 +26859,7 @@ async function startVnextRuntimeSupervisorInner(paths, requestedPortOption, now)
26394
26859
  const scheduler = VnextRunScheduler.for(context, bundle);
26395
26860
  const opening = scheduler.openDriveSession(runId, {
26396
26861
  mode: body.mode,
26397
- allowLimits: true,
26862
+ allowLimits: false,
26398
26863
  liveMode: body.mode === "live",
26399
26864
  createProducer
26400
26865
  });
@@ -26568,6 +27033,15 @@ async function startVnextRuntimeSupervisorInner(paths, requestedPortOption, now)
26568
27033
  }
26569
27034
  }
26570
27035
  await waitForDriveSessions(openSessions.map(({ session }) => session.settled), runtimeStopGraceMs());
27036
+ for (const { context, session } of openSessions) {
27037
+ if (!await driveSessionStillPending(session.settled)) continue;
27038
+ recordDriveReceipt(context, session, {
27039
+ kind: "unsettled",
27040
+ reason: "runtime_shutdown_grace_expired",
27041
+ producerId: session.producerId,
27042
+ producerClosed: false
27043
+ });
27044
+ }
26571
27045
  for (const context of contexts.values()) closeVnextRuntimeContext(context);
26572
27046
  contexts.clear();
26573
27047
  const closed = new Promise((resolveStop) => server.close(() => resolveStop()));