@cortexkit/opencode-magic-context 0.49.5 → 0.49.6

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 (94) hide show
  1. package/dist/auto-search-worker.js +5 -5
  2. package/dist/{compaction-marker-candidates-dd638ypn.js → compaction-marker-candidates-cz72pm1t.js} +2 -2
  3. package/dist/compaction-marker-candidates-worker.js +2 -2
  4. package/dist/{conflict-warning-hook-ae8nmv7c.js → conflict-warning-hook-1jq1rxx7.js} +5 -5
  5. package/dist/{context-yg023c5r.js → context-ae3gxdye.js} +23 -23
  6. package/dist/{embedding-backfill-aj488s8x.js → embedding-backfill-dtjmyktb.js} +6 -6
  7. package/dist/{index-kb9nn0a0.js → index-0nnd4bry.js} +2 -2
  8. package/dist/{index-yqps2zsv.js → index-1j8jcjpa.js} +1 -1
  9. package/dist/{index-3wckxwfp.js → index-1xaw2pq8.js} +5 -5
  10. package/dist/{index-m4p77myp.js → index-6q5h70h2.js} +1 -1
  11. package/dist/{index-7ndnvw7a.js → index-7q1m1qjk.js} +1 -1
  12. package/dist/{index-6m7rdv7y.js → index-9m7bn21d.js} +1 -1
  13. package/dist/{index-c0b01zrc.js → index-9s58tq95.js} +3 -3
  14. package/dist/{index-p2hs3rps.js → index-a796ct3s.js} +4 -4
  15. package/dist/{index-qvr78ej6.js → index-ab3bgm2m.js} +2 -2
  16. package/dist/{index-znzgze2v.js → index-besxhcsh.js} +7 -7
  17. package/dist/{index-7w18gg78.js → index-bg5qqene.js} +1 -1
  18. package/dist/{index-fst3t0d9.js → index-ch08qwgd.js} +8 -8
  19. package/dist/{index-dd18gej8.js → index-ck6y3td2.js} +3 -3
  20. package/dist/{index-7jzrrxap.js → index-cm4hmxyk.js} +1 -1
  21. package/dist/{index-yxawqmdd.js → index-f3dnvnw6.js} +1 -1
  22. package/dist/{index-41gqa557.js → index-g9exahnx.js} +1 -1
  23. package/dist/{index-bhk710rw.js → index-hr64sth2.js} +1 -1
  24. package/dist/{index-gcdb3rqw.js → index-j55vn694.js} +1 -1
  25. package/dist/{index-x3y1np1h.js → index-mj1fgfrk.js} +23 -23
  26. package/dist/{index-fjtgekd4.js → index-s0gsmthp.js} +4 -4
  27. package/dist/{index-v4bqjy56.js → index-vh3e2mvr.js} +17 -17
  28. package/dist/{index-jpm52v9x.js → index-vnjhmkwk.js} +1 -1
  29. package/dist/{index-7zg9dvx0.js → index-vztbgcdk.js} +4 -4
  30. package/dist/{index-xfbfrngb.js → index-xqyj5c85.js} +2 -2
  31. package/dist/{index-2mqps3c1.js → index-zgzdm6dg.js} +9 -9
  32. package/dist/index.js +34 -34
  33. package/dist/{message-index-bounded-pv6ct15d.js → message-index-bounded-630j53ps.js} +9 -9
  34. package/dist/{message-index-jqa7qd0s.js → message-index-c84wm2g0.js} +9 -9
  35. package/dist/{message-time-backfill-8x06r9kx.js → message-time-backfill-8kj57qe3.js} +1 -1
  36. package/dist/migration-worker.js +6 -6
  37. package/dist/{project-embedding-registry-fcmszatg.js → project-embedding-registry-vv59t7ah.js} +5 -5
  38. package/dist/raw-ordinal-warmup-worker.js +6 -6
  39. package/dist/{read-session-chunk-cwgjwjd0.js → read-session-chunk-t3vjd0h0.js} +5 -5
  40. package/dist/{read-session-raw-z38cn0as.js → read-session-raw-gf7eytnm.js} +2 -2
  41. package/dist/{recomp-orchestrator-xw9wt5bm.js → recomp-orchestrator-1d08g57a.js} +20 -20
  42. package/dist/{search-v1t47s2q.js → search-kth2p6cc.js} +16 -16
  43. package/dist/{send-session-notification-yp9m5g4p.js → send-session-notification-3j6krd4w.js} +4 -4
  44. package/dist/{sqlite-mhjkerzq.js → sqlite-d7edbk1s.js} +1 -1
  45. package/dist/{storage-memory-07fx57k6.js → storage-memory-af5zdz98.js} +2 -2
  46. package/dist/{storage-tags-0ssbmzg9.js → storage-tags-dyj7mmbq.js} +2 -2
  47. package/dist/{transform-postprocess-phase-ttra554y.js → transform-postprocess-phase-bv3kb5s1.js} +20 -20
  48. package/dist/v2/auto-search-worker.js +5 -5
  49. package/dist/v2/{compaction-marker-candidates-1s21e2fz.js → compaction-marker-candidates-6gqp5wrc.js} +2 -2
  50. package/dist/v2/compaction-marker-candidates-worker.js +2 -2
  51. package/dist/v2/{context-6en6a8ar.js → context-p8f2shp1.js} +23 -23
  52. package/dist/v2/{embedding-backfill-9hbkfvnz.js → embedding-backfill-cg4rv90f.js} +6 -6
  53. package/dist/v2/{message-index-h8ssgq3q.js → message-index-3ws17x1g.js} +9 -9
  54. package/dist/v2/{message-index-bounded-c0810p5w.js → message-index-bounded-yzxmf6vp.js} +9 -9
  55. package/dist/v2/{message-time-backfill-cje68egj.js → message-time-backfill-5nf10c65.js} +1 -1
  56. package/dist/v2/migration-worker.js +6 -6
  57. package/dist/v2/{project-embedding-registry-42th7k1z.js → project-embedding-registry-rsnf2263.js} +5 -5
  58. package/dist/v2/raw-ordinal-warmup-worker.js +6 -6
  59. package/dist/v2/{read-session-chunk-n86v9xfg.js → read-session-chunk-vtb0w2kd.js} +5 -5
  60. package/dist/v2/{read-session-raw-3b3ehga4.js → read-session-raw-gpcddemt.js} +2 -2
  61. package/dist/v2/{recomp-orchestrator-krvsbnds.js → recomp-orchestrator-v64r4s4r.js} +19 -19
  62. package/dist/v2/{search-048v8y02.js → search-bpa4fxq1.js} +16 -16
  63. package/dist/v2/{send-session-notification-a4h2azxa.js → send-session-notification-5aj2j7vf.js} +4 -4
  64. package/dist/v2/{server-9a6v0wth.js → server-09g9pkvx.js} +7 -7
  65. package/dist/v2/{server-kb9nn0a0.js → server-0nnd4bry.js} +2 -2
  66. package/dist/v2/{server-cjz51jm2.js → server-158ehmk2.js} +3 -3
  67. package/dist/v2/{server-3dqjhchy.js → server-387vkhjq.js} +1 -1
  68. package/dist/v2/{server-czb2rkpk.js → server-4tn95znb.js} +1 -1
  69. package/dist/v2/{server-9290a1mb.js → server-6a9mxnb2.js} +1 -1
  70. package/dist/v2/{server-e2v4m8xe.js → server-7skbfb81.js} +17 -17
  71. package/dist/v2/{server-4enr7s6x.js → server-9zqewm6g.js} +1 -1
  72. package/dist/v2/{server-hetyb88z.js → server-aa9w15cs.js} +8 -8
  73. package/dist/v2/{server-q6j5dasr.js → server-btgnsv7w.js} +1 -1
  74. package/dist/v2/{server-7jzrrxap.js → server-cm4hmxyk.js} +1 -1
  75. package/dist/v2/{server-5zrpr764.js → server-f9py7s7a.js} +1 -1
  76. package/dist/v2/{server-4n2tknpc.js → server-fby0cxbq.js} +4 -4
  77. package/dist/v2/{server-8wcf79fe.js → server-keswwkvv.js} +1 -1
  78. package/dist/v2/{server-3bc6k4k4.js → server-qn23p4h7.js} +5 -5
  79. package/dist/v2/{server-cvgn49tr.js → server-wrem2nmz.js} +1 -1
  80. package/dist/v2/{server-8pqnnmf9.js → server-ww9nr8pe.js} +2 -2
  81. package/dist/v2/{server-rygvffsf.js → server-x2r63c0x.js} +4 -4
  82. package/dist/v2/{server-pcygfdbs.js → server-yd01snxq.js} +1 -1
  83. package/dist/v2/{server-2htmbqbv.js → server-yezz0cp2.js} +1 -1
  84. package/dist/v2/server.js +2 -2
  85. package/dist/v2/{sqlite-mhjkerzq.js → sqlite-d7edbk1s.js} +1 -1
  86. package/dist/v2/{storage-memory-07fx57k6.js → storage-memory-af5zdz98.js} +2 -2
  87. package/dist/v2/{storage-tags-3a4cavqb.js → storage-tags-d47bpaqa.js} +2 -2
  88. package/dist/v2/{wrapup-orchestrator-r2v7kgy3.js → wrapup-orchestrator-cahk37n7.js} +19 -19
  89. package/dist/{wrapup-orchestrator-z7agncp8.js → wrapup-orchestrator-mqp0v195.js} +21 -21
  90. package/package.json +1 -1
  91. package/src/shared/sqlite-acquisition-routing.test.ts +4 -3
  92. package/src/shared/sqlite-foreground-wait.test.ts +140 -0
  93. package/src/shared/sqlite-pass-scope.test.ts +4 -4
  94. package/src/shared/sqlite.ts +2 -2
