@positronic/cloudflare 0.0.67 → 0.0.69

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (37) hide show
  1. package/dist/src/api/auth-middleware.js +25 -0
  2. package/dist/src/api/brains.js +67 -16
  3. package/dist/src/api/secrets.js +3 -0
  4. package/dist/src/brain-runner-do.js +51 -5
  5. package/dist/src/create-r2-store.js +319 -0
  6. package/dist/src/dev-server.js +19 -1
  7. package/dist/src/governor-client-wrapper.js +364 -0
  8. package/dist/src/governor-do.js +387 -0
  9. package/dist/src/index.js +3 -0
  10. package/dist/src/monitor-do.js +25 -12
  11. package/dist/src/rate-limit-headers.js +199 -0
  12. package/dist/src/schedule-do.js +38 -22
  13. package/dist/src/token-estimator.js +39 -0
  14. package/dist/types/api/auth-middleware.d.ts +5 -0
  15. package/dist/types/api/auth-middleware.d.ts.map +1 -1
  16. package/dist/types/api/brains.d.ts.map +1 -1
  17. package/dist/types/api/secrets.d.ts.map +1 -1
  18. package/dist/types/brain-runner-do.d.ts +9 -1
  19. package/dist/types/brain-runner-do.d.ts.map +1 -1
  20. package/dist/types/create-r2-store.d.ts +14 -0
  21. package/dist/types/create-r2-store.d.ts.map +1 -0
  22. package/dist/types/dev-server.d.ts.map +1 -1
  23. package/dist/types/governor-client-wrapper.d.ts +15 -0
  24. package/dist/types/governor-client-wrapper.d.ts.map +1 -0
  25. package/dist/types/governor-do.d.ts +25 -0
  26. package/dist/types/governor-do.d.ts.map +1 -0
  27. package/dist/types/index.d.ts +3 -0
  28. package/dist/types/index.d.ts.map +1 -1
  29. package/dist/types/monitor-do.d.ts +13 -4
  30. package/dist/types/monitor-do.d.ts.map +1 -1
  31. package/dist/types/rate-limit-headers.d.ts +10 -0
  32. package/dist/types/rate-limit-headers.d.ts.map +1 -0
  33. package/dist/types/schedule-do.d.ts +11 -3
  34. package/dist/types/schedule-do.d.ts.map +1 -1
  35. package/dist/types/token-estimator.d.ts +9 -0
  36. package/dist/types/token-estimator.d.ts.map +1 -0
  37. package/package.json +5 -4
@@ -126,6 +126,31 @@ function _ts_generator(thisArg, body) {
126
126
  }
127
127
  }
128
128
  import { jwtVerify, decodeJwt, importJWK } from 'jose';
