@kontextmind/kxm 0.7.24 → 0.7.26

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.
@@ -18764,9 +18764,15 @@ var VnextRunEventStore = class {
18764
18764
  }
18765
18765
  driveReceiptsForRun(runId, limit = 20) {
18766
18766
  const rows = this.database.prepare(`
18767
- SELECT receipt FROM drive_receipts WHERE run_id = ? ORDER BY closed_at DESC, drive_id DESC LIMIT ?
18767
+ SELECT drive_id, receipt FROM drive_receipts WHERE run_id = ? ORDER BY closed_at DESC, drive_id DESC LIMIT ?
18768
18768
  `).all(runId, limit);
18769
- return rows.map((row) => parseDriveReceipt(row.receipt));
18769
+ return rows.map((row) => {
18770
+ try {
18771
+ return parseDriveReceipt(row.receipt);
18772
+ } catch {
18773
+ return { driveId: row.drive_id, divergence: "receipt unreadable" };
18774
+ }
18775
+ });
18770
18776
  }
18771
18777
  insertCapability(row) {
18772
18778
  this.database.prepare(`
@@ -19397,6 +19403,16 @@ var ATTEMPT_EDGES = {
19397
19403
  executing: /* @__PURE__ */ new Set(["settling"]),
19398
19404
  settling: /* @__PURE__ */ new Set(["terminal"])
19399
19405
  };
19406
+ function effectiveRunDurationBudget(planLimits, projectLimits) {
19407
+ const workflow = planLimits?.maxRunDurationMs;
19408
+ const project = projectLimits?.maxRunDurationMs;
19409
+ if (workflow === void 0 && project === void 0) return void 0;
19410
+ if (workflow !== void 0 && project !== void 0) {
19411
+ return { budgetMs: Math.min(workflow, project), source: "both" };
19412
+ }
19413
+ if (workflow !== void 0) return { budgetMs: workflow, source: "workflow" };
19414
+ return { budgetMs: project, source: "project" };
19415
+ }
19400
19416
  function emptyPanel() {
19401
19417
  return { order: [], assignments: /* @__PURE__ */ Object.create(null) };
19402
19418
  }
@@ -19628,7 +19644,7 @@ function foldVnextRunState(run, plan, events, options = {}) {
19628
19644
  foldRunStatus(state, plan, event);
19629
19645
  break;
19630
19646
  case "run.cancel_requested":
19631
- foldCancelRequested(state, event);
19647
+ foldCancelRequested(state, event, plan, options);
19632
19648
  break;
19633
19649
  case "run.drive_opened":
19634
19650
  foldDriveOpened(state, event);
@@ -19757,6 +19773,9 @@ function foldRunStatus(state, plan, event) {
19757
19773
  if ((status === "running" || status === "cancelling") && !plan) {
19758
19774
  throw runtimeError("run_plan_missing", state.runId, `status ${status} requires a pinned run plan`);
19759
19775
  }
19776
+ if (status === "running" && state.runningSince === void 0) {
19777
+ state.runningSince = event.occurredAt;
19778
+ }
19760
19779
  if (TERMINAL_RUN.has(status)) {
19761
19780
  assertTerminalRunStatus(state, plan, status, event);
19762
19781
  if (typeof event.payload.reason === "string") state.terminalReason = event.payload.reason;
@@ -19855,10 +19874,36 @@ function foldDriveOpened(state, event) {
19855
19874
  }
19856
19875
  state.drive = { driveId, mode, openedSequence: event.sequence };
19857
19876
  }
19858
- function foldCancelRequested(state, event) {
19877
+ function foldCancelRequested(state, event, plan, options) {
19859
19878
  if (state.cancelRequested || TERMINAL_RUN.has(state.status)) {
19860
19879
  throw runtimeError("run_events_illegal", state.runId, "duplicate run.cancel_requested is not legal");
19861
19880
  }
19881
+ if (event.payload.reason === "budget_run_duration") {
19882
+ const budget = event.payload.budget;
19883
+ if (!budget || typeof budget !== "object" || Array.isArray(budget)) {
19884
+ throw runtimeError("run_events_illegal", state.runId, "budget_run_duration requires a budget payload");
19885
+ }
19886
+ const body = budget;
19887
+ const budgetMs = body.budgetMs;
19888
+ const elapsedMs = body.elapsedMs;
19889
+ const source = body.source;
19890
+ if (typeof budgetMs !== "number" || !Number.isInteger(budgetMs) || budgetMs < 0) {
19891
+ throw runtimeError("run_events_illegal", state.runId, "budget_run_duration budgetMs is invalid");
19892
+ }
19893
+ if (typeof elapsedMs !== "number" || !Number.isInteger(elapsedMs) || elapsedMs < 0) {
19894
+ throw runtimeError("run_events_illegal", state.runId, "budget_run_duration elapsedMs is invalid");
19895
+ }
19896
+ if (source !== "workflow" && source !== "project" && source !== "both") {
19897
+ throw runtimeError("run_events_illegal", state.runId, "budget_run_duration source is invalid");
19898
+ }
19899
+ const expected = effectiveRunDurationBudget(plan?.limits, options.projectLimits);
19900
+ if (!expected || expected.budgetMs !== budgetMs || expected.source !== source) {
19901
+ throw runtimeError("run_events_illegal", state.runId, "budget_run_duration budgetMs does not match the plan");
19902
+ }
19903
+ if (elapsedMs < budgetMs) {
19904
+ throw runtimeError("run_events_illegal", state.runId, "budget_run_duration elapsedMs is below budgetMs");
19905
+ }
19906
+ }
19862
19907
  state.cancelRequested = true;
19863
19908
  if (event.commandId) state.cancelCommandId = event.commandId;
19864
19909
  }
@@ -20504,7 +20549,8 @@ function freezeState(state) {
20504
20549
  cancelRequested: state.cancelRequested,
20505
20550
  ...state.terminalReason !== void 0 ? { terminalReason: state.terminalReason } : {},
20506
20551
  ...state.terminalReason !== void 0 && state.status === "failed" ? { failureReason: state.terminalReason } : {},
20507
- ...state.drive !== void 0 ? { drive: Object.freeze({ ...state.drive }) } : {}
20552
+ ...state.drive !== void 0 ? { drive: Object.freeze({ ...state.drive }) } : {},
20553
+ ...state.runningSince !== void 0 ? { runningSince: state.runningSince } : {}
20508
20554
  };
20509
20555
  return Object.freeze(frozen);
20510
20556
  }
@@ -22063,6 +22109,9 @@ function clearVnextDriveSession(storePath, runId, token) {
22063
22109
  if (!current || current.token !== token) return;
22064
22110
  delete current.driveSession;
22065
22111
  }
22112
+ function vnextDriveSession(storePath, runId) {
22113
+ return owners.get(storePath)?.admitted.get(runId)?.driveSession;
22114
+ }
22066
22115
  function vnextOpenDriveSessions(storePath) {
22067
22116
  const owner = owners.get(storePath);
22068
22117
  if (!owner) return [];
@@ -22402,7 +22451,8 @@ function foldStoredVnextRun(context, run) {
22402
22451
  const step = envelope.plan.steps[stepId];
22403
22452
  if (!step || step.kind !== "gate") return void 0;
22404
22453
  return envelope.gates.definitions[step.gate]?.kind;
22405
- }
22454
+ },
22455
+ projectLimits: envelope.projectLimits
22406
22456
  } : {});
22407
22457
  if (envelope) verifyVnextGateEvidence(context.eventStore, run, envelope, events, state);
22408
22458
  assertStoredProjection(context, run);
@@ -22512,10 +22562,17 @@ function cancelVnextRun(context, runId, options = {}) {
22512
22562
  };
22513
22563
  const cancelReason = options.reason ?? "operator_cancel";
22514
22564
  const activeAttempt = Boolean(folded.currentStep?.attemptId) || vnextFoldPanelAttemptIds(folded.currentStep).length > 0;
22515
- push("run.cancel_requested", {
22565
+ const cancelPayload = {
22516
22566
  actor: { kind: "runtime", id: context.homeRuntimeId },
22517
22567
  reason: cancelReason
22518
- });
22568
+ };
22569
+ if (cancelReason === "budget_run_duration") {
22570
+ if (!options.budget) {
22571
+ throw runtimeError("run_events_illegal", runId, "budget_run_duration requires a budget payload");
22572
+ }
22573
+ cancelPayload.budget = options.budget;
22574
+ }
22575
+ push("run.cancel_requested", cancelPayload);
22519
22576
  let status = "cancelled";
22520
22577
  if (folded.status === "running" && activeAttempt) {
22521
22578
  status = "cancelling";
@@ -23892,7 +23949,7 @@ function recordGateNoStartInTransaction(context, run, envelope, stepId, observat
23892
23949
  const cancelled = observation.stopCause === "cancel";
23893
23950
  const now = (/* @__PURE__ */ new Date()).toISOString();
23894
23951
  const seq = sequencer(context, run, now);
23895
- if (cancelled) ensureOperatorCancel(seq, ids.state, run);
23952
+ const cancelReason = cancelled ? ensureOperatorCancel(seq, ids.state, run, context) : void 0;
23896
23953
  const observationId = newVnextObservationId();
23897
23954
  const observed = seq.push("effect.observed", {
23898
23955
  effect: { id: ids.effectId, policy: { class: ids.gateKind === "artifacts-exist" ? "read-only" : "unknown", sharedMutable: false } },
@@ -23924,7 +23981,7 @@ function recordGateNoStartInTransaction(context, run, envelope, stepId, observat
23924
23981
  seq.push("attempt.status_changed", { attemptId: ids.attemptId, status: "terminal" });
23925
23982
  seq.push("assignment.terminal", { assignmentId: ids.assignmentId, outcome: "cancelled", status: "terminal" });
23926
23983
  seq.push("step.status_changed", { stepId, status: "cancelled", previousStatus: "running" });
23927
- seq.push("run.status_changed", { status: "cancelled", reason: "operator_cancel", stepId });
23984
+ seq.push("run.status_changed", { status: "cancelled", reason: cancelReason ?? "operator_cancel", stepId });
23928
23985
  } else {
23929
23986
  seq.push("assignment.result_recorded", { assignmentId: ids.assignmentId, resultClass: "producer_rejected", status: "result_recorded" });
23930
23987
  seq.push("attempt.status_changed", { attemptId: ids.attemptId, status: "terminal" });
@@ -23978,7 +24035,7 @@ function recordGateCancelObservedInTransaction(context, run, envelope, stepId, o
23978
24035
  }
23979
24036
  const now = (/* @__PURE__ */ new Date()).toISOString();
23980
24037
  const seq = sequencer(context, run, now);
23981
- ensureOperatorCancel(seq, ids.state, run);
24038
+ const cancelReason = ensureOperatorCancel(seq, ids.state, run, context);
23982
24039
  if (ids.gateKind === "artifacts-exist") {
23983
24040
  seq.push("assignment.executing", { assignmentId: ids.assignmentId, stepId, stepAttempt: ids.stepAttempt, attemptId: ids.attemptId, status: "executing" });
23984
24041
  seq.push("attempt.status_changed", { attemptId: ids.attemptId, assignmentId: ids.assignmentId, stepId, stepAttempt: ids.stepAttempt, status: "executing" });
@@ -24021,7 +24078,7 @@ function recordGateCancelObservedInTransaction(context, run, envelope, stepId, o
24021
24078
  seq.push("attempt.status_changed", { attemptId: ids.attemptId, status: "terminal" });
24022
24079
  seq.push("assignment.terminal", { assignmentId: ids.assignmentId, outcome: "cancelled", status: "terminal" });
24023
24080
  seq.push("step.status_changed", { stepId, status: "cancelled", previousStatus: "running" });
24024
- seq.push("run.status_changed", { status: "cancelled", reason: "operator_cancel", stepId });
24081
+ seq.push("run.status_changed", { status: "cancelled", reason: cancelReason, stepId });
24025
24082
  for (const event of seq.events) context.eventStore.appendEvent(event);
24026
24083
  context.eventStore.insertGateObservation(observationRow);
24027
24084
  context.eventStore.settleCapability(ids.attemptId, "settled");
@@ -24106,8 +24163,8 @@ function requireIntent(context, run, envelope, stepId) {
24106
24163
  state: folded
24107
24164
  };
24108
24165
  }
24109
- function ensureOperatorCancel(seq, state, run) {
24110
- if (state.status === "cancelling") return;
24166
+ function ensureOperatorCancel(seq, state, run, context) {
24167
+ if (state.status === "cancelling") return cancelReasonFromLog(context, run.runId);
24111
24168
  if (state.status !== "running") {
24112
24169
  throw runtimeError("run_events_illegal", run.runId, "cancelled gate proof requires a running or cancelling run");
24113
24170
  }
@@ -24116,6 +24173,17 @@ function ensureOperatorCancel(seq, state, run) {
24116
24173
  reason: "operator_cancel"
24117
24174
  });
24118
24175
  seq.push("run.status_changed", { status: "cancelling", reason: "operator_cancel" });
24176
+ return "operator_cancel";
24177
+ }
24178
+ function cancelReasonFromLog(context, runId) {
24179
+ const events = context.eventStore.events(runId, 0, 1e6);
24180
+ for (let index = events.length - 1; index >= 0; index -= 1) {
24181
+ const event = events[index];
24182
+ if (event.eventType === "run.cancel_requested" && typeof event.payload.reason === "string") {
24183
+ return event.payload.reason;
24184
+ }
24185
+ }
24186
+ return "operator_cancel";
24119
24187
  }
24120
24188
  function sequencer(context, run, now) {
24121
24189
  let sequence = context.eventStore.nextSequence(run.runId);
@@ -24454,6 +24522,8 @@ async function driveAdmitted(context, runId, producer, token, options = {}) {
24454
24522
  }
24455
24523
  let latest = { state: foldStoredVnextRun(context, requireRun(context, runId)) };
24456
24524
  while (latest.state.status === "running") {
24525
+ const overBudget = cancelRunDurationIfExceeded(context, runId);
24526
+ if (overBudget) return overBudget;
24457
24527
  const before = context.eventStore.runState(runId)?.lastSequence;
24458
24528
  latest = await stepLocked(context, runId, producer, token);
24459
24529
  if (latest.handoff) return latest;
@@ -24513,6 +24583,7 @@ function recordDriveReceipt(context, session, closeInfo) {
24513
24583
  const last = events[events.length - 1];
24514
24584
  const openedSequence = opened?.openedSequence ?? openedEvent?.sequence;
24515
24585
  if (openedSequence === void 0) return;
24586
+ const closedAt = (/* @__PURE__ */ new Date()).toISOString();
24516
24587
  const receipt = {
24517
24588
  schema: VNEXT_DRIVE_RECEIPT_SCHEMA,
24518
24589
  driveId: session.driveId,
@@ -24522,7 +24593,7 @@ function recordDriveReceipt(context, session, closeInfo) {
24522
24593
  mode: session.mode,
24523
24594
  openedAt: openedEvent?.occurredAt ?? session.openedAt,
24524
24595
  openedSequence,
24525
- closedAt: (/* @__PURE__ */ new Date()).toISOString(),
24596
+ closedAt,
24526
24597
  lastSequence: last.sequence,
24527
24598
  logHash: hashVnextDriveLog(events.filter((event) => event.sequence >= 1 && event.sequence <= last.sequence)),
24528
24599
  settlement: {
@@ -24532,7 +24603,7 @@ function recordDriveReceipt(context, session, closeInfo) {
24532
24603
  ...closeInfo.kind === "handoff" && closeInfo.handoff ? { handoff: receiptHandoff(closeInfo.handoff) } : {},
24533
24604
  ...closeInfo.error !== void 0 ? { error: closeInfo.error } : {}
24534
24605
  },
24535
- budget: null,
24606
+ budget: driveReceiptBudget(context, run.runId, state, events, closedAt),
24536
24607
  producer: { id: closeInfo.producerId, closed: closeInfo.producerClosed }
24537
24608
  };
24538
24609
  context.eventStore.insertDriveReceipt(receipt);
@@ -24721,6 +24792,8 @@ var VnextRunScheduler = class _VnextRunScheduler {
24721
24792
  }
24722
24793
  const driveId = newDriveId(runId, token, this.context.homeRuntimeId, vnextMonotonicNs());
24723
24794
  const openedMeta = appendDriveOpened(this.context, runId, driveId, options.mode);
24795
+ const startedState = foldStoredVnextRun(this.context, requireRun(this.context, runId));
24796
+ const deadlineAt = driveDeadlineAt(this.context, runId, startedState);
24724
24797
  const session = {
24725
24798
  driveId,
24726
24799
  runId,
@@ -24730,7 +24803,8 @@ var VnextRunScheduler = class _VnextRunScheduler {
24730
24803
  openedAt: openedMeta.occurredAt,
24731
24804
  producerId: producer.id,
24732
24805
  controller: new AbortController(),
24733
- settled
24806
+ settled,
24807
+ ...deadlineAt !== void 0 ? { deadlineAt } : {}
24734
24808
  };
24735
24809
  attachVnextDriveSession(this.context.eventStore.path, runId, token, session);
24736
24810
  opened = true;
@@ -24809,11 +24883,13 @@ async function stepLocked(context, runId, producer, token) {
24809
24883
  throw runtimeError("run_events_illegal", prepared.run.runId, "prepared gate is not artifacts-exist");
24810
24884
  }
24811
24885
  registerVnextAttemptController(context.eventStore.path, runId, { attemptId: prepared.attemptId, controller: prepared.controller });
24886
+ const clearBudget = armRunDurationBudgetTimer(context, runId);
24812
24887
  try {
24813
24888
  const observation = evaluateArtifactsGate(context, definition);
24814
24889
  vnextGateDispatchSeams.afterEvaluate?.(prepared);
24815
24890
  return context.eventStore.transaction(() => settlePreparedGate(context, prepared, observation));
24816
24891
  } finally {
24892
+ clearBudget();
24817
24893
  unregisterVnextAttemptController(context.eventStore.path, runId, prepared.attemptId);
24818
24894
  }
24819
24895
  }
@@ -24844,6 +24920,7 @@ async function runPreparedCommandGate(context, prepared, definition, token) {
24844
24920
  });
24845
24921
  armVnextGateHold(storePath, prepared.run.runId, token, prepared.attemptId, () => observer.requestStop("cancel"));
24846
24922
  registerVnextAttemptController(storePath, prepared.run.runId, { attemptId: prepared.attemptId, controller: prepared.controller });
24923
+ const clearBudget = armRunDurationBudgetTimer(context, prepared.run.runId);
24847
24924
  const unhookClose = registerVnextRuntimeCloseHook(context, () => {
24848
24925
  try {
24849
24926
  markVnextGateHoldUnsettled(storePath, prepared.run.runId, token, prepared.attemptId);
@@ -24884,6 +24961,7 @@ async function runPreparedCommandGate(context, prepared, definition, token) {
24884
24961
  return commitCommandUncertainty(context, prepared, token, outcome.reason, outcome.observation);
24885
24962
  } finally {
24886
24963
  unhookClose();
24964
+ clearBudget();
24887
24965
  unregisterVnextAttemptController(storePath, prepared.run.runId, prepared.attemptId);
24888
24966
  }
24889
24967
  }
@@ -25509,8 +25587,10 @@ async function drivePanel(context, panel, producer) {
25509
25587
  const pending = /* @__PURE__ */ new Map();
25510
25588
  let stopBirths = false;
25511
25589
  let settlementFailed = false;
25590
+ const budgetClears = /* @__PURE__ */ new Map();
25512
25591
  const register = (member) => {
25513
25592
  registerVnextAttemptController(context.eventStore.path, runId, { attemptId: member.attemptId, controller: member.controller });
25593
+ budgetClears.set(member.attemptId, armRunDurationBudgetTimer(context, runId));
25514
25594
  owned.set(member.attemptId, member);
25515
25595
  };
25516
25596
  const abortOwned = () => {
@@ -25693,6 +25773,7 @@ async function drivePanel(context, panel, producer) {
25693
25773
  throw error;
25694
25774
  } finally {
25695
25775
  for (const attemptId of owned.keys()) {
25776
+ budgetClears.get(attemptId)?.();
25696
25777
  unregisterVnextAttemptController(context.eventStore.path, runId, attemptId);
25697
25778
  }
25698
25779
  }
@@ -25872,7 +25953,7 @@ function joinPanel(context, panel) {
25872
25953
  };
25873
25954
  const cancelRun = () => {
25874
25955
  push("step.status_changed", { stepId: panel.stepId, status: "cancelled", previousStatus: "running" });
25875
- push("run.status_changed", { status: "cancelled", reason: "operator_cancel" });
25956
+ push("run.status_changed", { status: "cancelled", reason: cancelReasonFromLog2(context, run.runId) });
25876
25957
  for (const event of events) context.eventStore.appendEvent(event);
25877
25958
  const next2 = foldStoredVnextRun(context, run);
25878
25959
  persistVnextRunState(context, run.runId, next2, events[events.length - 1].sequence);
@@ -25979,16 +26060,124 @@ function transitionBudgetFailure(plan, state, fromStepId, outcome) {
25979
26060
  }
25980
26061
  return void 0;
25981
26062
  }
25982
- function unsupportedLimit(envelope) {
25983
- if (envelope.plan.limits.maxRunDurationMs !== void 0) {
25984
- return { reason: "limit_unsupported", field: "limits.maxRunDurationMs", detail: "duration budget enforcement is not available in this slice" };
26063
+ var MAX_TIMER_DELAY_MS = 2147483647;
26064
+ function elapsedMsBetween(fromIso, toIso) {
26065
+ const from = Date.parse(fromIso);
26066
+ const to = Date.parse(toIso);
26067
+ if (!Number.isFinite(from) || !Number.isFinite(to)) return 0;
26068
+ return Math.max(0, Math.trunc(to - from));
26069
+ }
26070
+ function declaredRunDurationBudget(context, runId) {
26071
+ const run = context.eventStore.run(runId);
26072
+ if (!run) return void 0;
26073
+ try {
26074
+ const envelope = loadVnextRunPlanEnvelope(context.eventStore, run);
26075
+ return effectiveRunDurationBudget(envelope.plan.limits, envelope.projectLimits);
26076
+ } catch {
26077
+ return void 0;
26078
+ }
26079
+ }
26080
+ function runDurationOverrunPayload(context, runId, nowIso2 = (/* @__PURE__ */ new Date()).toISOString()) {
26081
+ const declared = declaredRunDurationBudget(context, runId);
26082
+ if (!declared) return void 0;
26083
+ const run = context.eventStore.run(runId);
26084
+ if (!run) return void 0;
26085
+ const state = foldStoredVnextRun(context, run);
26086
+ if (!state.runningSince) return void 0;
26087
+ if (isTerminalRunStatus(state.status) || state.status === "cancelling") return void 0;
26088
+ const elapsedMs = elapsedMsBetween(state.runningSince, nowIso2);
26089
+ if (elapsedMs < declared.budgetMs) return void 0;
26090
+ return { budgetMs: declared.budgetMs, elapsedMs, source: declared.source };
26091
+ }
26092
+ function cancelRunDurationIfExceeded(context, runId) {
26093
+ if (isVnextRuntimeContextClosed(context)) return void 0;
26094
+ const payload = runDurationOverrunPayload(context, runId);
26095
+ if (!payload) return void 0;
26096
+ cancelVnextRun(context, runId, { reason: "budget_run_duration", budget: payload });
26097
+ return { state: foldStoredVnextRun(context, requireRun(context, runId)) };
26098
+ }
26099
+ function driveDeadlineAt(context, runId, state) {
26100
+ const declared = declaredRunDurationBudget(context, runId);
26101
+ if (!declared || !state.runningSince) return void 0;
26102
+ const start = Date.parse(state.runningSince);
26103
+ if (!Number.isFinite(start)) return void 0;
26104
+ return new Date(start + declared.budgetMs).toISOString();
26105
+ }
26106
+ function driveReceiptBudget(context, runId, state, events, closedAt) {
26107
+ const declared = declaredRunDurationBudget(context, runId);
26108
+ if (!declared) return null;
26109
+ const elapsedMs = state.runningSince ? elapsedMsBetween(state.runningSince, closedAt) : 0;
26110
+ const overrun = events.some((event) => event.eventType === "run.cancel_requested" && event.payload.reason === "budget_run_duration");
26111
+ return {
26112
+ budgetMs: declared.budgetMs,
26113
+ source: declared.source,
26114
+ elapsedMs,
26115
+ overrun
26116
+ };
26117
+ }
26118
+ function cancelReasonFromLog2(context, runId) {
26119
+ const events = context.eventStore.events(runId, 0, 1e6);
26120
+ for (let index = events.length - 1; index >= 0; index -= 1) {
26121
+ const event = events[index];
26122
+ if (event.eventType === "run.cancel_requested" && typeof event.payload.reason === "string") {
26123
+ return event.payload.reason;
26124
+ }
25985
26125
  }
26126
+ return "operator_cancel";
26127
+ }
26128
+ function armRunDurationBudgetTimer(context, runId) {
26129
+ const declared = declaredRunDurationBudget(context, runId);
26130
+ if (!declared) return () => void 0;
26131
+ const run = context.eventStore.run(runId);
26132
+ if (!run) return () => void 0;
26133
+ const state = foldStoredVnextRun(context, run);
26134
+ if (!state.runningSince) return () => void 0;
26135
+ const startMs = Date.parse(state.runningSince);
26136
+ if (!Number.isFinite(startMs)) return () => void 0;
26137
+ const deadlineMs = startMs + declared.budgetMs;
26138
+ let timer;
26139
+ let cleared = false;
26140
+ const fire = () => {
26141
+ timer = void 0;
26142
+ if (cleared || isVnextRuntimeContextClosed(context)) return;
26143
+ const nowIso2 = (/* @__PURE__ */ new Date()).toISOString();
26144
+ const elapsedMs = elapsedMsBetween(state.runningSince, nowIso2);
26145
+ if (elapsedMs < declared.budgetMs) {
26146
+ arm(declared.budgetMs - elapsedMs);
26147
+ return;
26148
+ }
26149
+ try {
26150
+ cancelVnextRun(context, runId, {
26151
+ reason: "budget_run_duration",
26152
+ budget: { budgetMs: declared.budgetMs, elapsedMs, source: declared.source }
26153
+ });
26154
+ } catch {
26155
+ }
26156
+ };
26157
+ const arm = (remaining) => {
26158
+ if (cleared) return;
26159
+ const delay = Math.min(Math.max(0, remaining), MAX_TIMER_DELAY_MS);
26160
+ timer = setTimeout(fire, delay);
26161
+ timer.unref();
26162
+ };
26163
+ const unhook = registerVnextRuntimeCloseHook(context, () => {
26164
+ cleared = true;
26165
+ if (timer !== void 0) clearTimeout(timer);
26166
+ timer = void 0;
26167
+ });
26168
+ arm(deadlineMs - Date.now());
26169
+ return () => {
26170
+ if (cleared) return;
26171
+ cleared = true;
26172
+ if (timer !== void 0) clearTimeout(timer);
26173
+ timer = void 0;
26174
+ unhook();
26175
+ };
26176
+ }
26177
+ function unsupportedLimit(envelope) {
25986
26178
  if (envelope.plan.limits.maxAgentTimeMs !== void 0) {
25987
26179
  return { reason: "limit_unsupported", field: "limits.maxAgentTimeMs", detail: "agent-time budget enforcement is not available in this slice" };
25988
26180
  }
25989
- if (envelope.projectLimits.maxRunDurationMs !== void 0) {
25990
- return { reason: "limit_unsupported", field: "project.limits.maxRunDurationMs", detail: "duration budget enforcement is not available in this slice" };
25991
- }
25992
26181
  if (envelope.projectLimits.maxAgentTimeMs !== void 0) {
25993
26182
  return { reason: "limit_unsupported", field: "project.limits.maxAgentTimeMs", detail: "agent-time budget enforcement is not available in this slice" };
25994
26183
  }
@@ -27165,7 +27354,7 @@ async function startVnextRuntimeSupervisorInner(paths, requestedPortOption, now)
27165
27354
  const scheduler = VnextRunScheduler.for(context, bundle);
27166
27355
  const opening = scheduler.openDriveSession(runId, {
27167
27356
  mode: body.mode,
27168
- allowLimits: true,
27357
+ allowLimits: false,
27169
27358
  liveMode: body.mode === "live",
27170
27359
  createProducer
27171
27360
  });
@@ -27208,6 +27397,20 @@ async function startVnextRuntimeSupervisorInner(paths, requestedPortOption, now)
27208
27397
  sendJson(response, 200, { ok: true, events });
27209
27398
  return;
27210
27399
  }
27400
+ if (request.method === "GET" && sub === "drive") {
27401
+ const run = context.eventStore.run(runId);
27402
+ if (!run) throw runtimeError("run_unknown", runId, "run not found");
27403
+ const activeSession = vnextDriveSession(context.eventStore.path, runId);
27404
+ const session = activeSession ? {
27405
+ driveId: activeSession.driveId,
27406
+ mode: activeSession.mode,
27407
+ openedAt: activeSession.openedAt,
27408
+ deadlineAt: activeSession.deadlineAt ?? null
27409
+ } : null;
27410
+ const receipts = context.eventStore.driveReceiptsForRun(runId, 20);
27411
+ sendJson(response, 200, { ok: true, session, receipts });
27412
+ return;
27413
+ }
27211
27414
  if (request.method === "POST" && sub === "cancel") {
27212
27415
  const body = await readJsonBody(request);
27213
27416
  const result = cancelVnextRun(context, runId, {
@@ -27241,6 +27444,43 @@ async function startVnextRuntimeSupervisorInner(paths, requestedPortOption, now)
27241
27444
  return;
27242
27445
  }
27243
27446
  }
27447
+ const driveMatch = /^\/v1\/drives\/([A-Za-z0-9_-]+)$/.exec(url.pathname);
27448
+ if (request.method === "GET" && driveMatch) {
27449
+ const driveId = driveMatch[1];
27450
+ const projectRoot = url.searchParams.get("projectRoot") ?? "";
27451
+ if (!projectRoot) {
27452
+ sendJson(response, 400, { ok: false, error: "runtime_request_invalid", message: "projectRoot query parameter is required" });
27453
+ return;
27454
+ }
27455
+ const context = contextFor(projectRoot);
27456
+ let receipt;
27457
+ try {
27458
+ receipt = context.eventStore.driveReceipt(driveId);
27459
+ } catch {
27460
+ sendJson(response, 200, { ok: true, receipt: null, verified: false, divergence: "receipt unreadable" });
27461
+ return;
27462
+ }
27463
+ if (!receipt) {
27464
+ sendJson(response, 404, { ok: false, error: "drive_receipt_missing", message: "receipt not found" });
27465
+ return;
27466
+ }
27467
+ const runId = receipt.runId;
27468
+ const stored = context.eventStore.run(runId);
27469
+ if (!stored) {
27470
+ sendJson(response, 200, { ok: true, receipt, verified: false, divergence: "run missing" });
27471
+ return;
27472
+ }
27473
+ const state = foldStoredVnextRun(context, stored);
27474
+ const events = context.eventStore.events(runId, 0, 1e6);
27475
+ const checked = verifyVnextDriveReceipt(receipt, events, state.status, { runId, driveId });
27476
+ sendJson(response, 200, {
27477
+ ok: true,
27478
+ receipt,
27479
+ verified: checked.verified,
27480
+ ...checked.divergence !== void 0 ? { divergence: checked.divergence } : {}
27481
+ });
27482
+ return;
27483
+ }
27244
27484
  const projectRunsMatch = /^\/v1\/projects\/(prj_[A-Za-z0-9_-]+)\/runs$/.exec(url.pathname);
27245
27485
  if (request.method === "GET" && projectRunsMatch) {
27246
27486
  const projectRoot = url.searchParams.get("projectRoot") ?? "";