@@ -2,7 +2,7 @@ import"./server-pavzsdc6.js";
2
2
  import {
3
3
  sessionLog2
4
4
  } from "./server-t4k4qexw.js";
5
- import"./server-cvgn49tr.js";
5
+ import"./server-wrem2nmz.js";
6
6
  import {
7
7
  COMPARTMENT_LEASE_RENEWAL_MS,
8
8
  acquireCompartmentLease,
@@ -19,13 +19,13 @@ import {
19
19
  registerActiveCompartmentRun,
20
20
  setRecompStarting2,
21
21
  setRecompTerminal2
22
- } from "./server-e2v4m8xe.js";
22
+ } from "./server-7skbfb81.js";
23
23
  import"./server-kzns2hbz.js";
24
24
  import"./server-hb6xhh9q.js";
25
- import"./server-kb9nn0a0.js";
26
- import"./server-2htmbqbv.js";
27
- import"./server-8wcf79fe.js";
28
- import"./server-3bc6k4k4.js";
25
+ import"./server-0nnd4bry.js";
26
+ import"./server-yezz0cp2.js";
27
+ import"./server-keswwkvv.js";
28
+ import"./server-qn23p4h7.js";
29
29
  import {
30
30
  getWrapupInProgressState,
31
31
  acquireWrapupInProgress,
@@ -34,39 +34,39 @@ import {
34
34
  getHistorianFailureState,
35
35
  clearEmergencyRecovery,
36
36
  prepareRawSessionOrdinals2
37
- } from "./server-4n2tknpc.js";
37
+ } from "./server-fby0cxbq.js";
38
38
  import"./server-6byqfbqf.js";
