@alma-harness/postgres 0.1.0 → 0.2.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/index.js CHANGED
@@ -1,11 +1,9 @@
1
1
  // src/session-store.ts
2
2
  import { assertWellFormed, scopePath as scopePath2 } from "@alma-harness/core";
3
3
 
4
- // src/scoped.ts
5
- import { scopePath } from "@alma-harness/core";
6
-
7
4
  // src/schema.ts
8
5
  var DEFAULT_RLS_ROLE = "alma_app";
6
+ var DEFAULT_RETENTION_ROLE = "alma_retention";
9
7
  var IDENTIFIER = /^[a-z_][a-z0-9_]*$/;
10
8
  function assertRoleIdentifier(role) {
11
9
  if (!IDENTIFIER.test(role)) {
@@ -30,6 +28,29 @@ create policy ${name} on ${table}
30
28
  );
31
29
  `;
32
30
  }
31
+ function retentionPolicySql(table, retentionRole, name) {
32
+ assertRoleIdentifier(table);
33
+ assertRoleIdentifier(retentionRole);
34
+ assertRoleIdentifier(name);
35
+ return `
36
+ drop policy if exists ${name}_read on ${table};
37
+ create policy ${name}_read on ${table}
38
+ for select
39
+ to ${retentionRole}
40
+ using (true);
41
+
42
+ drop policy if exists ${name} on ${table};
43
+ create policy ${name} on ${table}
44
+ for delete
45
+ to ${retentionRole}
46
+ using (true);`;
47
+ }
48
+ function assertIso8601(at, label = "timestamp") {
49
+ if (Number.isNaN(Date.parse(at))) {
50
+ throw new Error(`invalid ISO 8601 ${label}: ${JSON.stringify(at)}`);
51
+ }
52
+ return at;
53
+ }
33
54
  function roleBootstrapSql(role) {
34
55
  assertRoleIdentifier(role);
35
56
  return `
@@ -38,16 +59,26 @@ begin
38
59
  if not exists (select from pg_roles where rolname = '${role}') then
39
60
  begin
40
61
  create role ${role} nologin;
41
- exception when duplicate_object then
62
+ exception when duplicate_object or unique_violation then
42
63
  -- Another instance won the race between the existence check and the
43
64
  -- create (pg_roles is cluster-wide and CREATE ROLE has no IF NOT
44
65
  -- EXISTS); losing it must not roll back the rest of the migration.
66
+ -- Two creates that overlap surface as unique_violation on
67
+ -- pg_authid, not duplicate_object (review of 056\u2013058).
45
68
  null;
46
69
  end;
47
70
  end if;
48
71
  end $$;
49
72
  `;
50
73
  }
74
+ function grantRoleSql(role, to) {
75
+ assertRoleIdentifier(role);
76
+ assertRoleIdentifier(to);
77
+ return `grant ${role} to ${to};`;
78
+ }
79
+ async function grantRole(pool, opts) {
80
+ await pool.query(grantRoleSql(opts.role ?? DEFAULT_RLS_ROLE, opts.to));
81
+ }
51
82
  function sessionStoreMigrationSql(role = DEFAULT_RLS_ROLE) {
52
83
  assertRoleIdentifier(role);
53
84
  return `
@@ -84,6 +115,7 @@ async function migrateSessionStore(pool, opts = {}) {
84
115
  }
85
116
 
86
117
  // src/scoped.ts
118
+ import { scopePath } from "@alma-harness/core";
87
119
  var DEFAULT_STATEMENT_TIMEOUT_MS = 3e4;
88
120
  function resolveRlsRole(opts) {
89
121
  const role = opts.role === void 0 ? DEFAULT_RLS_ROLE : opts.role;
@@ -97,19 +129,12 @@ function resolveStatementTimeout(opts) {
97
129
  }
98
130
  return ms;
99
131
  }
100
- async function inScope(pool, role, scope, fn, statementTimeoutMs = DEFAULT_STATEMENT_TIMEOUT_MS) {
101
- scopePath(scope);
132
+ async function inTransaction(pool, role, fn) {
102
133
  const client = await pool.connect();
103
134
  let rollbackFailed;
104
135
  try {
105
136
  await client.query("begin");
106
137
  if (role !== null) await client.query(`set local role ${role}`);
107
- await client.query(
108
- `select set_config('alma.org', $1, true),
109
- set_config('alma.uid', $2, true),
110
- set_config('statement_timeout', $3, true)`,
111
- [scope.org, scope.uid, statementTimeoutMs === null ? "0" : String(statementTimeoutMs)]
112
- );
113
138
  const result = await fn(client);
114
139
  await client.query("commit");
115
140
  return result;
@@ -122,6 +147,37 @@ async function inScope(pool, role, scope, fn, statementTimeoutMs = DEFAULT_STATE
122
147
  client.release(rollbackFailed === void 0 ? void 0 : rollbackFailed);
123
148
  }
124
149
  }
150
+ async function sweepBefore(pool, opts) {
151
+ assertRoleIdentifier(opts.table);
152
+ assertRoleIdentifier(opts.column);
153
+ const batch = opts.batch ?? 5e3;
154
+ if (!Number.isInteger(batch) || batch < 1) throw new Error(`batch must be a positive integer, got ${batch}`);
155
+ let total = 0;
156
+ for (; ; ) {
157
+ const removed = await inTransaction(pool, opts.role, async (client) => {
158
+ const { rowCount } = await client.query(
159
+ `delete from ${opts.table}
160
+ where ctid = any(array(select ctid from ${opts.table} where ${opts.column} < $1::timestamptz limit $2))`,
161
+ [opts.before, batch]
162
+ );
163
+ return rowCount ?? 0;
164
+ });
165
+ total += removed;
166
+ if (removed < batch) return total;
167
+ }
168
+ }
169
+ async function inScope(pool, role, scope, fn, statementTimeoutMs = DEFAULT_STATEMENT_TIMEOUT_MS) {
170
+ scopePath(scope);
171
+ return inTransaction(pool, role, async (client) => {
172
+ await client.query(
173
+ `select set_config('alma.org', $1, true),
174
+ set_config('alma.uid', $2, true),
175
+ set_config('statement_timeout', $3, true)`,
176
+ [scope.org, scope.uid, statementTimeoutMs === null ? "0" : String(statementTimeoutMs)]
177
+ );
178
+ return fn(client);
179
+ });
180
+ }
125
181
 
126
182
  // src/session-store.ts
127
183
  var PostgresSessionStore = class {
@@ -205,7 +261,7 @@ var PostgresSessionStore = class {
205
261
  const removals = [];
206
262
  for (const row of rows) {
207
263
  const survivors = row.msg.blocks.filter(
208
- (b) => b.type !== "tool_call" && b.type !== "tool_result"
264
+ (b) => b.type !== "tool_call" && b.type !== "tool_result" && b.type !== "reasoning"
209
265
  );
210
266
  if (survivors.length === row.msg.blocks.length) continue;
211
267
  blocks += row.msg.blocks.length - survivors.length;
@@ -249,11 +305,7 @@ var PostgresSessionStore = class {
249
305
  return inScope(this.#pool, this.#role, scope, fn, this.#timeoutMs);
250
306
  }
251
307
  };
252
- function instant(at) {
253
- const ms = Date.parse(at);
254
- if (Number.isNaN(ms)) throw new Error(`invalid ISO 8601 timestamp: ${JSON.stringify(at)}`);
255
- return ms;
256
- }
308
+ var instant = (at) => Date.parse(assertIso8601(at));
257
309
 
258
310
  // src/memory-stores.ts
259
311
  import {
@@ -1075,7 +1127,6 @@ var AUDIT_ROUTING_TABLE = "alma_audit_routing";
1075
1127
  var AUDIT_COST_TABLE = "alma_audit_cost";
1076
1128
  var AUDIT_RECALL_TABLE = "alma_audit_recall";
1077
1129
  var AUDIT_CONTEXT_TABLE = "alma_audit_context";
1078
- var DEFAULT_RETENTION_ROLE = "alma_retention";
1079
1130
  var AUDIT_TABLES = [
1080
1131
  AUDIT_ACCESS_TABLE,
1081
1132
  AUDIT_ROUTING_TABLE,
@@ -1225,25 +1276,11 @@ grant select, insert
1225
1276
  -- 039 review caught: a retention mechanism that silently retains forever, in
1226
1277
  -- exactly the deployments careful enough not to connect as a superuser.
1227
1278
  --
1228
- -- TWO policies, not one. A FOR DELETE policy alone still deleted nothing,
1229
- -- because a DELETE with a WHERE clause must SCAN the rows to filter them, and
1230
- -- the scope-keyed policy is FOR ALL -- which governs SELECT too. That second
1231
- -- step surfaced only by running the statement; it does not follow from reading
1232
- -- the first fix.
1233
- ${AUDIT_TABLES.map(
1234
- (t) => `
1235
- drop policy if exists alma_audit_retention_read on ${t};
1236
- create policy alma_audit_retention_read on ${t}
1237
- for select
1238
- to ${retentionRole}
1239
- using (true);
1240
-
1241
- drop policy if exists alma_audit_retention on ${t};
1242
- create policy alma_audit_retention on ${t}
1243
- for delete
1244
- to ${retentionRole}
1245
- using (true);`
1246
- ).join("")}
1279
+ -- TWO policies, not one (see retentionPolicySql). A FOR DELETE policy alone
1280
+ -- still deleted nothing, because a DELETE with a WHERE clause must SCAN the
1281
+ -- rows to filter them, and the scope-keyed policy is FOR ALL -- which governs
1282
+ -- SELECT too. That second step surfaced only by running the statement.
1283
+ ${AUDIT_TABLES.map((t) => retentionPolicySql(t, retentionRole, "alma_audit_retention")).join("")}
1247
1284
 
1248
1285
  grant select, delete
1249
1286
  on ${AUDIT_TABLES.join(", ")}
@@ -1258,32 +1295,15 @@ async function purgeAuditBefore(pool, windows, opts = {}) {
1258
1295
  assertRoleIdentifier(retentionRole);
1259
1296
  for (const table of AUDIT_TABLES) {
1260
1297
  const before = windows[table];
1261
- if (before !== void 0 && Number.isNaN(Date.parse(before))) {
1262
- throw new Error(`invalid ISO 8601 timestamp for ${table}: ${JSON.stringify(before)}`);
1263
- }
1298
+ if (before !== void 0) assertIso8601(before, `timestamp for ${table}`);
1264
1299
  }
1265
1300
  const purged = {};
1266
- const client = await pool.connect();
1267
- try {
1268
- await client.query("begin");
1269
- await client.query(`set local role ${retentionRole}`);
1270
- for (const table of AUDIT_TABLES) {
1271
- const before = windows[table];
1272
- if (before === void 0) continue;
1273
- const { rowCount } = await client.query(
1274
- `delete from ${table} where at < $1::timestamptz`,
1275
- [before]
1276
- );
1277
- purged[table] = rowCount ?? 0;
1278
- }
1279
- await client.query("commit");
1280
- return purged;
1281
- } catch (err) {
1282
- await client.query("rollback").catch(() => void 0);
1283
- throw err;
1284
- } finally {
1285
- client.release();
1301
+ for (const table of AUDIT_TABLES) {
1302
+ const before = windows[table];
1303
+ if (before === void 0) continue;
1304
+ purged[table] = await sweepBefore(pool, { role: retentionRole, table, column: "at", before, ...opts.batch !== void 0 ? { batch: opts.batch } : {} });
1286
1305
  }
1306
+ return purged;
1287
1307
  }
1288
1308
 
1289
1309
  // src/audit-store.ts
@@ -1439,12 +1459,7 @@ var PostgresAuditLog = class {
1439
1459
  }, this.#timeoutMs);
1440
1460
  }
1441
1461
  };
1442
- function instant2(at) {
1443
- if (Number.isNaN(Date.parse(at))) {
1444
- throw new Error(`invalid ISO 8601 timestamp: ${JSON.stringify(at)}`);
1445
- }
1446
- return at;
1447
- }
1462
+ var instant2 = (at) => assertIso8601(at);
1448
1463
 
1449
1464
  // src/turn-store.ts
1450
1465
  import {
@@ -1455,8 +1470,9 @@ import {
1455
1470
  // src/turn-schema.ts
1456
1471
  var TURN_LEASES_TABLE = "alma_turn_leases";
1457
1472
  var TURN_CLAIMS_TABLE = "alma_turn_claims";
1458
- function turnStoreMigrationSql(role = DEFAULT_RLS_ROLE) {
1473
+ function turnStoreMigrationSql(role = DEFAULT_RLS_ROLE, retentionRole = DEFAULT_RETENTION_ROLE) {
1459
1474
  assertRoleIdentifier(role);
1475
+ assertRoleIdentifier(retentionRole);
1460
1476
  return `
1461
1477
  create table if not exists ${TURN_LEASES_TABLE} (
1462
1478
  org text not null,
@@ -1476,15 +1492,30 @@ create table if not exists ${TURN_CLAIMS_TABLE} (
1476
1492
  created_at timestamptz not null default now(),
1477
1493
  primary key (org, uid, session_id, idempotency_key)
1478
1494
  );
1495
+
1496
+ create index if not exists alma_turn_claims_created
1497
+ on ${TURN_CLAIMS_TABLE} (created_at);
1479
1498
  ${rlsPolicySql(TURN_LEASES_TABLE)}${rlsPolicySql(TURN_CLAIMS_TABLE)}
1480
1499
  ${roleBootstrapSql(role)}
1500
+ ${roleBootstrapSql(retentionRole)}
1481
1501
  grant select, insert, update, delete
1482
1502
  on ${TURN_LEASES_TABLE}, ${TURN_CLAIMS_TABLE}
1483
1503
  to ${role};
1504
+ ${retentionPolicySql(TURN_CLAIMS_TABLE, retentionRole, "alma_turn_claims_retention")}
1505
+
1506
+ grant select, delete
1507
+ on ${TURN_CLAIMS_TABLE}
1508
+ to ${retentionRole};
1484
1509
  `;
1485
1510
  }
1486
1511
  async function migrateTurnStore(pool, opts = {}) {
1487
- await pool.query(turnStoreMigrationSql(opts.role));
1512
+ await pool.query(turnStoreMigrationSql(opts.role, opts.retentionRole));
1513
+ }
1514
+ async function purgeTurnClaimsBefore(pool, before, opts = {}) {
1515
+ const role = opts.retentionRole ?? DEFAULT_RETENTION_ROLE;
1516
+ assertRoleIdentifier(role);
1517
+ assertIso8601(before);
1518
+ return sweepBefore(pool, { role, table: TURN_CLAIMS_TABLE, column: "created_at", before, ...opts.batch !== void 0 ? { batch: opts.batch } : {} });
1488
1519
  }
1489
1520
 
1490
1521
  // src/turn-store.ts
@@ -1607,12 +1638,10 @@ var PostgresTurnStore = class {
1607
1638
  await this.#inScope(scope, async (client) => {
1608
1639
  const params = sessionId === void 0 ? [scope.org, scope.uid] : [scope.org, scope.uid, sessionId];
1609
1640
  const bySession = sessionId === void 0 ? "" : " and session_id = $3";
1610
- for (const table of [TURN_CLAIMS_TABLE, TURN_LEASES_TABLE]) {
1611
- await client.query(
1612
- `delete from ${table} where org = $1 and uid = $2${bySession}`,
1613
- params
1614
- );
1615
- }
1641
+ await client.query(
1642
+ `delete from ${TURN_CLAIMS_TABLE} where org = $1 and uid = $2${bySession}`,
1643
+ params
1644
+ );
1616
1645
  });
1617
1646
  }
1618
1647
  /** Shared RLS binding — see `scoped.ts`. */
@@ -1630,6 +1659,165 @@ function assertLeaseOpts(opts) {
1630
1659
  }
1631
1660
  }
1632
1661
  }
1662
+
1663
+ // src/routine-run-store.ts
1664
+ import { scopePath as scopePath5 } from "@alma-harness/core";
1665
+
1666
+ // src/routine-schema.ts
1667
+ var ROUTINE_RUNS_TABLE = "alma_routine_runs";
1668
+ function routineRunStoreMigrationSql(role = DEFAULT_RLS_ROLE, retentionRole = DEFAULT_RETENTION_ROLE) {
1669
+ assertRoleIdentifier(role);
1670
+ assertRoleIdentifier(retentionRole);
1671
+ return `
1672
+ create table if not exists ${ROUTINE_RUNS_TABLE} (
1673
+ org text not null,
1674
+ uid text not null,
1675
+ routine_id text not null,
1676
+ run_id text not null,
1677
+ started_at timestamptz not null,
1678
+ finished_at timestamptz,
1679
+ outcome text not null,
1680
+ reason text,
1681
+ cost_usd double precision not null,
1682
+ session_id text,
1683
+ turn_id text,
1684
+ handle jsonb,
1685
+ delivery_hash text,
1686
+ primary key (org, uid, routine_id, run_id),
1687
+ constraint alma_routine_runs_outcome_check
1688
+ check (outcome in ('delivered', 'duplicate', 'submitted', 'waiting', 'refused', 'failed'))
1689
+ );
1690
+
1691
+ create index if not exists alma_routine_runs_recent
1692
+ on ${ROUTINE_RUNS_TABLE} (org, uid, routine_id, started_at desc);
1693
+ ${rlsPolicySql(ROUTINE_RUNS_TABLE)}
1694
+ ${roleBootstrapSql(role)}
1695
+ ${roleBootstrapSql(retentionRole)}
1696
+ grant select, insert, update
1697
+ on ${ROUTINE_RUNS_TABLE}
1698
+ to ${role};
1699
+ ${retentionPolicySql(ROUTINE_RUNS_TABLE, retentionRole, "alma_routine_runs_retention")}
1700
+
1701
+ grant select, delete
1702
+ on ${ROUTINE_RUNS_TABLE}
1703
+ to ${retentionRole};
1704
+ `;
1705
+ }
1706
+ async function migrateRoutineRunStore(pool, opts = {}) {
1707
+ await pool.query(routineRunStoreMigrationSql(opts.role, opts.retentionRole));
1708
+ }
1709
+ async function purgeRoutineRunsBefore(pool, before, opts = {}) {
1710
+ const role = opts.retentionRole ?? DEFAULT_RETENTION_ROLE;
1711
+ assertRoleIdentifier(role);
1712
+ assertIso8601(before);
1713
+ return sweepBefore(pool, { role, table: ROUTINE_RUNS_TABLE, column: "started_at", before, ...opts.batch !== void 0 ? { batch: opts.batch } : {} });
1714
+ }
1715
+
1716
+ // src/routine-run-store.ts
1717
+ var COLUMNS = "routine_id, run_id, started_at, finished_at, outcome, reason, cost_usd, session_id, turn_id, handle, delivery_hash";
1718
+ var PostgresRoutineRunStore = class {
1719
+ #pool;
1720
+ #role;
1721
+ #timeoutMs;
1722
+ constructor(pool, opts = {}) {
1723
+ this.#pool = pool;
1724
+ this.#role = resolveRlsRole(opts);
1725
+ this.#timeoutMs = resolveStatementTimeout(opts);
1726
+ }
1727
+ async record(run) {
1728
+ scopePath5(run.scope);
1729
+ assertIso8601(run.startedAt, "startedAt");
1730
+ if (run.finishedAt !== void 0) assertIso8601(run.finishedAt, "finishedAt");
1731
+ await this.#inScope(run.scope, async (client) => {
1732
+ await client.query(
1733
+ `insert into ${ROUTINE_RUNS_TABLE}
1734
+ (org, uid, routine_id, run_id, started_at, finished_at, outcome, reason, cost_usd,
1735
+ session_id, turn_id, handle, delivery_hash)
1736
+ values ($1, $2, $3, $4, $5::timestamptz, $6::timestamptz, $7, $8, $9, $10, $11, $12::jsonb, $13)
1737
+ on conflict (org, uid, routine_id, run_id) do update set
1738
+ started_at = excluded.started_at, finished_at = excluded.finished_at,
1739
+ outcome = excluded.outcome, reason = excluded.reason, cost_usd = excluded.cost_usd,
1740
+ session_id = excluded.session_id, turn_id = excluded.turn_id,
1741
+ handle = excluded.handle, delivery_hash = excluded.delivery_hash`,
1742
+ [
1743
+ run.scope.org,
1744
+ run.scope.uid,
1745
+ run.routineId,
1746
+ run.id,
1747
+ run.startedAt,
1748
+ run.finishedAt ?? null,
1749
+ run.outcome,
1750
+ run.reason ?? null,
1751
+ run.costUsd,
1752
+ run.sessionId ?? null,
1753
+ run.turnId ?? null,
1754
+ run.handle === void 0 ? null : JSON.stringify(run.handle),
1755
+ run.deliveryHash ?? null
1756
+ ]
1757
+ );
1758
+ });
1759
+ }
1760
+ async get(scope, routineId, runId) {
1761
+ return this.#inScope(scope, async (client) => {
1762
+ const { rows } = await client.query(
1763
+ `select ${COLUMNS} from ${ROUTINE_RUNS_TABLE}
1764
+ where org = $1 and uid = $2 and routine_id = $3 and run_id = $4`,
1765
+ [scope.org, scope.uid, routineId, runId]
1766
+ );
1767
+ return rows[0] === void 0 ? null : toRun(scope, rows[0]);
1768
+ });
1769
+ }
1770
+ async list(scope, routineId, opts = {}) {
1771
+ scopePath5(scope);
1772
+ if (opts.since !== void 0) assertIso8601(opts.since, "since");
1773
+ if (opts.limit !== void 0 && opts.limit <= 0) return [];
1774
+ return this.#inScope(scope, async (client) => {
1775
+ const params = [scope.org, scope.uid, routineId];
1776
+ const where = ["org = $1", "uid = $2", "routine_id = $3"];
1777
+ if (opts.since !== void 0) {
1778
+ params.push(opts.since);
1779
+ where.push(`started_at >= $${params.length}::timestamptz`);
1780
+ }
1781
+ if (opts.outcome !== void 0) {
1782
+ params.push(opts.outcome);
1783
+ where.push(`outcome = $${params.length}`);
1784
+ }
1785
+ let limit = "";
1786
+ if (opts.limit !== void 0) {
1787
+ params.push(opts.limit);
1788
+ limit = ` limit $${params.length}`;
1789
+ }
1790
+ const { rows } = await client.query(
1791
+ `select ${COLUMNS} from ${ROUTINE_RUNS_TABLE}
1792
+ where ${where.join(" and ")}
1793
+ order by started_at desc, run_id asc${limit}`,
1794
+ params
1795
+ );
1796
+ return rows.map((row) => toRun(scope, row));
1797
+ });
1798
+ }
1799
+ /** Shared RLS binding — see `scoped.ts`. */
1800
+ async #inScope(scope, fn) {
1801
+ return inScope(this.#pool, this.#role, scope, fn, this.#timeoutMs);
1802
+ }
1803
+ };
1804
+ function toRun(scope, row) {
1805
+ const run = {
1806
+ id: row.run_id,
1807
+ routineId: row.routine_id,
1808
+ scope: { org: scope.org, uid: scope.uid },
1809
+ startedAt: row.started_at.toISOString(),
1810
+ outcome: row.outcome,
1811
+ costUsd: row.cost_usd
1812
+ };
1813
+ if (row.finished_at !== null) run.finishedAt = row.finished_at.toISOString();
1814
+ if (row.reason !== null) run.reason = row.reason;
1815
+ if (row.session_id !== null) run.sessionId = row.session_id;
1816
+ if (row.turn_id !== null) run.turnId = row.turn_id;
1817
+ if (row.handle !== null) run.handle = row.handle;
1818
+ if (row.delivery_hash !== null) run.deliveryHash = row.delivery_hash;
1819
+ return run;
1820
+ }
1633
1821
  export {
1634
1822
  AUDIT_ACCESS_TABLE,
1635
1823
  AUDIT_CONTEXT_TABLE,
@@ -1645,27 +1833,39 @@ export {
1645
1833
  PostgresEpisodeStore,
1646
1834
  PostgresErasureWatermarks,
1647
1835
  PostgresProfileStore,
1836
+ PostgresRoutineRunStore,
1648
1837
  PostgresSessionStore,
1649
1838
  PostgresSpendStore,
1650
1839
  PostgresTurnStore,
1840
+ ROUTINE_RUNS_TABLE,
1651
1841
  SCOPE_STATE_TABLE,
1652
1842
  SPEND_SESSIONS_TABLE,
1653
1843
  SPEND_TENANT_DAYS_TABLE,
1654
1844
  TURN_CLAIMS_TABLE,
1655
1845
  TURN_LEASES_TABLE,
1846
+ assertIso8601,
1656
1847
  assertRoleIdentifier,
1657
1848
  auditLogMigrationSql,
1849
+ grantRole,
1850
+ grantRoleSql,
1851
+ inTransaction,
1658
1852
  memoryStoreMigrationSql,
1659
1853
  migrateAuditLog,
1660
1854
  migrateMemoryStores,
1855
+ migrateRoutineRunStore,
1661
1856
  migrateSessionStore,
1662
1857
  migrateSpendStore,
1663
1858
  migrateTurnStore,
1664
1859
  purgeAuditBefore,
1860
+ purgeRoutineRunsBefore,
1861
+ purgeTurnClaimsBefore,
1862
+ retentionPolicySql,
1665
1863
  rlsPolicySql,
1666
1864
  roleBootstrapSql,
1865
+ routineRunStoreMigrationSql,
1667
1866
  sessionStoreMigrationSql,
1668
1867
  spendStoreMigrationSql,
1868
+ sweepBefore,
1669
1869
  turnStoreMigrationSql
1670
1870
  };
1671
1871
  //# sourceMappingURL=index.js.map