@namzu/sdk 14.0.1 → 14.0.3

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/CHANGELOG.md CHANGED
@@ -1,5 +1,55 @@
1
1
  # Changelog
2
2
 
3
+ ## 14.0.3
4
+
5
+ ### Patch Changes
6
+
7
+ - c50f9bf: `ProjectManager.archive` refuses when it cannot establish the precondition.
8
+
9
+ 14.0.0 shipped archival that "refuses rather than cascading" — a workspace with
10
+ a live session throws `ProjectNotEmptyError` instead of closing over running
11
+ work. The check read the session list as
12
+ `(await store.listSessionsByProject?.(...)) ?? []`, and `listSessionsByProject`
13
+ is optional. So on a store that does not implement it, "this store cannot tell
14
+ me what is running here" became "nothing is running here": the workspace closed
15
+ over live sessions and the call returned success.
16
+
17
+ It now throws, naming the missing method and what to do instead. Both stores in
18
+ this package implement it, so nothing in-tree changes; a host with its own
19
+ `SessionStore` gets a refusal where it previously got a wrong answer.
20
+
21
+ The mistake is worth naming, because the two halves are each correct and only
22
+ the combination is not. Optional-on-the-interface protects implementors: a
23
+ host's own store should not stop compiling because the SDK grew a method. It
24
+ cannot also mean a **safety precondition silently passes**. Where a store
25
+ cannot answer the question the check exists to ask, the answer is a refusal,
26
+ not a default.
27
+
28
+ ## 14.0.2
29
+
30
+ ### Patch Changes
31
+
32
+ - 9e03c89: `InMemoryTaskStore.block()` stops announcing an edge that already existed.
33
+
34
+ The two task stores disagreed about what `task.updated` means. `block()` is
35
+ idempotent on both — each guards its array against a duplicate entry — but only
36
+ the disk store guarded the _announcement_. Calling `block(a, b)` twice emitted
37
+ two `task.updated` events from the in-memory store and one from the disk store,
38
+ which is the one a host runs in production.
39
+
40
+ So a host rebuilding a dependency graph from the event stream did redundant
41
+ work against the reference implementation and not the durable one, and a host
42
+ counting events to detect change saw change where there was none. The
43
+ divergence is the kind that stays invisible until a store is swapped.
44
+
45
+ The disk store's behaviour was already correct and is now the behaviour of
46
+ both. No event is lost: a call that establishes a new edge — including one that
47
+ repairs a half-edge, where only one of the two arrays grows — still announces
48
+ both ends, because both ends are one fact.
49
+
50
+ The disk store's side of this had no test, which is why the disagreement
51
+ survived. Both are now driven from the same cases.
52
+
3
53
  ## 14.0.1
4
54
 
5
55
  ### Patch Changes
@@ -205,4 +205,44 @@ describe('a workspace stored before it had a status', () => {
205
205
  expect(archived.status).toBe('archived');
206
206
  });
207
207
  });
208
+ describe('a store that cannot answer the precondition', () => {
209
+ /**
210
+ * `listSessionsByProject` is optional on `SessionStore` so a host's own
211
+ * store keeps compiling. The archive path read it as
212
+ * `(await store.listSessionsByProject?.(...)) ?? []`, which turned "this
213
+ * store cannot tell me what is running here" into "nothing is running
214
+ * here" — so a host with such a store closed a workspace over live
215
+ * sessions and got a success back. The refusal that the whole feature is
216
+ * about was skippable by not implementing one method.
217
+ */
218
+ function storeWithoutTheListing(inner) {
219
+ const partial = {};
220
+ for (const key of [
221
+ 'getProject',
222
+ 'createProject',
223
+ 'createSession',
224
+ 'getSession',
225
+ 'updateSession',
226
+ 'setProjectStatus',
227
+ ]) {
228
+ const fn = inner[key];
229
+ if (typeof fn === 'function')
230
+ partial[key] = fn.bind(inner);
231
+ }
232
+ return partial;
233
+ }
234
+ it('refuses to archive rather than assuming the workspace is empty', async () => {
235
+ const h = await harness();
236
+ await h.store.updateSession({ ...h.parentSession, status: 'active' }, TENANT);
237
+ const blind = new ProjectManager({ store: storeWithoutTheListing(h.store) });
238
+ await expect(blind.archive(h.project.id, TENANT)).rejects.toThrow(/listSessionsByProject/);
239
+ });
240
+ it('leaves the workspace open after refusing', async () => {
241
+ // The refusal has to happen before the write, or it is only a message.
242
+ const h = await harness();
243
+ const blind = new ProjectManager({ store: storeWithoutTheListing(h.store) });
244
+ await blind.archive(h.project.id, TENANT).catch(() => undefined);
245
+ expect((await h.store.getProject(h.project.id, TENANT))?.status).toBe('open');
246
+ });
247
+ });
208
248
  //# sourceMappingURL=a-closed-workspace-takes-no-work.test.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"a-closed-workspace-takes-no-work.test.js","sourceRoot":"","sources":["../../../../src/manager/project/__tests__/a-closed-workspace-takes-no-work.test.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"a-closed-workspace-takes-no-work.test.js","sourceRoot":"","sources":["../../../../src/manager/project/__tests__/a-closed-workspace-takes-no-work.test.ts"],"names":[],"mappings":"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"}