39
- import"./server-9a6v0wth.js";
39
+ import"./server-09g9pkvx.js";
40
40
  import"./server-1zx87sdm.js";
41
- import"./server-pcygfdbs.js";
41
+ import"./server-yd01snxq.js";
42
42
  import"./server-cw6521wn.js";
43
43
  import"./server-51779zs2.js";
44
- import"./server-3dqjhchy.js";
44
+ import"./server-387vkhjq.js";
45
45
  import"./server-2ra6pwf3.js";
46
- import"./server-czb2rkpk.js";
46
+ import"./server-4tn95znb.js";
47
47
  import"./server-7ekna9zs.js";
48
48
  import"./server-fr0wbhdn.js";
49
- import"./server-8pqnnmf9.js";
50
- import"./server-q6j5dasr.js";
51
- import"./server-cjz51jm2.js";
49
+ import"./server-ww9nr8pe.js";
50
+ import"./server-btgnsv7w.js";
51
+ import"./server-158ehmk2.js";
52
52
  import"./server-fb3zxn06.js";
53
- import"./server-rygvffsf.js";
53
+ import"./server-x2r63c0x.js";
54
54
  import {
55
55
  pushNotification2
56
56
  } from "./server-x8a7jmkh.js";
57
- import"./server-9290a1mb.js";
57
+ import"./server-6a9mxnb2.js";
58
58
  import"./server-qt1qqasc.js";