129
+ /**
130
+ * Middleware that restricts access to root users only.
131
+ * Returns 403 if the authenticated user is not root.
132
+ */ export function requireRoot() {
133
+ return function(c, next) {
134
+ return _async_to_generator(function() {
135
+ var auth;
136
+ return _ts_generator(this, function(_state) {
137
+ auth = c.get('auth');
138
+ if (!(auth === null || auth === void 0 ? void 0 : auth.isRoot)) {
139
+ return [
140
+ 2,
141
+ c.json({
142
+ error: 'Root access required'
143
+ }, 403)
144
+ ];
145
+ }
146
+ return [
147
+ 2,
148
+ next()
149
+ ];
150
+ });
151
+ })();
152
+ };
153
+ }
129
154
  /**
130
155
  * Get the JWT algorithm based on JWK key type
131
156
  */ function getAlgorithmForJwk(jwk) {
@@ -160,9 +160,18 @@ import Fuse from 'fuse.js';
160
160
  import { isSignalValid, brainMachineDefinition } from '@positronic/core';
161
161
  import { getManifest } from '../brain-runner-do.js';
162
162
  var brains = new Hono();
163
+ /**
164
+ * Get the userId for ownership filtering from the auth context.
165
+ * Root users get null (no filter — sees everything).
166
+ * Non-root users get their userId (sees only their own).
167
+ */ function scopeUserId(context) {
168
+ var auth = context.get('auth');
169
+ var _auth_userId;
170
+ return (auth === null || auth === void 0 ? void 0 : auth.isRoot) ? null : (_auth_userId = auth === null || auth === void 0 ? void 0 : auth.userId) !== null && _auth_userId !== void 0 ? _auth_userId : null;
171
+ }
163
172
  brains.post('/runs', function(context) {
164
173
  return _async_to_generator(function() {
165
- var requestBody, options, identifier, manifest, resolution, brain, brainRunId, namespace, doId, stub, initialData, brainTitle, response;
174
+ var requestBody, options, identifier, manifest, resolution, brain, brainRunId, namespace, doId, stub, auth, currentUser, initialData, brainTitle, response;
166
175
  return _ts_generator(this, function(_state) {
167
176
  switch(_state.label){
168
177
  case 0:
@@ -218,6 +227,19 @@ brains.post('/runs', function(context) {
218
227
  namespace = context.env.BRAIN_RUNNER_DO;
219
228
  doId = namespace.idFromName(brainRunId);
220
229
  stub = namespace.get(doId);
230
+ // Read auth context for currentUser (every brain run must have an owner)
231
+ auth = context.get('auth');
232
+ if (!(auth === null || auth === void 0 ? void 0 : auth.userId) && !(auth === null || auth === void 0 ? void 0 : auth.isRoot)) {
233
+ return [
234
+ 2,
235
+ context.json({
236
+ error: 'Authentication required to run a brain'
237
+ }, 401)
238
+ ];
239
+ }
240
+ currentUser = {
241
+ id: auth.userId || 'root'
242
+ };
221
243
  // Pass options to the brain runner if provided
222
244
  initialData = options ? {
223
245
  options: options
@@ -226,7 +248,7 @@ brains.post('/runs', function(context) {
226
248
  brainTitle = brain.title || identifier;
227
249
  return [
228
250
  4,
229
- stub.start(brainTitle, brainRunId, initialData)
251
+ stub.start(brainTitle, brainRunId, currentUser, initialData)
230
252
  ];
231
253
  case 2:
232
254
  _state.sent();
@@ -243,7 +265,7 @@ brains.post('/runs', function(context) {
243
265
  });
244
266
  brains.post('/runs/rerun', function(context) {
245
267
  return _async_to_generator(function() {
246
- var requestBody, runId, startsAt, stopsAfter, identifier, manifest, resolution, brain, monitorId, monitorStub, existingRun, newBrainRunId, namespace, doId, stub, rerunOptions, brainTitle, response;
268
+ var requestBody, runId, startsAt, stopsAfter, identifier, manifest, resolution, brain, monitorId, monitorStub, existingRun, auth, currentUser, newBrainRunId, namespace, doId, stub, rerunOptions, brainTitle, response;
247
269
  return _ts_generator(this, function(_state) {
248
270
  switch(_state.label){
249
271
  case 0:
@@ -317,6 +339,19 @@ brains.post('/runs/rerun', function(context) {
317
339
  }
318
340
  _state.label = 3;
319
341
  case 3:
342
+ // Read auth context for currentUser (every brain run must have an owner)
343
+ auth = context.get('auth');
344
+ if (!(auth === null || auth === void 0 ? void 0 : auth.userId) && !(auth === null || auth === void 0 ? void 0 : auth.isRoot)) {
345
+ return [
346
+ 2,
347
+ context.json({
348
+ error: 'Authentication required to run a brain'
349
+ }, 401)
350
+ ];
351
+ }
352
+ currentUser = {
353
+ id: auth.userId || 'root'
354
+ };
320
355
  // Create a new brain run with rerun parameters
321
356
  newBrainRunId = uuidv4();
322
357
  namespace = context.env.BRAIN_RUNNER_DO;
@@ -334,7 +369,7 @@ brains.post('/runs/rerun', function(context) {
334
369
  brainTitle = brain.title || identifier;
335
370
  return [
336
371
  4,
337
- stub.start(brainTitle, newBrainRunId, rerunOptions)
372
+ stub.start(brainTitle, newBrainRunId, currentUser, rerunOptions)
338
373
  ];
339
374
  case 4:
340
375
  _state.sent();
@@ -375,16 +410,17 @@ brains.get('/runs/:runId/watch', function(context) {
375
410
  });
376
411
  brains.get('/runs/:runId', function(context) {
377
412
  return _async_to_generator(function() {
378
- var runId, monitorId, monitorStub, run;
413
+ var runId, userId, monitorId, monitorStub, run;
379
414
  return _ts_generator(this, function(_state) {
380
415
  switch(_state.label){
381
416
  case 0:
382
417
  runId = context.req.param('runId');
418
+ userId = scopeUserId(context);
383
419
  monitorId = context.env.MONITOR_DO.idFromName('singleton');
384
420
  monitorStub = context.env.MONITOR_DO.get(monitorId);
385
421
  return [
386
422
  4,
387
- monitorStub.getRun(runId)
423
+ monitorStub.getRun(runId, userId)
388
424
  ];
389
425
  case 1:
390
426
  run = _state.sent();
@@ -640,7 +676,7 @@ brains.post('/runs/:runId/resume', function(context) {
640
676
  });
641
677
  brains.get('/:identifier/history', function(context) {
642
678
  return _async_to_generator(function() {
643
- var identifier, limit, manifest, resolution, brain, brainTitle, monitorId, monitorStub, runs;
679
+ var identifier, limit, manifest, resolution, brain, brainTitle, monitorId, monitorStub, userId, runs;
644
680
  return _ts_generator(this, function(_state) {
645
681
  switch(_state.label){
646
682
  case 0:
@@ -681,9 +717,10 @@ brains.get('/:identifier/history', function(context) {
681
717
  // Get the monitor singleton instance
682
718
  monitorId = context.env.MONITOR_DO.idFromName('singleton');
683
719
  monitorStub = context.env.MONITOR_DO.get(monitorId);
720
+ userId = scopeUserId(context);
684
721
  return [
685
722
  4,
686
- monitorStub.history(brainTitle, limit)
723
+ monitorStub.history(brainTitle, limit, userId)
687
724
  ];
688
725
  case 1:
689
726
  runs = _state.sent();
@@ -699,7 +736,7 @@ brains.get('/:identifier/history', function(context) {
699
736
  });
700
737
  brains.get('/:identifier/active-runs', function(context) {
701
738
  return _async_to_generator(function() {
702
- var identifier, manifest, resolution, brain, brainTitle, monitorId, monitorStub, runs;
739
+ var identifier, manifest, resolution, brain, brainTitle, monitorId, monitorStub, userId, runs;
703
740
  return _ts_generator(this, function(_state) {
704
741
  switch(_state.label){
705
742
  case 0:
@@ -739,9 +776,10 @@ brains.get('/:identifier/active-runs', function(context) {
739
776
  // Get the monitor singleton instance
740
777
  monitorId = context.env.MONITOR_DO.idFromName('singleton');
741
778
  monitorStub = context.env.MONITOR_DO.get(monitorId);
779
+ userId = scopeUserId(context);
742
780
  return [
743
781
  4,
744
- monitorStub.activeRuns(brainTitle)
782
+ monitorStub.activeRuns(brainTitle, userId)
745
783
  ];
746
784
  case 1:
747
785
  runs = _state.sent();
@@ -922,7 +960,7 @@ brains.get('/', function(context) {
922
960
  // Create a new schedule
923
961
  brains.post('/schedules', function(context) {
924
962
  return _async_to_generator(function() {
925
- var body, cronExpression, identifier, manifest, resolution, brain, brainTitle, scheduleDoId, scheduleStub, timezone, schedule, error, errorMessage;
963
+ var body, cronExpression, identifier, manifest, resolution, brain, brainTitle, scheduleDoId, scheduleStub, auth, runAsUserId, timezone, schedule, error, errorMessage;
926
964
  return _ts_generator(this, function(_state) {
927
965
  switch(_state.label){
928
966
  case 0:
@@ -1003,6 +1041,17 @@ brains.post('/schedules', function(context) {
1003
1041
  // Get the schedule singleton instance
1004
1042
  scheduleDoId = context.env.SCHEDULE_DO.idFromName('singleton');
1005
1043
  scheduleStub = context.env.SCHEDULE_DO.get(scheduleDoId);
1044
+ // Require authentication — scheduled runs will execute as this user
1045
+ auth = context.get('auth');
1046
+ if (!(auth === null || auth === void 0 ? void 0 : auth.userId) && !(auth === null || auth === void 0 ? void 0 : auth.isRoot)) {
1047
+ return [
1048
+ 2,
1049
+ context.json({
1050
+ error: 'Authentication required to create a schedule'
1051
+ }, 401)
1052
+ ];
1053
+ }
1054
+ runAsUserId = auth.userId || 'root';
1006
1055
  // Determine timezone: use provided value, fall back to project timezone
1007
1056
  timezone = body.timezone;
1008
1057
  if (!!timezone) return [
@@ -1032,7 +1081,7 @@ brains.post('/schedules', function(context) {
1032
1081
  }
1033
1082
  return [
1034
1083
  4,
1035
- scheduleStub.createSchedule(brainTitle, cronExpression, timezone)
1084
+ scheduleStub.createSchedule(brainTitle, cronExpression, timezone, runAsUserId)
1036
1085
  ];
1037
1086
  case 4:
1038
1087
  schedule = _state.sent();
@@ -1060,15 +1109,16 @@ brains.post('/schedules', function(context) {
1060
1109
  // List all schedules
1061
1110
  brains.get('/schedules', function(context) {
1062
1111
  return _async_to_generator(function() {
1063
- var scheduleId, scheduleStub, result;
1112
+ var scheduleId, scheduleStub, userId, result;
1064
1113
  return _ts_generator(this, function(_state) {
1065
1114
  switch(_state.label){
1066
1115
  case 0:
1067
1116
  scheduleId = context.env.SCHEDULE_DO.idFromName('singleton');
1068
1117
  scheduleStub = context.env.SCHEDULE_DO.get(scheduleId);
1118
+ userId = scopeUserId(context);
1069
1119
  return [
1070
1120
  4,
1071
- scheduleStub.listSchedules()
1121
+ scheduleStub.listSchedules(userId)
1072
1122
  ];
1073
1123
  case 1:
1074
1124
  result = _state.sent();
@@ -1083,7 +1133,7 @@ brains.get('/schedules', function(context) {
1083
1133
  // Get scheduled run history - MUST be before :scheduleId route
1084
1134
  brains.get('/schedules/runs', function(context) {
1085
1135
  return _async_to_generator(function() {
1086
- var scheduleIdParam, limit, scheduleDoId, scheduleStub, result;
1136
+ var scheduleIdParam, limit, scheduleDoId, scheduleStub, userId, result;
1087
1137
  return _ts_generator(this, function(_state) {
1088
1138
  switch(_state.label){
1089
1139
  case 0:
@@ -1091,9 +1141,10 @@ brains.get('/schedules/runs', function(context) {
1091
1141
  limit = Number(context.req.query('limit') || '100');
1092
1142
  scheduleDoId = context.env.SCHEDULE_DO.idFromName('singleton');
1093
1143
  scheduleStub = context.env.SCHEDULE_DO.get(scheduleDoId);
1144
+ userId = scopeUserId(context);
1094
1145
  return [
1095
1146
  4,
1096
- scheduleStub.getAllRuns(scheduleIdParam, limit)
1147
+ scheduleStub.getAllRuns(scheduleIdParam, limit, userId)
1097
1148
  ];
1098
1149
  case 1:
1099
1150
  result = _state.sent();
@@ -178,6 +178,7 @@ function _ts_generator(thisArg, body) {
178
178
  }
179
179
  }
180
180
  import { Hono } from 'hono';
181
+ import { requireRoot } from './auth-middleware.js';
181
182
  /**
182
183
  * Helper to check if Cloudflare API credentials are configured
183
184
  */ function getSecretsApiConfig(env) {
@@ -214,6 +215,8 @@ import { Hono } from 'hono';
214
215
  }).apply(this, arguments);
215
216
  }
216
217
  var secrets = new Hono();
218
+ // Only root users can manage secrets
219
+ secrets.use('*', requireRoot());
217
220
  // Protected secret name that cannot be managed via the API
218
221
  var PROTECTED_SECRET = 'ROOT_PUBLIC_KEY';
219
222
  // List all secrets (names only, not values)
@@ -298,7 +298,9 @@ import { TimeoutAdapter } from './timeout-adapter.js';
298
298
  import { PageAdapter } from './page-adapter.js';
299
299
  import { EventLoader } from './event-loader.js';
300
300
  import { createPagesService } from './pages-service.js';
301
+ import { setGovernorBinding, rateGoverned } from './governor-client-wrapper.js';
301
302
  import { CloudflareR2Loader } from './r2-loader.js';
303
+ import { createR2Backend } from './create-r2-store.js';
302
304
  import { createResources } from '@positronic/core';
303
305
  var manifest = null;
304
306
  export function setManifest(generatedManifest) {
@@ -503,6 +505,8 @@ var ScheduleAdapter = /*#__PURE__*/ function() {
503
505
  ]);
504
506
  return BatchChunkAdapter;
505
507
  }();
508
+ // SQL to initialize the run owner table (stores who started this brain run)
509
+ var runOwnerTableSQL = "\nCREATE TABLE IF NOT EXISTS run_owner (\n user_id TEXT NOT NULL\n);\n";
506
510
  // SQL to initialize the signals table
507
511
  var signalsTableSQL = "\nCREATE TABLE IF NOT EXISTS brain_signals (\n id INTEGER PRIMARY KEY AUTOINCREMENT,\n signal_type TEXT NOT NULL,\n content TEXT,\n queued_at INTEGER NOT NULL\n);\n";
508
512
  // SQL to initialize the wait timeout table
@@ -516,13 +520,37 @@ export var BrainRunnerDO = /*#__PURE__*/ function(DurableObject) {
516
520
  _this = _call_super(this, BrainRunnerDO, [
517
521
  state,
518
522
  env
519
- ]), _define_property(_this, "sql", void 0), _define_property(_this, "brainRunId", void 0), _define_property(_this, "eventStreamAdapter", new EventStreamAdapter()), _define_property(_this, "abortController", null), _define_property(_this, "pageAdapter", null), _define_property(_this, "signalsTableInitialized", false), _define_property(_this, "waitTimeoutTableInitialized", false);
523
+ ]), _define_property(_this, "sql", void 0), _define_property(_this, "brainRunId", void 0), _define_property(_this, "eventStreamAdapter", new EventStreamAdapter()), _define_property(_this, "abortController", null), _define_property(_this, "pageAdapter", null), _define_property(_this, "runOwnerTableInitialized", false), _define_property(_this, "signalsTableInitialized", false), _define_property(_this, "waitTimeoutTableInitialized", false);
520
524
  _this.sql = state.storage.sql;
521
525
  _this.brainRunId = state.id.toString();
522
526
  _this.env = env;
523
527
  return _this;
524
528
  }
525
529
  _create_class(BrainRunnerDO, [
530
+ {
531
+ key: "initializeRunOwnerTable",
532
+ value: function initializeRunOwnerTable() {
533
+ if (!this.runOwnerTableInitialized) {
534
+ this.sql.exec(runOwnerTableSQL);
535
+ this.runOwnerTableInitialized = true;
536
+ }
537
+ }
538
+ },
539
+ {
540
+ key: "storeRunOwner",
541
+ value: function storeRunOwner(userId) {
542
+ this.initializeRunOwnerTable();
543
+ this.sql.exec("INSERT INTO run_owner (user_id) VALUES (?)", userId);
544
+ }
545
+ },
546
+ {
547
+ key: "getRunOwner",
548
+ value: function getRunOwner() {
549
+ this.initializeRunOwnerTable();
550
+ var results = this.sql.exec("SELECT user_id FROM run_owner LIMIT 1").toArray();
551
+ return results.length > 0 ? results[0].user_id : null;
552
+ }
553
+ },
526
554
  {
527
555
  key: "initializeSignalsTable",
528
556
  value: function initializeSignalsTable() {
@@ -1018,7 +1046,7 @@ export var BrainRunnerDO = /*#__PURE__*/ function(DurableObject) {
1018
1046
  },
1019
1047
  {
1020
1048
  key: "start",
1021
- value: function start(brainTitle, brainRunId, initialData) {
1049
+ value: function start(brainTitle, brainRunId, currentUser, initialData) {
1022
1050
  return _async_to_generator(function() {
1023
1051
  var _this, sql, resolution, brainToRun, sqliteAdapter, eventStreamAdapter, monitorDOStub, monitorAdapter, scheduleAdapter, webhookAdapter, env, pagesService, r2Resources, runnerWithResources, signalProvider, options, initialState, batchChunkAdapter, timeoutAdapter;
1024
1052
  return _ts_generator(this, function(_state) {
@@ -1055,6 +1083,7 @@ export var BrainRunnerDO = /*#__PURE__*/ function(DurableObject) {
1055
1083
  env = this.buildRuntimeEnv();
1056
1084
  // Create pages service for brain to use
1057
1085
  pagesService = createPagesService(brainRunId, this.env.RESOURCES_BUCKET, monitorDOStub, env);
1086
+ setGovernorBinding(this.env.GOVERNOR_DO);
1058
1087
  if (!brainRunner) {
1059
1088
  throw new Error('BrainRunner not initialized');
1060
1089
  }
@@ -1076,10 +1105,14 @@ export var BrainRunnerDO = /*#__PURE__*/ function(DurableObject) {
1076
1105
  signalProvider = new CloudflareSignalProvider(function(filter) {
1077
1106
  return _this.getAndConsumeSignals(filter);
1078
1107
  });
1079
- runnerWithResources = runnerWithResources.withSignalProvider(signalProvider);
1108
+ runnerWithResources = runnerWithResources.withSignalProvider(signalProvider).withGovernor(function(c) {
1109
+ return rateGoverned(c);
1110
+ }).withStoreProvider(createR2Backend(this.env.RESOURCES_BUCKET));
1080
1111
  // Extract options from initialData if present
1081
1112
  options = initialData === null || initialData === void 0 ? void 0 : initialData.options;
1082
1113
  initialState = initialData && !initialData.options ? initialData : {};
1114
+ // Persist run owner durably (immutable, not derived from events)
1115
+ this.storeRunOwner(currentUser.id);
1083
1116
  // Create abort controller for this run
1084
1117
  this.abortController = new AbortController();
1085
1118
  batchChunkAdapter = new BatchChunkAdapter(function(signal) {
@@ -1102,6 +1135,7 @@ export var BrainRunnerDO = /*#__PURE__*/ function(DurableObject) {
1102
1135
  batchChunkAdapter,
1103
1136
  timeoutAdapter
1104
1137
  ]).run(brainToRun, _object_spread_props(_object_spread({
1138
+ currentUser: currentUser,
1105
1139
  initialState: initialState,
1106
1140
  brainRunId: brainRunId
1107
1141
  }, options && {
@@ -1131,7 +1165,7 @@ export var BrainRunnerDO = /*#__PURE__*/ function(DurableObject) {
1131
1165
  * This method reconstructs state and calls BrainRunner.resume().
1132
1166
  */ function wakeUp(brainRunId) {
1133
1167
  return _async_to_generator(function() {
1134
- var _this, sql, pendingTimeout, eventLoader, startEvent, brainTitle, initialState, originalBrainRunId, resolution, brainToRun, allEvents, machine, _iteratorNormalCompletion, _didIteratorError, _iteratorError, _iterator, _step, event, sqliteAdapter, eventStreamAdapter, monitorDOStub, monitorAdapter, scheduleAdapter, webhookAdapter, env, pagesService, r2Resources, runnerWithResources, signalProvider, batchChunkAdapter, timeoutAdapter;
1168
+ var _this, sql, pendingTimeout, eventLoader, startEvent, brainTitle, initialState, ownerId, currentUser, originalBrainRunId, resolution, brainToRun, allEvents, machine, _iteratorNormalCompletion, _didIteratorError, _iteratorError, _iterator, _step, event, sqliteAdapter, eventStreamAdapter, monitorDOStub, monitorAdapter, scheduleAdapter, webhookAdapter, env, pagesService, r2Resources, runnerWithResources, signalProvider, batchChunkAdapter, timeoutAdapter;
1135
1169
  return _ts_generator(this, function(_state) {
1136
1170
  switch(_state.label){
1137
1171
  case 0:
@@ -1170,6 +1204,14 @@ export var BrainRunnerDO = /*#__PURE__*/ function(DurableObject) {
1170
1204
  }
1171
1205
  brainTitle = startEvent.brainTitle;
1172
1206
  initialState = startEvent.initialState || {};
1207
+ // Read run owner from durable storage (set once in start(), not from events)
1208
+ ownerId = this.getRunOwner();
1209
+ if (!ownerId) {
1210
+ throw new Error("No run owner found for brain run ".concat(brainRunId));
1211
+ }
1212
+ currentUser = {
1213
+ id: ownerId
1214
+ };
1173
1215
  // Use the brainRunId from the START event, not the parameter.
1174
1216
  // alarm() passes state.id.toString() (the DO hex ID), but the brain was
1175
1217
  // originally started with a UUID. Events must use the original UUID so
@@ -1233,6 +1275,7 @@ export var BrainRunnerDO = /*#__PURE__*/ function(DurableObject) {
1233
1275
  env = this.buildRuntimeEnv();
1234
1276
  // Create pages service for brain to use
1235
1277
  pagesService = createPagesService(brainRunId, this.env.RESOURCES_BUCKET, monitorDOStub, env);
1278
+ setGovernorBinding(this.env.GOVERNOR_DO);
1236
1279
  if (!brainRunner) {
1237
1280
  throw new Error('BrainRunner not initialized');
1238
1281
  }
@@ -1253,7 +1296,9 @@ export var BrainRunnerDO = /*#__PURE__*/ function(DurableObject) {
1253
1296
  signalProvider = new CloudflareSignalProvider(function(filter) {
1254
1297
  return _this.getAndConsumeSignals(filter);
1255
1298
  });
1256
- runnerWithResources = runnerWithResources.withSignalProvider(signalProvider);
1299
+ runnerWithResources = runnerWithResources.withSignalProvider(signalProvider).withGovernor(function(c) {
1300
+ return rateGoverned(c);
1301
+ }).withStoreProvider(createR2Backend(this.env.RESOURCES_BUCKET));
1257
1302
  // Create abort controller for this run
1258
1303
  this.abortController = new AbortController();
1259
1304
  batchChunkAdapter = new BatchChunkAdapter(function(signal) {
@@ -1276,6 +1321,7 @@ export var BrainRunnerDO = /*#__PURE__*/ function(DurableObject) {
1276
1321
  batchChunkAdapter,
1277
1322
  timeoutAdapter
1278
1323
  ]).resume(brainToRun, {
1324
+ currentUser: currentUser,
1279
1325
  machine: machine,
1280
1326
  brainRunId: originalBrainRunId,
1281
1327
  signal: this.abortController.signal