@@ -1 +1 @@
1
- {"version":3,"file":"lifecycle.d.ts","sourceRoot":"","sources":["../../../src/manager/project/lifecycle.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;GAiBG;AAOH,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,0BAA0B,CAAA;AACxD,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,+BAA+B,CAAA;AAE5D,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,4BAA4B,CAAA;AAC3D,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,8BAA8B,CAAA;AAgBhE;;;;;;;;;;GAUG;AACH,wBAAsB,kBAAkB,CACvC,KAAK,EAAE,IAAI,CAAC,YAAY,EAAE,YAAY,CAAC,EACvC,SAAS,EAAE,SAAS,EACpB,QAAQ,EAAE,QAAQ,EAClB,EAAE,EAAE,MAAM,GACR,OAAO,CAAC,OAAO,CAAC,CASlB;AAED,MAAM,WAAW,kBAAkB;IAClC,KAAK,EAAE,YAAY,CAAA;CACnB;AAED,qBAAa,cAAc;IACd,OAAO,CAAC,QAAQ,CAAC,IAAI;gBAAJ,IAAI,EAAE,kBAAkB;IAErD,sCAAsC;IACtC,WAAW,CAAC,SAAS,EAAE,SAAS,EAAE,QAAQ,EAAE,QAAQ,EAAE,EAAE,SAAiB,GAAG,OAAO,CAAC,OAAO,CAAC;IAI5F;;;;;;;;;;;;;OAaG;IACG,OAAO,CAAC,SAAS,EAAE,SAAS,EAAE,QAAQ,EAAE,QAAQ,GAAG,OAAO,CAAC,OAAO,CAAC;IAwBzE;;;;OAIG;IACG,MAAM,CAAC,SAAS,EAAE,SAAS,EAAE,QAAQ,EAAE,QAAQ,GAAG,OAAO,CAAC,OAAO,CAAC;YAS1D,KAAK;CAwBnB"}
1
+ {"version":3,"file":"lifecycle.d.ts","sourceRoot":"","sources":["../../../src/manager/project/lifecycle.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;GAiBG;AAOH,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,0BAA0B,CAAA;AACxD,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,+BAA+B,CAAA;AAE5D,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,4BAA4B,CAAA;AAC3D,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,8BAA8B,CAAA;AAgBhE;;;;;;;;;;GAUG;AACH,wBAAsB,kBAAkB,CACvC,KAAK,EAAE,IAAI,CAAC,YAAY,EAAE,YAAY,CAAC,EACvC,SAAS,EAAE,SAAS,EACpB,QAAQ,EAAE,QAAQ,EAClB,EAAE,EAAE,MAAM,GACR,OAAO,CAAC,OAAO,CAAC,CASlB;AAED,MAAM,WAAW,kBAAkB;IAClC,KAAK,EAAE,YAAY,CAAA;CACnB;AAED,qBAAa,cAAc;IACd,OAAO,CAAC,QAAQ,CAAC,IAAI;gBAAJ,IAAI,EAAE,kBAAkB;IAErD,sCAAsC;IACtC,WAAW,CAAC,SAAS,EAAE,SAAS,EAAE,QAAQ,EAAE,QAAQ,EAAE,EAAE,SAAiB,GAAG,OAAO,CAAC,OAAO,CAAC;IAI5F;;;;;;;;;;;;;OAaG;IACG,OAAO,CAAC,SAAS,EAAE,SAAS,EAAE,QAAQ,EAAE,QAAQ,GAAG,OAAO,CAAC,OAAO,CAAC;IA0CzE;;;;OAIG;IACG,MAAM,CAAC,SAAS,EAAE,SAAS,EAAE,QAAQ,EAAE,QAAQ,GAAG,OAAO,CAAC,OAAO,CAAC;YAS1D,KAAK;CAwBnB"}
@@ -79,7 +79,23 @@ export class ProjectManager {
79
79
  if (!project) {
80
80
  throw new Error(`Project ${projectId} not found for tenant ${tenantId} — archive rejected`);
81
81
  }
82
- const sessions = (await this.deps.store.listSessionsByProject?.(projectId, tenantId)) ?? [];
82
+ // An unanswerable precondition is a refusal, not an empty answer.
83
+ //
84
+ // This read used to be `?? []`, which turned "this store cannot tell me
85
+ // what is running here" into "nothing is running here": a store without
86
+ // the optional method archived the workspace over live sessions and
87
+ // reported success. The whole point of the check is that archival does
88
+ // not cascade over running work, and the check was skippable by any
89
+ // store that had not implemented one optional method.
90
+ //
91
+ // Optional on the interface protects implementors — a host's own store
92
+ // should not stop compiling because the SDK grew a method. It cannot
93
+ // also mean a safety precondition silently passes.
94
+ const listByProject = this.deps.store.listSessionsByProject;
95
+ if (!listByProject) {
96
+ throw new Error(`Project ${projectId} cannot be archived: this SessionStore does not implement listSessionsByProject, so whether a session is still running in the workspace cannot be established. Implement it, or settle and verify the sessions through your own path before closing the workspace.`);
97
+ }
98
+ const sessions = await listByProject.call(this.deps.store, projectId, tenantId);
83
99
  const blocking = sessions.filter((s) => ARCHIVAL_BLOCKING_STATUSES.has(s.status));
84
100
  if (blocking.length > 0) {
85
101
  throw new ProjectNotEmptyError({
@@ -1 +1 @@
1
- {"version":3,"file":"lifecycle.js","sourceRoot":"","sources":["../../../src/manager/project/lifecycle.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"lifecycle.js","sourceRoot":"","sources":["../../../src/manager/project/lifecycle.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,2 @@
1
+ export {};
2
+ //# sourceMappingURL=an-edge-that-already-exists-is-not-news.test.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"an-edge-that-already-exists-is-not-news.test.d.ts","sourceRoot":"","sources":["../../../../src/store/task/__tests__/an-edge-that-already-exists-is-not-news.test.ts"],"names":[],"mappings":""}
@@ -0,0 +1,95 @@
1
+ import { mkdtemp, rm } from 'node:fs/promises';
2
+ import { tmpdir } from 'node:os';
3
+ import { join } from 'node:path';
4
+ import { afterEach, describe, expect, it } from 'vitest';
5
+ import { DiskTaskStore } from '../disk.js';
6
+ import { InMemoryTaskStore } from '../memory.js';
7
+ /**
8
+ * The two stores disagreed about what `task.updated` means.
9
+ *
10
+ * `block()` is idempotent on both — it guards each array against a duplicate
11
+ * entry — but only the disk store guarded the *announcement*. Calling
12
+ * `block(a, b)` twice emitted two `task.updated` events from the in-memory
13
+ * store and one from the disk store, which is the one a host runs in
14
+ * production. So a host rebuilding a dependency graph from the stream did
15
+ * redundant work against the reference implementation and not the durable one,
16
+ * and a host counting events to detect change saw change where there was none.
17
+ *
18
+ * The disk store's behaviour is the correct one and the in-memory store now
19
+ * matches it: an edge that already existed is not news.
20
+ *
21
+ * Both are driven from the same cases here, because a reference implementation
22
+ * that disagrees with the durable one is worse than having only one — the
23
+ * disagreement is invisible until a host swaps stores in production.
24
+ */
25
+ const RUN = 'run_edge';
26
+ const dirs = [];
27
+ afterEach(async () => {
28
+ await Promise.all(dirs.map((d) => rm(d, { recursive: true, force: true })));
29
+ dirs.length = 0;
30
+ });
31
+ async function diskStore() {
32
+ const dir = await mkdtemp(join(tmpdir(), 'namzu-edge-'));
33
+ dirs.push(dir);
34
+ return new DiskTaskStore({ baseDir: dir, defaultRunId: RUN });
35
+ }
36
+ const IMPLEMENTATIONS = [
37
+ ['in memory', async () => new InMemoryTaskStore()],
38
+ ['on disk', diskStore],
39
+ ];
40
+ describe.each(IMPLEMENTATIONS)('an edge that already exists is not news (%s)', (_n, build) => {
41
+ async function twoTasks(store) {
42
+ const blocker = await store.create({ runId: RUN, subject: 'blocker' });
43
+ const blocked = await store.create({ runId: RUN, subject: 'blocked' });
44
+ return { blocker, blocked };
45
+ }
46
+ function recordUpdates(store) {
47
+ const seen = [];
48
+ store.on((event) => {
49
+ if (event.type === 'task.updated')
50
+ seen.push(event);
51
+ });
52
+ return seen;
53
+ }
54
+ it('announces both ends when the edge is written', async () => {
55
+ // The control: without it, "no second announcement" could be passing
56
+ // because nothing announces at all.
57
+ const store = await build();
58
+ const { blocker, blocked } = await twoTasks(store);
59
+ const seen = recordUpdates(store);
60
+ await store.block(blocker.id, blocked.id);
61
+ expect(seen.map((e) => e.taskId)).toEqual([blocker.id, blocked.id]);
62
+ });
63
+ it('says nothing the second time', async () => {
64
+ const store = await build();
65
+ const { blocker, blocked } = await twoTasks(store);
66
+ await store.block(blocker.id, blocked.id);
67
+ const seen = recordUpdates(store);
68
+ await store.block(blocker.id, blocked.id);
69
+ expect(seen).toEqual([]);
70
+ });
71
+ it('still records the edge exactly once after a repeated call', async () => {
72
+ // Suppressing the event must not become suppressing the write, and the
73
+ // arrays must not grow a duplicate.
74
+ const store = await build();
75
+ const { blocker, blocked } = await twoTasks(store);
76
+ await store.block(blocker.id, blocked.id);
77
+ await store.block(blocker.id, blocked.id);
78
+ expect((await store.get(blocker.id))?.blocks).toEqual([blocked.id]);
79
+ expect((await store.get(blocked.id))?.blockedBy).toEqual([blocker.id]);
80
+ });
81
+ it('announces a repair when only one side of the edge was missing', async () => {
82
+ // A half-edge is the case the early return must not swallow: one array
83
+ // already names the other and its counterpart does not. Both ends are
84
+ // one fact, so both are announced even though only one array grew.
85
+ const store = await build();
86
+ const { blocker, blocked } = await twoTasks(store);
87
+ await store.block(blocker.id, blocked.id);
88
+ // Reverse direction: `blocked` has not yet been recorded as blocking
89
+ // `blocker`, so this is a new edge, not the existing one.
90
+ const seen = recordUpdates(store);
91
+ await store.block(blocked.id, blocker.id);
92
+ expect(seen.map((e) => e.taskId)).toEqual([blocked.id, blocker.id]);
93
+ });
94
+ });
95
+ //# sourceMappingURL=an-edge-that-already-exists-is-not-news.test.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"an-edge-that-already-exists-is-not-news.test.js","sourceRoot":"","sources":["../../../../src/store/task/__tests__/an-edge-that-already-exists-is-not-news.test.ts"],"names":[],"mappings":"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"}
@@ -1 +1 @@
1
- {"version":3,"file":"memory.d.ts","sourceRoot":"","sources":["../../../src/store/task/memory.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,KAAK,EAAE,MAAM,EAAE,MAAM,0BAA0B,CAAA;AAC7D,OAAO,KAAK,EACX,gBAAgB,EAChB,IAAI,EAEJ,iBAAiB,EACjB,UAAU,EACV,SAAS,EACT,gBAAgB,EAChB,MAAM,2BAA2B,CAAA;AAmBlC,qBAAa,iBAAkB,YAAW,SAAS;IAClD,OAAO,CAAC,KAAK,CAA0B;IACvC,OAAO,CAAC,SAAS,CAA0B;IAE3C,EAAE,CAAC,QAAQ,EAAE,iBAAiB,GAAG,MAAM,IAAI;IAO3C,OAAO,CAAC,IAAI;IAQN,MAAM,CAAC,MAAM,EAAE,gBAAgB,GAAG,OAAO,CAAC,IAAI,CAAC;IA+B/C,GAAG,CAAC,EAAE,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,GAAG,SAAS,CAAC;IAI1C,MAAM,CAAC,EAAE,EAAE,MAAM,EAAE,OAAO,EAAE,gBAAgB,GAAG,OAAO,CAAC,IAAI,GAAG,SAAS,CAAC;IAwCxE,MAAM,CAAC,EAAE,EAAE,MAAM,GAAG,OAAO,CAAC,OAAO,CAAC;IAsBpC,IAAI,CAAC,MAAM,CAAC,EAAE;QAAE,MAAM,CAAC,EAAE,UAAU,CAAC;QAAC,KAAK,CAAC,EAAE,MAAM,CAAC;QAAC,KAAK,CAAC,EAAE,KAAK,CAAA;KAAE,GAAG,OAAO,CAAC,IAAI,EAAE,CAAC;IAgBtF,KAAK,CAAC,EAAE,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,GAAG,SAAS,CAAC;IAc3D,KAAK,CAAC,SAAS,EAAE,MAAM,EAAE,SAAS,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC;IAsB1D,KAAK,IAAI,OAAO,CAAC,IAAI,CAAC;CAG5B"}
1
+ {"version":3,"file":"memory.d.ts","sourceRoot":"","sources":["../../../src/store/task/memory.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,KAAK,EAAE,MAAM,EAAE,MAAM,0BAA0B,CAAA;AAC7D,OAAO,KAAK,EACX,gBAAgB,EAChB,IAAI,EAEJ,iBAAiB,EACjB,UAAU,EACV,SAAS,EACT,gBAAgB,EAChB,MAAM,2BAA2B,CAAA;AAmBlC,qBAAa,iBAAkB,YAAW,SAAS;IAClD,OAAO,CAAC,KAAK,CAA0B;IACvC,OAAO,CAAC,SAAS,CAA0B;IAE3C,EAAE,CAAC,QAAQ,EAAE,iBAAiB,GAAG,MAAM,IAAI;IAO3C,OAAO,CAAC,IAAI;IAQN,MAAM,CAAC,MAAM,EAAE,gBAAgB,GAAG,OAAO,CAAC,IAAI,CAAC;IA+B/C,GAAG,CAAC,EAAE,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,GAAG,SAAS,CAAC;IAI1C,MAAM,CAAC,EAAE,EAAE,MAAM,EAAE,OAAO,EAAE,gBAAgB,GAAG,OAAO,CAAC,IAAI,GAAG,SAAS,CAAC;IAwCxE,MAAM,CAAC,EAAE,EAAE,MAAM,GAAG,OAAO,CAAC,OAAO,CAAC;IAsBpC,IAAI,CAAC,MAAM,CAAC,EAAE;QAAE,MAAM,CAAC,EAAE,UAAU,CAAC;QAAC,KAAK,CAAC,EAAE,MAAM,CAAC;QAAC,KAAK,CAAC,EAAE,KAAK,CAAA;KAAE,GAAG,OAAO,CAAC,IAAI,EAAE,CAAC;IAgBtF,KAAK,CAAC,EAAE,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,GAAG,SAAS,CAAC;IAc3D,KAAK,CAAC,SAAS,EAAE,MAAM,EAAE,SAAS,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC;IAiC1D,KAAK,IAAI,OAAO,CAAC,IAAI,CAAC;CAG5B"}
@@ -150,17 +150,29 @@ export class InMemoryTaskStore {
150
150
  const blocked = this.tasks.get(blockedId);
151
151
  if (!blocker || !blocked)
152
152
  return;
153
+ let mutated = false;
153
154
  if (!blocker.blocks.includes(blockedId)) {
154
155
  blocker.blocks.push(blockedId);
156
+ mutated = true;
155
157
  }
156
158
  if (!blocked.blockedBy.includes(blockerId)) {
157
159
  blocked.blockedBy.push(blockerId);
160
+ mutated = true;
158
161
  }
162
+ // An edge that already existed is not news. This used to announce
163
+ // unconditionally while the disk store — the one a host runs in
164
+ // production — returned early, so the same call sequence produced two
165
+ // events from one implementation and none from the other. A host
166
+ // rebuilding a graph from the stream did redundant work against one
167
+ // store and not the other, and a host counting events to detect change
168
+ // saw change where there was none.
169
+ if (!mutated)
170
+ return;
159
171
  // Announce BOTH ends. The edge was written and nothing said so, which
160
172
  // left the graph observable only by polling: a listener saw a unit
161
173
  // created and never learned that something now waits on it. Both sides
162
- // changed, so both are announced a host tracking only one would draw
163
- // half the edge.
174
+ // are one fact, so both are announced even when only one array grew —
175
+ // a host tracking a single side would draw half the edge.
164
176
  const now = Date.now();
165
177
  this.emit({ type: 'task.updated', taskId: blockerId, task: blocker, timestamp: now });
166
178
  this.emit({ type: 'task.updated', taskId: blockedId, task: blocked, timestamp: now });
@@ -1 +1 @@
1
- {"version":3,"file":"memory.js","sourceRoot":"","sources":["../../../src/store/task/memory.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"memory.js","sourceRoot":"","sources":["../../../src/store/task/memory.ts"],"names":[],"mappings":"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"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@namzu/sdk",
3
- "version": "14.0.1",
3
+ "version": "14.0.3",
4
4
  "description": "Open-source AI agent SDK with a built-in runtime. Nothing between you and your agents.",
5
5
  "license": "FSL-1.1-MIT",
6
6
  "type": "module",
@@ -22,6 +22,7 @@ import type { AgentDefinition } from '../../../types/agent/factory.js'
22
22
  import type { AgentTaskContext } from '../../../types/agent/task.js'
23
23
  import type { AgentId, TenantId } from '../../../types/ids/index.js'
24
24
  import type { SummaryId } from '../../../types/session/ids.js'
25
+ import type { SessionStore } from '../../../types/session/store.js'
25
26
  import { ZERO_COST } from '../../../utils/cost.js'
26
27
  import { AgentManager } from '../../agent/lifecycle.js'
27
28
  import { ThreadManager } from '../../thread/lifecycle.js'
@@ -266,3 +267,48 @@ describe('a workspace stored before it had a status', () => {
266
267
  expect(archived.status).toBe('archived')
267
268
  })
268
269
  })
270
+
271
+ describe('a store that cannot answer the precondition', () => {
272
+ /**
273
+ * `listSessionsByProject` is optional on `SessionStore` so a host's own
274
+ * store keeps compiling. The archive path read it as
275
+ * `(await store.listSessionsByProject?.(...)) ?? []`, which turned "this
276
+ * store cannot tell me what is running here" into "nothing is running
277
+ * here" — so a host with such a store closed a workspace over live
278
+ * sessions and got a success back. The refusal that the whole feature is
279
+ * about was skippable by not implementing one method.
280
+ */
281
+ function storeWithoutTheListing(inner: SessionStore): SessionStore {
282
+ const partial: Record<string, unknown> = {}
283
+ for (const key of [
284
+ 'getProject',
285
+ 'createProject',
286
+ 'createSession',
287
+ 'getSession',
288
+ 'updateSession',
289
+ 'setProjectStatus',
290
+ ]) {
291
+ const fn = (inner as unknown as Record<string, unknown>)[key]
292
+ if (typeof fn === 'function') partial[key] = (fn as (...a: unknown[]) => unknown).bind(inner)
293
+ }
294
+ return partial as unknown as SessionStore
295
+ }
296
+
297
+ it('refuses to archive rather than assuming the workspace is empty', async () => {
298
+ const h = await harness()
299
+ await h.store.updateSession({ ...h.parentSession, status: 'active' }, TENANT)
300
+ const blind = new ProjectManager({ store: storeWithoutTheListing(h.store) })
301
+
302
+ await expect(blind.archive(h.project.id, TENANT)).rejects.toThrow(/listSessionsByProject/)
303
+ })
304
+
305
+ it('leaves the workspace open after refusing', async () => {
306
+ // The refusal has to happen before the write, or it is only a message.
307
+ const h = await harness()
308
+ const blind = new ProjectManager({ store: storeWithoutTheListing(h.store) })
309
+
310
+ await blind.archive(h.project.id, TENANT).catch(() => undefined)
311
+
312
+ expect((await h.store.getProject(h.project.id, TENANT))?.status).toBe('open')
313
+ })
314
+ })
@@ -101,7 +101,25 @@ export class ProjectManager {
101
101
  throw new Error(`Project ${projectId} not found for tenant ${tenantId} — archive rejected`)
102
102
  }
103
103
 
104
- const sessions = (await this.deps.store.listSessionsByProject?.(projectId, tenantId)) ?? []
104
+ // An unanswerable precondition is a refusal, not an empty answer.
105
+ //
106
+ // This read used to be `?? []`, which turned "this store cannot tell me
107
+ // what is running here" into "nothing is running here": a store without
108
+ // the optional method archived the workspace over live sessions and
109
+ // reported success. The whole point of the check is that archival does
110
+ // not cascade over running work, and the check was skippable by any
111
+ // store that had not implemented one optional method.
112
+ //
113
+ // Optional on the interface protects implementors — a host's own store
114
+ // should not stop compiling because the SDK grew a method. It cannot
115
+ // also mean a safety precondition silently passes.
116
+ const listByProject = this.deps.store.listSessionsByProject
117
+ if (!listByProject) {
118
+ throw new Error(
119
+ `Project ${projectId} cannot be archived: this SessionStore does not implement listSessionsByProject, so whether a session is still running in the workspace cannot be established. Implement it, or settle and verify the sessions through your own path before closing the workspace.`,
120
+ )
121
+ }
122
+ const sessions = await listByProject.call(this.deps.store, projectId, tenantId)
105
123
  const blocking = sessions.filter((s) => ARCHIVAL_BLOCKING_STATUSES.has(s.status))
106
124
  if (blocking.length > 0) {
107
125
  throw new ProjectNotEmptyError({
@@ -0,0 +1,115 @@
1
+ import { mkdtemp, rm } from 'node:fs/promises'
2
+ import { tmpdir } from 'node:os'
3
+ import { join } from 'node:path'
4
+ import { afterEach, describe, expect, it } from 'vitest'
5
+
6
+ import type { RunId } from '../../../types/ids/index.js'
7
+ import type { TaskEvent, TaskStore } from '../../../types/task/index.js'
8
+ import { DiskTaskStore } from '../disk.js'
9
+ import { InMemoryTaskStore } from '../memory.js'
10
+
11
+ /**
12
+ * The two stores disagreed about what `task.updated` means.
13
+ *
14
+ * `block()` is idempotent on both — it guards each array against a duplicate
15
+ * entry — but only the disk store guarded the *announcement*. Calling
16
+ * `block(a, b)` twice emitted two `task.updated` events from the in-memory
17
+ * store and one from the disk store, which is the one a host runs in
18
+ * production. So a host rebuilding a dependency graph from the stream did
19
+ * redundant work against the reference implementation and not the durable one,
20
+ * and a host counting events to detect change saw change where there was none.
21
+ *
22
+ * The disk store's behaviour is the correct one and the in-memory store now
23
+ * matches it: an edge that already existed is not news.
24
+ *
25
+ * Both are driven from the same cases here, because a reference implementation
26
+ * that disagrees with the durable one is worse than having only one — the
27
+ * disagreement is invisible until a host swaps stores in production.
28
+ */
29
+
30
+ const RUN = 'run_edge' as RunId
31
+
32
+ const dirs: string[] = []
33
+ afterEach(async () => {
34
+ await Promise.all(dirs.map((d) => rm(d, { recursive: true, force: true })))
35
+ dirs.length = 0
36
+ })
37
+
38
+ async function diskStore(): Promise<TaskStore> {
39
+ const dir = await mkdtemp(join(tmpdir(), 'namzu-edge-'))
40
+ dirs.push(dir)
41
+ return new DiskTaskStore({ baseDir: dir, defaultRunId: RUN })
42
+ }
43
+
44
+ const IMPLEMENTATIONS: ReadonlyArray<readonly [string, () => Promise<TaskStore>]> = [
45
+ ['in memory', async () => new InMemoryTaskStore()],
46
+ ['on disk', diskStore],
47
+ ]
48
+
49
+ describe.each(IMPLEMENTATIONS)('an edge that already exists is not news (%s)', (_n, build) => {
50
+ async function twoTasks(store: TaskStore) {
51
+ const blocker = await store.create({ runId: RUN, subject: 'blocker' })
52
+ const blocked = await store.create({ runId: RUN, subject: 'blocked' })
53
+ return { blocker, blocked }
54
+ }
55
+
56
+ function recordUpdates(store: TaskStore): TaskEvent[] {
57
+ const seen: TaskEvent[] = []
58
+ store.on((event) => {
59
+ if (event.type === 'task.updated') seen.push(event)
60
+ })
61
+ return seen
62
+ }
63
+
64
+ it('announces both ends when the edge is written', async () => {
65
+ // The control: without it, "no second announcement" could be passing
66
+ // because nothing announces at all.
67
+ const store = await build()
68
+ const { blocker, blocked } = await twoTasks(store)
69
+ const seen = recordUpdates(store)
70
+
71
+ await store.block(blocker.id, blocked.id)
72
+
73
+ expect(seen.map((e) => e.taskId)).toEqual([blocker.id, blocked.id])
74
+ })
75
+
76
+ it('says nothing the second time', async () => {
77
+ const store = await build()
78
+ const { blocker, blocked } = await twoTasks(store)
79
+ await store.block(blocker.id, blocked.id)
80
+ const seen = recordUpdates(store)
81
+
82
+ await store.block(blocker.id, blocked.id)
83
+
84
+ expect(seen).toEqual([])
85
+ })
86
+
87
+ it('still records the edge exactly once after a repeated call', async () => {
88
+ // Suppressing the event must not become suppressing the write, and the
89
+ // arrays must not grow a duplicate.
90
+ const store = await build()
91
+ const { blocker, blocked } = await twoTasks(store)
92
+
93
+ await store.block(blocker.id, blocked.id)
94
+ await store.block(blocker.id, blocked.id)
95
+
96
+ expect((await store.get(blocker.id))?.blocks).toEqual([blocked.id])
97
+ expect((await store.get(blocked.id))?.blockedBy).toEqual([blocker.id])
98
+ })
99
+
100
+ it('announces a repair when only one side of the edge was missing', async () => {
101
+ // A half-edge is the case the early return must not swallow: one array
102
+ // already names the other and its counterpart does not. Both ends are
103
+ // one fact, so both are announced even though only one array grew.
104
+ const store = await build()
105
+ const { blocker, blocked } = await twoTasks(store)
106
+ await store.block(blocker.id, blocked.id)
107
+ // Reverse direction: `blocked` has not yet been recorded as blocking
108
+ // `blocker`, so this is a new edge, not the existing one.
109
+ const seen = recordUpdates(store)
110
+
111
+ await store.block(blocked.id, blocker.id)
112
+
113
+ expect(seen.map((e) => e.taskId)).toEqual([blocked.id, blocker.id])
114
+ })
115
+ })
@@ -177,18 +177,29 @@ export class InMemoryTaskStore implements TaskStore {
177
177
  const blocked = this.tasks.get(blockedId)
178
178
  if (!blocker || !blocked) return
179
179
 
180
+ let mutated = false
180
181
  if (!blocker.blocks.includes(blockedId)) {
181
182
  blocker.blocks.push(blockedId)
183
+ mutated = true
182
184
  }
183
185
  if (!blocked.blockedBy.includes(blockerId)) {
184
186
  blocked.blockedBy.push(blockerId)
187
+ mutated = true
185
188
  }
189
+ // An edge that already existed is not news. This used to announce
190
+ // unconditionally while the disk store — the one a host runs in
191
+ // production — returned early, so the same call sequence produced two
192
+ // events from one implementation and none from the other. A host
193
+ // rebuilding a graph from the stream did redundant work against one
194
+ // store and not the other, and a host counting events to detect change
195
+ // saw change where there was none.
196
+ if (!mutated) return
186
197
 
187
198
  // Announce BOTH ends. The edge was written and nothing said so, which
188
199
  // left the graph observable only by polling: a listener saw a unit
189
200
  // created and never learned that something now waits on it. Both sides
190
- // changed, so both are announced a host tracking only one would draw
191
- // half the edge.
201
+ // are one fact, so both are announced even when only one array grew —
202
+ // a host tracking a single side would draw half the edge.
192
203
  const now = Date.now()
193
204
  this.emit({ type: 'task.updated', taskId: blockerId, task: blocker, timestamp: now })
194
205
  this.emit({ type: 'task.updated', taskId: blockedId, task: blocked, timestamp: now })