59
59
  import"./server-4dhv7mqz.js";
60
60
  import"./server-ras2sxnc.js";
61
- import"./server-5zrpr764.js";
62
- import"./server-7jzrrxap.js";
61
+ import"./server-f9py7s7a.js";
62
+ import"./server-cm4hmxyk.js";
63
63
  import"./server-d6g4whc2.js";
64
64
  import"./server-vb7pbd9p.js";
65
65
  import"./server-t528t8qm.js";
66
66
  import"./server-676xw7at.js";
67
67
  import {
68
68
  sendStatusNotification2
69
- } from "./server-4enr7s6x.js";
69
+ } from "./server-9zqewm6g.js";
70
70
  import"./server-3t0q2cqx.js";
71
71
 
72
72
  // src/hooks/magic-context/wrapup-orchestrator.ts
@@ -1,43 +1,43 @@
1
1
  import {
2
2
  runManagedWrapup2
3
- } from "./index-p2hs3rps.js";
4
- import"./index-dd18gej8.js";
5
- import"./index-v4bqjy56.js";
6
- import"./index-yxawqmdd.js";
3
+ } from "./index-a796ct3s.js";
4
+ import"./index-ck6y3td2.js";
5
+ import"./index-vh3e2mvr.js";
6
+ import"./index-f3dnvnw6.js";
7
7
  import"./index-sd3egckz.js";
8
- import"./index-fjtgekd4.js";
9
- import"./index-3wckxwfp.js";
10
- import"./index-7ndnvw7a.js";
11
- import"./index-7jzrrxap.js";
12
- import"./index-c0b01zrc.js";
13
- import"./index-gcdb3rqw.js";
8
+ import"./index-s0gsmthp.js";
9
+ import"./index-1xaw2pq8.js";
10
+ import"./index-7q1m1qjk.js";
11
+ import"./index-cm4hmxyk.js";
12
+ import"./index-9s58tq95.js";
13
+ import"./index-j55vn694.js";
14
14
  import"./index-4dhv7mqz.js";
15
15
  import"./index-w23dh319.js";
16
- import"./index-bhk710rw.js";
16
+ import"./index-hr64sth2.js";
17
17
  import"./index-qt1qqasc.js";
18
18
  import"./index-x8a7jmkh.js";
19
19
  import"./index-tqf7yg27.js";
20
20
  import"./index-gbmqa9x9.js";
21
21
  import"./index-vkbqdnkj.js";
22
- import"./index-znzgze2v.js";
22
+ import"./index-besxhcsh.js";
23
23
  import"./index-fb3zxn06.js";
24
- import"./index-xfbfrngb.js";
25
- import"./index-6m7rdv7y.js";
24
+ import"./index-xqyj5c85.js";
25
+ import"./index-9m7bn21d.js";
26
26
  import"./index-fr0wbhdn.js";
27
- import"./index-41gqa557.js";
28
- import"./index-7w18gg78.js";
29
- import"./index-7zg9dvx0.js";
30
- import"./index-yqps2zsv.js";
27
+ import"./index-g9exahnx.js";
28
+ import"./index-bg5qqene.js";
29
+ import"./index-vztbgcdk.js";
30
+ import"./index-1j8jcjpa.js";
31
31
  import"./index-1zx87sdm.js";
32
- import"./index-qvr78ej6.js";
33
- import"./index-jpm52v9x.js";
32
+ import"./index-ab3bgm2m.js";
33
+ import"./index-vnjhmkwk.js";
34
34
  import"./index-v0p37hm2.js";
35
35
  import"./index-k6xvbj2e.js";
36
36
  import"./index-h2wc01qk.js";
37
37
  import"./index-1bt88epp.js";
38
38
  import"./index-58e3y90n.js";
39
39
  import"./index-4mjhqadz.js";
40
- import"./index-kb9nn0a0.js";
40
+ import"./index-0nnd4bry.js";
41
41
  import"./index-qx53vezw.js";
42
42
  import"./index-nsjyysj0.js";
43
43
  import"./index-0sahzkwr.js";
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@cortexkit/opencode-magic-context",
3
- "version": "0.49.5",
3
+ "version": "0.49.6",
4
4
  "type": "module",
5
5
  "description": "OpenCode plugin for Magic Context — cross-session memory and context management",
6
6
  "main": "dist/index.js",
@@ -118,7 +118,7 @@ test("exhausted routed acquisition never enters the callback or multiplies privi
118
118
  db.close();
119
119
  rmSync(dir, { recursive: true, force: true });
120
120
  }
121
- });
121
+ }, 30_000);
122
122
 
123
123
  for (const mode of ["run", "get", "all", "exec"] as const) {
124
124
  test(`foreground ${mode} autocommit waits share one turn budget and restore production timeout`, () => {
@@ -147,7 +147,8 @@ for (const mode of ["run", "get", "all", "exec"] as const) {
147
147
  }
148
148
  expect(() => db.exec("BEGIN IMMEDIATE")).toThrow("acquisition remained busy");
149
149
  });
150
- expect(performance.now() - started).toBeLessThan(650);
150
+ expect(performance.now() - started).toBeGreaterThanOrEqual(1900);
151
+ expect(performance.now() - started).toBeLessThan(2600);
151
152
  expect(db.prepare("PRAGMA busy_timeout").get()).toEqual({ timeout: 5000 });
152
153
  expect(db.prepare("SELECT * FROM result").all()).toEqual([]);
153
154
  blocker.exec("ROLLBACK");
@@ -159,5 +160,5 @@ for (const mode of ["run", "get", "all", "exec"] as const) {
159
160
  db.close();
160
161
  rmSync(dir, { recursive: true, force: true });
161
162
  }
162
- });
163
+ }, 30_000);
163
164
  }
@@ -0,0 +1,140 @@
1
+ import { expect, test } from "bun:test";
2
+ import { rmSync } from "node:fs";
3
+ import { tmpdir } from "node:os";
4
+ import { join } from "node:path";
5
+ import { StorageBusyRefusalError } from "../hooks/magic-context/storage-busy-refusal";
6
+ import { createMessagesTransformHandler } from "../plugin/messages-transform";
7
+ import { log } from "./logger";
8
+ import {
9
+ Database,
10
+ guardSqliteTransformPass,
11
+ registerSqliteDiagnosticSink,
12
+ SqliteAcquisitionBusyError,
13
+ withPrivilegedWriter,
14
+ withSqliteTransformPass,
15
+ } from "./sqlite";
16
+ import { type SqliteWriteLocker, startSqliteWriteLocker } from "./sqlite-write-locker-test-support";
17
+ import { createTestTempDirFromPath } from "./test-temp-dir";
18
+
19
+ function fixture() {
20
+ const dir = createTestTempDirFromPath(join(tmpdir(), "mc-foreground-wait-"));
21
+ const path = join(dir, "context.db");
22
+ const db = new Database(path);
23
+ db.exec(`
24
+ PRAGMA journal_mode=WAL;
25
+ PRAGMA busy_timeout=5000;
26
+ CREATE TABLE context_privilege_state(id INTEGER PRIMARY KEY, enabled INTEGER);
27
+ CREATE TABLE result(value TEXT);
28
+ `);
29
+ return {
30
+ db,
31
+ path,
32
+ close() {
33
+ db.close();
34
+ rmSync(dir, { recursive: true, force: true });
35
+ },
36
+ };
37
+ }
38
+
39
+ for (const holdMs of [1000, 2500]) {
40
+ test(holdMs === 1000
41
+ ? "a transform commits and serves managed output after a 1s in-pass writer lock"
42
+ : "a transform refuses a 2.5s in-pass writer lock without raw fallback and logs the real wait", async () => {
43
+ const { db, path, close } = fixture();
44
+ const sessionId = `foreground-wait-${holdMs}`;
45
+ const output = {
46
+ messages: [
47
+ {
48
+ info: { id: "u", sessionID: sessionId, role: "user" },
49
+ parts: [{ type: "text", text: "raw input must not be served on failure" }],
50
+ },
51
+ ],
52
+ };
53
+ let locker: SqliteWriteLocker | undefined;
54
+ let refusals = 0;
55
+ let served = false;
56
+ let waitedMs = 0;
57
+ const diagnostics: string[] = [];
58
+ registerSqliteDiagnosticSink((line) => diagnostics.push(line));
59
+ const handler = createMessagesTransformHandler({
60
+ onStorageBusyRefusal: async (id) => {
61
+ expect(id).toBe(sessionId);
62
+ refusals++;
63
+ },
64
+ magicContext: {
65
+ "experimental.chat.messages.transform": async (_input, result) => {
66
+ // Start the competing writer only once the transform callback begins;
67
+ // otherwise the wrapper's yielding lock check would absorb the wait.
68
+ locker = await startSqliteWriteLocker(path, holdMs);
69
+ const started = performance.now();
70
+ try {
71
+ withPrivilegedWriter(db, () => {
72
+ db.prepare("INSERT INTO result VALUES ('managed')").run();
73
+ });
74
+ } finally {
75
+ waitedMs = performance.now() - started;
76
+ }
77
+ (result.messages[0].parts[0] as { text: string }).text = "managed output";
78
+ },
79
+ },
80
+ });
81
+ try {
82
+ const pass = handler({}, output as Parameters<typeof handler>[1]).then((messages) => {
83
+ served = true;
84
+ return messages;
85
+ });
86
+ if (holdMs === 1000) {
87
+ await pass;
88
+ expect(served).toBe(true);
89
+ expect(refusals).toBe(0);
90
+ expect(output.messages[0].parts[0].text).toBe("managed output");
91
+ expect(db.prepare("SELECT * FROM result").all()).toEqual([{ value: "managed" }]);
92
+ expect(waitedMs).toBeGreaterThanOrEqual(900);
93
+ } else {
94
+ await expect(pass).rejects.toBeInstanceOf(StorageBusyRefusalError);
95
+ expect(served).toBe(false);
96
+ expect(refusals).toBe(1);
97
+ expect(db.prepare("SELECT * FROM result").all()).toEqual([]);
98
+ expect(waitedMs).toBeGreaterThanOrEqual(1900);
99
+ expect(waitedMs).toBeLessThan(2400);
100
+ const busy = diagnostics.filter((line) => line.includes("outcome=busy"));
101
+ expect(busy).toHaveLength(1);
102
+ expect(busy[0]).toContain("lane=foreground");
103
+ const reportedMs = Number(/acquire_ms=(\d+)/.exec(busy[0])?.[1]);
104
+ expect(Math.abs(reportedMs - waitedMs)).toBeLessThan(100);
105
+ }
106
+ expect(db.inTransaction).toBe(false);
107
+ expect(db.prepare("PRAGMA busy_timeout").get()).toEqual({ timeout: 5000 });
108
+ } finally {
109
+ registerSqliteDiagnosticSink(log);
110
+ if (locker) expect(await locker.exited).toBe(0);
111
+ close();
112
+ }
113
+ }, 30_000);
114
+ }
115
+
116
+ for (const mode of ["BEGIN", "autocommit"]) {
117
+ test(`foreground ${mode} wait is capped by the pass deadline`, () => {
118
+ const { db, path, close } = fixture();
119
+ const blocker = new Database(path);
120
+ blocker.exec("BEGIN IMMEDIATE");
121
+ try {
122
+ const started = performance.now();
123
+ withSqliteTransformPass(() => {
124
+ guardSqliteTransformPass({ assert() {}, remainingMs: () => 100 });
125
+ expect(() => {
126
+ if (mode === "BEGIN") withPrivilegedWriter(db, () => undefined);
127
+ else db.prepare("INSERT INTO result VALUES ('late')").run();
128
+ }).toThrow(SqliteAcquisitionBusyError);
129
+ });
130
+ expect(performance.now() - started).toBeGreaterThanOrEqual(75);
131
+ expect(performance.now() - started).toBeLessThan(700);
132
+ expect(db.prepare("SELECT * FROM result").all()).toEqual([]);
133
+ expect(db.prepare("PRAGMA busy_timeout").get()).toEqual({ timeout: 5000 });
134
+ } finally {
135
+ blocker.exec("ROLLBACK");
136
+ blocker.close();
137
+ close();
138
+ }
139
+ });
140
+ }
@@ -100,7 +100,7 @@ test("foreground admission keeps the loop ticking while a separate writer holds
100
100
  }
101
101
  }, 30000);
102
102
 
103
- test("a foreground in-pass writer has bounded 250ms tolerance and restores its timeout", () => {
103
+ test("a foreground in-pass writer has bounded 2000ms tolerance and restores its timeout", () => {
104
104
  const { db, path, close } = fixture();
105
105
  const blocker = new Database(path);
106
106
  blocker.exec("BEGIN IMMEDIATE");
@@ -109,15 +109,15 @@ test("a foreground in-pass writer has bounded 250ms tolerance and restores its t
109
109
  expect(() =>
110
110
  withSqliteTransformPass(() => withPrivilegedWriter(db, () => undefined)),
111
111
  ).toThrow(SqliteAcquisitionBusyError);
112
- expect(performance.now() - start).toBeGreaterThanOrEqual(200);
113
- expect(performance.now() - start).toBeLessThan(400);
112
+ expect(performance.now() - start).toBeGreaterThanOrEqual(1900);
113
+ expect(performance.now() - start).toBeLessThan(2500);
114
114
  expect(db.prepare("PRAGMA busy_timeout").get()).toEqual({ timeout: 5000 });
115
115
  } finally {
116
116
  blocker.exec("ROLLBACK");
117
117
  blocker.close();
118
118
  close();
119
119
  }
120
- });
120
+ }, 30000);
121
121
 
122
122
  test("ready background publication retries on a timer and retains its write", async () => {
123
123
  const { db, path, close } = fixture();
@@ -940,7 +940,7 @@ export class SqliteAcquisitionBusyError extends Error {
940
940
  }
941
941
 
942
942
  const SHORT_BUSY_TIMEOUT_MS = 25;
943
- const FOREGROUND_IN_PASS_BUSY_TIMEOUT_MS = 250;
943
+ const FOREGROUND_IN_PASS_BUSY_TIMEOUT_MS = 2_000;
944
944
  const FOREGROUND_ACQUISITION_BUDGET_MS = 16_500;
945
945
  /** Waiting this long for the writer lock, or holding it this long, is logged. */
946
946
  const SLOW_WRITER_LOG_MS = 250;
@@ -994,7 +994,7 @@ function withAutocommitTimeout<T>(db: Database, operation: () => T): T {
994
994
  if (isInTransaction(db) || (!lease && !backgroundWriterScope.getStore())) return operation();
995
995
  const previous = pragmaNumber(db, "busy_timeout");
996
996
  db.exec(
997
- `PRAGMA busy_timeout=${lease ? Math.floor(lease.remainingWaitMs) : SHORT_BUSY_TIMEOUT_MS}`,
997
+ `PRAGMA busy_timeout=${lease ? Math.floor(Math.min(lease.remainingWaitMs, lease.guard?.remainingMs() ?? Infinity)) : SHORT_BUSY_TIMEOUT_MS}`,
998
998
  );
999
999
  const started = performance.now();
1000
1000
  try {