@namzu/sdk 20.0.0 → 20.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.
Files changed (49) hide show
  1. package/CHANGELOG.md +108 -0
  2. package/dist/contracts/a2a.d.ts +2 -2
  3. package/dist/manager/run/persistence.d.ts.map +1 -1
  4. package/dist/manager/run/persistence.js +11 -0
  5. package/dist/manager/run/persistence.js.map +1 -1
  6. package/dist/public-runtime.d.ts +3 -1
  7. package/dist/public-runtime.d.ts.map +1 -1
  8. package/dist/public-runtime.js +7 -1
  9. package/dist/public-runtime.js.map +1 -1
  10. package/dist/runtime/query/checkpoint.d.ts +20 -0
  11. package/dist/runtime/query/checkpoint.d.ts.map +1 -1
  12. package/dist/runtime/query/checkpoint.js +47 -0
  13. package/dist/runtime/query/checkpoint.js.map +1 -1
  14. package/dist/store/index.d.ts +3 -0
  15. package/dist/store/index.d.ts.map +1 -1
  16. package/dist/store/index.js +12 -0
  17. package/dist/store/index.js.map +1 -1
  18. package/dist/store/run/checkpoint-disk.d.ts +56 -2
  19. package/dist/store/run/checkpoint-disk.d.ts.map +1 -1
  20. package/dist/store/run/checkpoint-disk.js +83 -2
  21. package/dist/store/run/checkpoint-disk.js.map +1 -1
  22. package/dist/store/run/checkpoint-memory.d.ts +31 -0
  23. package/dist/store/run/checkpoint-memory.d.ts.map +1 -0
  24. package/dist/store/run/checkpoint-memory.js +83 -0
  25. package/dist/store/run/checkpoint-memory.js.map +1 -0
  26. package/dist/store/run/disk.d.ts +53 -0
  27. package/dist/store/run/disk.d.ts.map +1 -1
  28. package/dist/store/run/disk.js +73 -30
  29. package/dist/store/run/disk.js.map +1 -1
  30. package/dist/store/run/listing.d.ts +75 -0
  31. package/dist/store/run/listing.d.ts.map +1 -0
  32. package/dist/store/run/listing.js +242 -0
  33. package/dist/store/run/listing.js.map +1 -0
  34. package/dist/types/hitl/index.d.ts +27 -0
  35. package/dist/types/hitl/index.d.ts.map +1 -1
  36. package/dist/types/hitl/index.js.map +1 -1
  37. package/dist/types/run/checkpoint-store.d.ts +260 -1
  38. package/dist/types/run/checkpoint-store.d.ts.map +1 -1
  39. package/package.json +1 -1
  40. package/src/manager/run/persistence.ts +18 -4
  41. package/src/public-runtime.ts +13 -0
  42. package/src/runtime/query/checkpoint.ts +51 -0
  43. package/src/store/index.ts +18 -0
  44. package/src/store/run/checkpoint-disk.ts +128 -4
  45. package/src/store/run/checkpoint-memory.ts +101 -0
  46. package/src/store/run/disk.ts +72 -27
  47. package/src/store/run/listing.ts +307 -0
  48. package/src/types/hitl/index.ts +28 -0
  49. package/src/types/run/checkpoint-store.ts +274 -1
@@ -0,0 +1,242 @@
1
+ /**
2
+ * Shared machinery for {@link CheckpointStore.listDurableRuns}.
3
+ *
4
+ * Every rule the listing promises — the contiguous-prefix refusal, the park
5
+ * precedence, the ordering, the paging — lives here and is used by BOTH
6
+ * shipped implementations. A rule implemented twice is a rule that holds in
7
+ * one store and not the other, and the whole point of a store contract is
8
+ * that a host can swap the backend without swapping the semantics.
9
+ */
10
+ import { NamzuError } from '../../types/errors/index.js';
11
+ /** Page size when the caller names none. */
12
+ export const DEFAULT_DURABLE_RUN_LIMIT = 100;
13
+ /**
14
+ * Refuse a listing scope with a hole in it.
15
+ *
16
+ * `{ tenantId, sessionId }` reads as "that session under whichever project
17
+ * holds it". A flat backend can answer it; a hierarchical one cannot look up
18
+ * a session without its project. Answering differently per backend is the
19
+ * one thing the contract exists to prevent, so neither answers: the caller
20
+ * names the project it means.
21
+ */
22
+ export function assertContiguousListingScope(scope, caller) {
23
+ if (scope.sessionId !== undefined && scope.projectId === undefined) {
24
+ throw new NamzuError({
25
+ code: 'invalid_config',
26
+ message: `${caller}: listing scope has a hole — \`sessionId\` was supplied without \`projectId\`. A run listing scope is a contiguous prefix of tenant → project → session; name the project the session belongs to.`,
27
+ details: { tenantId: scope.tenantId, sessionId: scope.sessionId },
28
+ });
29
+ }
30
+ }
31
+ /** Whether a park's absolute deadline has passed. No deadline never expires. */
32
+ function isPastDeadline(pending, now) {
33
+ return pending.deadlineAt !== undefined && now >= pending.deadlineAt;
34
+ }
35
+ /**
36
+ * Which of the three states a recorded park is in.
37
+ *
38
+ * `resolved` is checked FIRST: a park that was answered after its deadline
39
+ * passed is answered, not expired. Reading the deadline first would report
40
+ * a decision a human actually made as an expiry nobody made, and the
41
+ * checkpoint is the evidence record for exactly that question.
42
+ */
43
+ function parkStateOf(pending, now) {
44
+ if (pending.resolvedAt !== undefined)
45
+ return 'resolved';
46
+ return isPastDeadline(pending, now) ? 'expired' : 'outstanding';
47
+ }
48
+ function toParkSummary(cp, pending, now) {
49
+ return {
50
+ state: parkStateOf(pending, now),
51
+ checkpointId: cp.id,
52
+ requestType: pending.request.type,
53
+ parkedAt: pending.parkedAt,
54
+ ...(pending.deadlineAt !== undefined ? { deadlineAt: pending.deadlineAt } : {}),
55
+ ...(pending.resolvedAt !== undefined ? { resolvedAt: pending.resolvedAt } : {}),
56
+ };
57
+ }
58
+ /**
59
+ * The one park that describes what a run is doing now, out of every park it
60
+ * ever recorded.
61
+ *
62
+ * Precedence: newest `outstanding`, else newest `expired`, else newest
63
+ * `resolved`.
64
+ *
65
+ * `outstanding` wins because that is the question an inbox is asking, and
66
+ * because the answer has to be the SAME checkpoint `findPendingCheckpoint`
67
+ * returns. A run can hold several parks — it parks, a human answers, it runs
68
+ * on, it parks again — and it can hold an outstanding one that is older than
69
+ * a resolved one only in the reverse case, where an earlier park expired
70
+ * unanswered and the run was resumed past it. Ranking by recency alone would
71
+ * then hand an inbox a resolved checkpoint and report the live park as
72
+ * nothing.
73
+ *
74
+ * @param checkpoints the run's checkpoints, any order.
75
+ */
76
+ export function summarizePark(checkpoints, now) {
77
+ let best;
78
+ let bestRank = -1;
79
+ let bestParkedAt = Number.NEGATIVE_INFINITY;
80
+ for (const cp of checkpoints) {
81
+ const pending = cp.pending;
82
+ if (!pending)
83
+ continue;
84
+ const summary = toParkSummary(cp, pending, now);
85
+ const rank = PARK_RANK[summary.state];
86
+ if (rank > bestRank || (rank === bestRank && pending.parkedAt > bestParkedAt)) {
87
+ best = summary;
88
+ bestRank = rank;
89
+ bestParkedAt = pending.parkedAt;
90
+ }
91
+ }
92
+ return best;
93
+ }
94
+ const PARK_RANK = {
95
+ resolved: 0,
96
+ expired: 1,
97
+ outstanding: 2,
98
+ };
99
+ /**
100
+ * Project one run's checkpoints into a listing entry.
101
+ *
102
+ * Returns `null` for a run with no checkpoints: the listing is of runs with
103
+ * DURABLE state, and a run with nothing stored has nothing a sweeper could
104
+ * resume. A disk walk hits this case for real — a sub-run's directory is
105
+ * created as a bare shell under its own id before anything is written to it.
106
+ */
107
+ export function toDurableRunEntry(scope, checkpoints, now) {
108
+ if (checkpoints.length === 0)
109
+ return null;
110
+ let latest = checkpoints[0];
111
+ // The EARLIEST recorded stamp, not the one on any particular checkpoint.
112
+ // Every checkpoint of a run carries the same value, so under that
113
+ // invariant the minimum is that value. Taking the minimum rather than
114
+ // reading one checkpoint is what makes the read safe if the invariant is
115
+ // ever broken: it can only err toward the run's true attribution, never
116
+ // away from it, and it cannot move when a later checkpoint is added.
117
+ let runCreatedAt;
118
+ for (const cp of checkpoints) {
119
+ if (cp.createdAt > latest.createdAt)
120
+ latest = cp;
121
+ if (cp.runCreatedAt !== undefined &&
122
+ (runCreatedAt === undefined || cp.runCreatedAt < runCreatedAt)) {
123
+ runCreatedAt = cp.runCreatedAt;
124
+ }
125
+ }
126
+ const park = summarizePark(checkpoints, now);
127
+ return {
128
+ tenantId: scope.tenantId,
129
+ projectId: scope.projectId,
130
+ sessionId: scope.sessionId,
131
+ runId: scope.runId,
132
+ ...(scope.parentRunId ? { parentRunId: scope.parentRunId } : {}),
133
+ ...(runCreatedAt !== undefined ? { runCreatedAt } : {}),
134
+ checkpointCount: checkpoints.length,
135
+ latestCheckpointId: latest.id,
136
+ latestCheckpointAt: latest.createdAt,
137
+ ...(park ? { park } : {}),
138
+ };
139
+ }
140
+ /**
141
+ * Apply the park filter, the contract's ordering and the cursor to a set of
142
+ * entries an implementation has gathered.
143
+ *
144
+ * Both shipped stores gather differently — one walks a directory tree, one
145
+ * reads a map — and then hand the result here, so "ordered by `runId`, page
146
+ * ends where the next begins" is one implementation rather than two.
147
+ */
148
+ export function paginateDurableRuns(entries, options) {
149
+ const wanted = options?.park;
150
+ const filtered = wanted && wanted.length > 0
151
+ ? entries.filter((e) => e.park !== undefined && wanted.includes(e.park.state))
152
+ : entries;
153
+ // Both orders sort on a key that cannot move under a paging caller — see
154
+ // the contract comment on `listDurableRuns`.
155
+ const orderBy = options?.orderBy ?? 'runId';
156
+ const ordered = [...filtered].sort((a, b) => compareKeys(sortKey(a, orderBy), sortKey(b, orderBy)));
157
+ const after = options?.cursor === undefined ? undefined : decodeCursor(options.cursor, orderBy);
158
+ const start = after === undefined ? 0 : ordered.findIndex((e) => compareKeys(sortKey(e, orderBy), after) > 0);
159
+ const from = start < 0 ? ordered.length : start;
160
+ const limit = Math.max(1, Math.trunc(options?.limit ?? DEFAULT_DURABLE_RUN_LIMIT));
161
+ const page = ordered.slice(from, from + limit);
162
+ const exhausted = from + page.length >= ordered.length;
163
+ return {
164
+ entries: page,
165
+ // No cursor when there is nothing behind it, so `while (cursor)`
166
+ // terminates rather than fetching one empty page to find out.
167
+ ...(exhausted || page.length === 0
168
+ ? {}
169
+ : { cursor: encodeCursor(sortKey(page[page.length - 1], orderBy)) }),
170
+ };
171
+ }
172
+ function sortKey(entry, orderBy) {
173
+ if (orderBy === 'runId')
174
+ return [0, 0, entry.runId];
175
+ return entry.runCreatedAt === undefined
176
+ ? [0, 0, entry.runId]
177
+ : [1, entry.runCreatedAt, entry.runId];
178
+ }
179
+ function compareKeys(a, b) {
180
+ if (a[0] !== b[0])
181
+ return a[0] - b[0];
182
+ if (a[1] !== b[1])
183
+ return a[1] - b[1];
184
+ return a[2] < b[2] ? -1 : a[2] > b[2] ? 1 : 0;
185
+ }
186
+ /**
187
+ * The cursor is the last row's key, and nothing else.
188
+ *
189
+ * Opaque to callers by contract — the shape is written down here rather than
190
+ * in the type so a host is not tempted to construct one. Run ids come from a
191
+ * 36-character lowercase alphabet with a `run_` prefix and contain no
192
+ * separator, so joining on `:` is unambiguous.
193
+ */
194
+ function encodeCursor(key) {
195
+ return `${key[0]}:${key[1]}:${key[2]}`;
196
+ }
197
+ function decodeCursor(cursor, orderBy) {
198
+ const first = cursor.indexOf(':');
199
+ const second = cursor.indexOf(':', first + 1);
200
+ if (first < 0 || second < 0) {
201
+ throw new NamzuError({
202
+ code: 'invalid_config',
203
+ message: `listDurableRuns: "${cursor}" is not a cursor this listing issued. Pass back the \`cursor\` from the previous page rather than constructing one; its shape is not part of the contract.`,
204
+ details: { cursor, orderBy },
205
+ });
206
+ }
207
+ const rank = Number(cursor.slice(0, first));
208
+ const stamp = Number(cursor.slice(first + 1, second));
209
+ if (!Number.isFinite(rank) || !Number.isFinite(stamp)) {
210
+ throw new NamzuError({
211
+ code: 'invalid_config',
212
+ message: `listDurableRuns: cursor "${cursor}" is malformed — its position fields are not numbers. Pass back the \`cursor\` from the previous page.`,
213
+ details: { cursor, orderBy },
214
+ });
215
+ }
216
+ return [rank, stamp, cursor.slice(second + 1)];
217
+ }
218
+ /**
219
+ * Every run with durable state under a scope, refusing when the store cannot
220
+ * answer.
221
+ *
222
+ * The refusal is the point. `listDurableRuns` is optional on the contract so
223
+ * that adding it did not break every host that had already implemented the
224
+ * interface — and an optional capability reached without a check degrades
225
+ * into a wrong answer: a store that cannot list would hand an approval inbox
226
+ * an empty page, and "nothing is waiting on a human" is not what "I cannot
227
+ * tell" means. A host that gets this error knows to supply a backend that
228
+ * implements the listing; a host that got `[]` would ship an inbox that
229
+ * silently never fires.
230
+ */
231
+ export async function listDurableRuns(store, scope, options) {
232
+ if (typeof store.listDurableRuns !== 'function') {
233
+ throw new NamzuError({
234
+ code: 'capability_unavailable',
235
+ message: 'listDurableRuns: the injected checkpoint store does not implement `listDurableRuns`, so it cannot enumerate runs above a run id. Refusing rather than reporting an empty listing, which would read as "no runs are parked" when the truth is that this store cannot tell. Supply a store that implements it (the built-in disk and in-memory stores both do).',
236
+ details: { tenantId: scope.tenantId },
237
+ });
238
+ }
239
+ assertContiguousListingScope(scope, 'listDurableRuns');
240
+ return store.listDurableRuns(scope, options);
241
+ }
242
+ //# sourceMappingURL=listing.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"listing.js","sourceRoot":"","sources":["../../../src/store/run/listing.ts"],"names":[],"mappings":"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"}
@@ -217,6 +217,33 @@ export interface IterationCheckpoint {
217
217
  * @deprecated No producer. Removed in the next major.
218
218
  */
219
219
  planStatus?: PlanStatus;
220
+ /**
221
+ * When the RUN was attributed — not when this checkpoint was written.
222
+ * See {@link IterationCheckpoint.createdAt} for the latter.
223
+ *
224
+ * Denormalized onto every checkpoint of the run, identically, and that
225
+ * repetition is the whole point. A listing above the run needs a key it
226
+ * can order by, and a key a paging caller can trust is one that cannot
227
+ * MOVE. Every other time a checkpoint store can derive per run moves: the
228
+ * newest checkpoint's `createdAt` advances every time the run checkpoints
229
+ * again, and the oldest one's advances every time `prune` deletes
230
+ * oldest-first. Carried on all of them, this one survives both — pruning
231
+ * cannot reach a value every survivor also holds.
232
+ *
233
+ * `readonly`, and written exactly once per run by
234
+ * {@link import('../../runtime/query/checkpoint.js').CheckpointManager},
235
+ * which settles it on whichever comes first — adopting it from the
236
+ * checkpoint a resume restores, or minting it from the run's own start
237
+ * instant — and never reassigns after. A field that COULD be updated is
238
+ * one edit away from moving again, which would put the ordering back
239
+ * where it started.
240
+ *
241
+ * Absent on checkpoints written before this existed. That absence is
242
+ * information, not a gap: a run with no stamp on any of its checkpoints
243
+ * was attributed before the stamp existed, and therefore before every
244
+ * run that has one.
245
+ */
246
+ readonly runCreatedAt?: number;
220
247
  /**
221
248
  * Present when the run parked at this checkpoint awaiting a human.
222
249
  * See {@link PendingDecision}.
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/types/hitl/index.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,oBAAoB,EAAE,MAAM,0BAA0B,CAAA;AACpE,OAAO,KAAK,EAAE,qBAAqB,EAAE,MAAM,+BAA+B,CAAA;AAC1E,OAAO,KAAK,EAAE,QAAQ,EAAE,UAAU,EAAE,MAAM,oBAAoB,CAAA;AAC9D,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,iBAAiB,CAAA;AAClE,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,qBAAqB,CAAA;AAClD,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,kBAAkB,CAAA;AAElD,YAAY,EAAE,YAAY,EAAE,CAAA;AAE5B,MAAM,MAAM,kBAAkB,GAC3B;IAAE,MAAM,EAAE,UAAU,CAAA;CAAE,GACtB;IAAE,MAAM,EAAE,cAAc,CAAC;IAAC,QAAQ,CAAC,EAAE,MAAM,CAAA;CAAE,GAC7C;IAAE,MAAM,EAAE,aAAa,CAAC;IAAC,QAAQ,EAAE,MAAM,CAAA;CAAE,GAC3C;IACA,MAAM,EAAE,eAAe,CAAA;IACvB;;;;;;;;;;;;;;;;OAgBG;IACH,QAAQ,CAAC,EAAE,SAAS,MAAM,EAAE,CAAA;CAC3B,GACD;IAAE,MAAM,EAAE,cAAc,CAAC;IAAC,aAAa,EAAE,gBAAgB,EAAE,CAAA;CAAE,GAC7D;IAAE,MAAM,EAAE,cAAc,CAAC;IAAC,QAAQ,EAAE,MAAM,CAAA;CAAE,GAC5C;IACA,MAAM,EAAE,iBAAiB,CAAA;IACzB,iBAAiB,EAAE,MAAM,EAAE,CAAA;IAC3B,QAAQ,CAAC,EAAE,MAAM,CAAA;IACjB;;;;;;;;;OASG;IACH,UAAU,CAAC,EAAE,MAAM,CAAA;CAClB,GACD;IAAE,MAAM,EAAE,OAAO,CAAC;IAAC,MAAM,EAAE,MAAM,CAAA;CAAE,GACnC;IAAE,MAAM,EAAE,OAAO,CAAC;IAAC,MAAM,EAAE,MAAM,CAAA;CAAE,CAAA;AAEtC,MAAM,MAAM,mBAAmB,GAC5B;IAAE,IAAI,EAAE,eAAe,CAAC;IAAC,KAAK,EAAE,KAAK,CAAC;IAAC,YAAY,EAAE,YAAY,CAAC;IAAC,IAAI,EAAE,gBAAgB,CAAA;CAAE,GAC3F;IAAE,IAAI,EAAE,aAAa,CAAC;IAAC,KAAK,EAAE,KAAK,CAAC;IAAC,YAAY,EAAE,YAAY,CAAC;IAAC,SAAS,EAAE,eAAe,EAAE,CAAA;CAAE,GAC/F;IACA,IAAI,EAAE,sBAAsB,CAAA;IAC5B,KAAK,EAAE,KAAK,CAAA;IACZ,YAAY,EAAE,YAAY,CAAA;IAC1B,OAAO,EAAE,iBAAiB,CAAA;CACzB,GACD;IAAE,IAAI,EAAE,eAAe,CAAC;IAAC,KAAK,EAAE,KAAK,CAAC;IAAC,YAAY,EAAE,YAAY,CAAC;IAAC,QAAQ,EAAE,gBAAgB,CAAA;CAAE,CAAA;AAElG,MAAM,MAAM,aAAa,GAAG,CAAC,OAAO,EAAE,mBAAmB,KAAK,OAAO,CAAC,kBAAkB,CAAC,CAAA;AAEzF,MAAM,WAAW,eAAe;IAC/B,EAAE,EAAE,MAAM,CAAA;IACV,IAAI,EAAE,MAAM,CAAA;IACZ,KAAK,EAAE,OAAO,CAAA;IACd,aAAa,EAAE,OAAO,CAAA;CACtB;AAED,MAAM,WAAW,gBAAgB;IAChC,UAAU,EAAE,MAAM,CAAA;IAClB,MAAM,EAAE,SAAS,GAAG,MAAM,GAAG,QAAQ,CAAA;IACrC,aAAa,CAAC,EAAE,OAAO,CAAA;CACvB;AAED,MAAM,WAAW,kBAAkB;IAClC,EAAE,EAAE,MAAM,CAAA;IACV,KAAK,EAAE,MAAM,CAAA;IACb,WAAW,CAAC,EAAE,MAAM,CAAA;CACpB;AAED;;;;;;;GAOG;AACH,MAAM,WAAW,gBAAgB;IAChC,UAAU,EAAE,MAAM,CAAA;IAClB,QAAQ,EAAE,MAAM,CAAA;IAChB,MAAM,CAAC,EAAE,MAAM,CAAA;IACf,OAAO,EAAE,kBAAkB,EAAE,CAAA;IAC7B,WAAW,EAAE,OAAO,CAAA;IACpB,aAAa,EAAE,OAAO,CAAA;CACtB;AAED,MAAM,WAAW,gBAAgB;IAChC,MAAM,EAAE,MAAM,CAAA;IACd,KAAK,EAAE,MAAM,CAAA;IACb,KAAK,EAAE,KAAK,CAAC;QACZ,EAAE,EAAE,MAAM,CAAA;QACV,WAAW,EAAE,MAAM,CAAA;QACnB,QAAQ,CAAC,EAAE,MAAM,CAAA;QAEjB;;;;;;;;;;;;;;WAcG;QACH,OAAO,CAAC,EAAE,MAAM,CAAA;QAEhB,SAAS,EAAE,MAAM,EAAE,CAAA;QACnB,KAAK,EAAE,MAAM,CAAA;KACb,CAAC,CAAA;IACF,OAAO,CAAC,EAAE,MAAM,CAAA;CAChB;AAED,MAAM,WAAW,iBAAiB;IACjC,SAAS,EAAE,MAAM,CAAA;IACjB,YAAY,EAAE,MAAM,CAAA;IACpB,UAAU,EAAE,UAAU,CAAA;IACtB,QAAQ,EAAE,QAAQ,CAAA;IAClB,oBAAoB,CAAC,EAAE,MAAM,CAAA;CAC7B;AAED;;;;;;;;;;;;;GAaG;AACH,MAAM,WAAW,eAAe;IAC/B,yEAAyE;IACzE,QAAQ,CAAC,OAAO,EAAE,mBAAmB,CAAA;IACrC,wCAAwC;IACxC,QAAQ,CAAC,QAAQ,EAAE,MAAM,CAAA;IACzB;;;;;;;;;;;;;;;;;;;OAmBG;IACH,QAAQ,CAAC,UAAU,CAAC,EAAE,MAAM,CAAA;IAC5B;;;;OAIG;IACH,QAAQ,CAAC,UAAU,CAAC,EAAE,MAAM,CAAA;IAC5B,0EAA0E;IAC1E,QAAQ,CAAC,QAAQ,CAAC,EAAE,kBAAkB,CAAA;CACtC;AAED,MAAM,WAAW,mBAAmB;IACnC,EAAE,EAAE,YAAY,CAAA;IAChB,KAAK,EAAE,KAAK,CAAA;IACZ,SAAS,EAAE,MAAM,CAAA;IACjB,QAAQ,EAAE,OAAO,EAAE,CAAA;IACnB,UAAU,EAAE,UAAU,CAAA;IACtB,QAAQ,EAAE,QAAQ,CAAA;IAClB;;;;;;;;;OASG;IACH,UAAU,CAAC,EAAE,UAAU,CAAA;IAEvB;;;OAGG;IACH,OAAO,CAAC,EAAE,eAAe,CAAA;IACzB,UAAU,EAAE;QACX,cAAc,EAAE,MAAM,CAAA;QACtB,SAAS,EAAE,MAAM,CAAA;KACjB,CAAA;IACD,SAAS,EAAE,MAAM,CAAA;IAEjB,gBAAgB,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAA;IAEzC;;;;;;;OAOG;IACH,YAAY,CAAC,EAAE,oBAAoB,CAAA;IAEnC;;;;;;;;;;;;;OAaG;IACH,YAAY,CAAC,EAAE,qBAAqB,CAAA;CACpC;AAED,wBAAgB,kBAAkB,CAAC,OAAO,EAAE,mBAAmB,GAAG,OAAO,CAAC,kBAAkB,CAAC,CAwB5F"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/types/hitl/index.ts"],"names":[],"mappings":"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"}
@@ -1 +1 @@
1
- {"version":3,"file":"index.js","sourceRoot":"","sources":["../../../src/types/hitl/index.ts"],"names":[],"mappings":"AA4PA,MAAM,UAAU,kBAAkB,CAAC,OAA4B;IAC9D,QAAQ,OAAO,CAAC,IAAI,EAAE,CAAC;QACtB,KAAK,eAAe;YACnB,OAAO,OAAO,CAAC,OAAO,CAAC,EAAE,MAAM,EAAE,cAAc,EAAE,CAAC,CAAA;QACnD,KAAK,aAAa;YACjB,OAAO,OAAO,CAAC,OAAO,CAAC,EAAE,MAAM,EAAE,eAAe,EAAE,CAAC,CAAA;QACpD,KAAK,sBAAsB;YAC1B,OAAO,OAAO,CAAC,OAAO,CAAC,EAAE,MAAM,EAAE,UAAU,EAAE,CAAC,CAAA;QAC/C,KAAK,eAAe;YACnB,2DAA2D;YAC3D,yDAAyD;YACzD,6DAA6D;YAC7D,uCAAuC;YACvC,OAAO,OAAO,CAAC,OAAO,CAAC;gBACtB,MAAM,EAAE,iBAAiB;gBACzB,iBAAiB,EAAE,EAAE;gBACrB,QAAQ,EAAE,mEAAmE;gBAC7E,UAAU,EAAE,OAAO,CAAC,QAAQ,CAAC,UAAU;aACvC,CAAC,CAAA;QACH,OAAO,CAAC,CAAC,CAAC;YACT,MAAM,WAAW,GAAU,OAAO,CAAA;YAClC,MAAM,IAAI,KAAK,CAAC,gCAAiC,WAAmC,CAAC,IAAI,EAAE,CAAC,CAAA;QAC7F,CAAC;IACF,CAAC;AACF,CAAC"}
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../../../src/types/hitl/index.ts"],"names":[],"mappings":"AAwRA,MAAM,UAAU,kBAAkB,CAAC,OAA4B;IAC9D,QAAQ,OAAO,CAAC,IAAI,EAAE,CAAC;QACtB,KAAK,eAAe;YACnB,OAAO,OAAO,CAAC,OAAO,CAAC,EAAE,MAAM,EAAE,cAAc,EAAE,CAAC,CAAA;QACnD,KAAK,aAAa;YACjB,OAAO,OAAO,CAAC,OAAO,CAAC,EAAE,MAAM,EAAE,eAAe,EAAE,CAAC,CAAA;QACpD,KAAK,sBAAsB;YAC1B,OAAO,OAAO,CAAC,OAAO,CAAC,EAAE,MAAM,EAAE,UAAU,EAAE,CAAC,CAAA;QAC/C,KAAK,eAAe;YACnB,2DAA2D;YAC3D,yDAAyD;YACzD,6DAA6D;YAC7D,uCAAuC;YACvC,OAAO,OAAO,CAAC,OAAO,CAAC;gBACtB,MAAM,EAAE,iBAAiB;gBACzB,iBAAiB,EAAE,EAAE;gBACrB,QAAQ,EAAE,mEAAmE;gBAC7E,UAAU,EAAE,OAAO,CAAC,QAAQ,CAAC,UAAU;aACvC,CAAC,CAAA;QACH,OAAO,CAAC,CAAC,CAAC;YACT,MAAM,WAAW,GAAU,OAAO,CAAA;YAClC,MAAM,IAAI,KAAK,CAAC,gCAAiC,WAAmC,CAAC,IAAI,EAAE,CAAC,CAAA;QAC7F,CAAC;IACF,CAAC;AACF,CAAC"}
@@ -8,7 +8,7 @@
8
8
  * {@link CheckpointRunScope} so a shared backend can key rows by the full
9
9
  * five-layer attribution (Convention #17) instead of a filesystem path.
10
10
  */
11
- import type { CheckpointId, IterationCheckpoint } from '../hitl/index.js';
11
+ import type { CheckpointId, HITLDecisionRequest, IterationCheckpoint } from '../hitl/index.js';
12
12
  import type { RunId, SessionId, TenantId } from '../ids/index.js';
13
13
  import type { ProjectId } from '../session/ids.js';
14
14
  /**
@@ -36,6 +36,203 @@ export interface CheckpointRunScope {
36
36
  */
37
37
  parentRunId?: RunId;
38
38
  }
39
+ /**
40
+ * A CONTIGUOUS PREFIX of the run attribution hierarchy, addressing a SET of
41
+ * runs rather than one.
42
+ *
43
+ * A separate type from {@link CheckpointRunScope} on purpose. That type
44
+ * addresses exactly one run and four accessors depend on it doing so; making
45
+ * its one distinguishing field optional in place would turn "the scope of a
46
+ * run" into "some identifiers, maybe", and every accessor's guarantee with
47
+ * it.
48
+ *
49
+ * Three properties, each deliberate:
50
+ *
51
+ * - **`tenantId` is required.** Isolation is the one boundary that is never
52
+ * optional here. An untenanted listing is a cross-tenant read with a
53
+ * friendly name.
54
+ * - **It stops ABOVE the run.** No `runId`, no `parentRunId`. A caller
55
+ * holding a run id already has a full {@link CheckpointRunScope} and four
56
+ * accessors that take it; admitting one here would make
57
+ * `CheckpointRunScope` structurally assignable to this type and re-merge
58
+ * the two ideas the split exists to keep apart.
59
+ * - **The prefix must be contiguous.** A `sessionId` with no `projectId` is
60
+ * REFUSED, not silently widened to "that session under whichever project
61
+ * holds it". A flat backend can answer it and a hierarchical one cannot,
62
+ * so the answer would depend on the backend's storage shape — which is
63
+ * the one thing a store contract exists to hide.
64
+ */
65
+ export interface CheckpointListingScope {
66
+ /** Isolation boundary (Convention #17). Never optional. */
67
+ readonly tenantId: TenantId;
68
+ /** Narrow to one project. Absent = every project of the tenant. */
69
+ readonly projectId?: ProjectId;
70
+ /** Narrow to one session. Requires `projectId`. */
71
+ readonly sessionId?: SessionId;
72
+ }
73
+ /**
74
+ * What a run's human-in-the-loop park is doing, as far as durable state can
75
+ * tell.
76
+ *
77
+ * A closed union rather than a boolean because the two unanswered states are
78
+ * drained by DIFFERENT operators: `outstanding` is an approval inbox's queue
79
+ * and `expired` is a reclamation sweep's, and serving one to the other either
80
+ * re-presents a dead approval forever or discards a live one.
81
+ */
82
+ export type ParkState =
83
+ /** `pending` set, no `resolvedAt`, deadline not passed. A human owes an answer. */
84
+ 'outstanding'
85
+ /** `pending` set, no `resolvedAt`, deadline passed. Nobody will answer it. */
86
+ | 'expired'
87
+ /** `pending` set with `resolvedAt`. Kept as evidence of who decided what. */
88
+ | 'resolved';
89
+ /**
90
+ * **Do not widen this union to say who is working on the run.**
91
+ *
92
+ * A consumer switches over `ParkState` exhaustively, so a fourth member is a
93
+ * backward-incompatible change and a `major` — and the pull to add one is
94
+ * real, because the next capability this contract takes is a cross-process
95
+ * claim, and a queue worker draining the inbox wants to skip runs another
96
+ * worker already holds.
97
+ *
98
+ * That is a different fact about a different subject. A park is a question
99
+ * put to a HUMAN; a claim is a lease held by a PROCESS, and one run can have
100
+ * both, neither, or either. Encoding them in one union makes the pair
101
+ * unsayable and loses the state a worker needs most: parked AND unclaimed.
102
+ *
103
+ * The additive shape is a sibling optional field — `claim?: …` on
104
+ * {@link DurableRunEntry}, `claimed?: …` on {@link ListDurableRunsOptions}.
105
+ * A consumer reading rows is not broken by a new optional field, so the
106
+ * claim ships as a second `minor` on this contract rather than a second
107
+ * migration of it. This note exists because the union is the obvious place
108
+ * to reach for and the wrong one.
109
+ */
110
+ /** A run's park disposition, projected from the checkpoint that carries it. */
111
+ export interface ParkSummary {
112
+ readonly state: ParkState;
113
+ /** The parked checkpoint — address it directly with `readCheckpoint`. */
114
+ readonly checkpointId: CheckpointId;
115
+ /** What the human was asked. Enough to route an inbox without a second read. */
116
+ readonly requestType: HITLDecisionRequest['type'];
117
+ /** Epoch ms at which the run parked. */
118
+ readonly parkedAt: number;
119
+ /** Absolute expiry, when the park carries one. */
120
+ readonly deadlineAt?: number;
121
+ /** Epoch ms at which the answer arrived. Only on `resolved`. */
122
+ readonly resolvedAt?: number;
123
+ }
124
+ /**
125
+ * One run that has durable checkpoint state under the queried scope.
126
+ *
127
+ * **Extends {@link CheckpointRunScope}, and that is the load-bearing part.**
128
+ * A listing whose rows cannot be turned back into an addressable scope is a
129
+ * report, not a work queue. Because an entry IS a run scope,
130
+ * `findPendingCheckpoint(store, entry)`, `new CheckpointManager(store, entry)`
131
+ * and `resumeRun({ scope: entry, … })` all accept a row straight out of the
132
+ * listing — with no re-assembly, and so no chance of assembling it wrong.
133
+ *
134
+ * ### What an entry deliberately does NOT carry
135
+ *
136
+ * A run STATUS. A checkpoint is written mid-flight, so nothing in this store
137
+ * distinguishes a run that finished from one that died — the same fact
138
+ * {@link import('../../runtime/query/run-state.js').loadRunState} already
139
+ * states, where a rebuilt snapshot always reports `running` and the host's
140
+ * own record stays the authority. A `status` field here would answer
141
+ * "mid-flight" for every run that ever succeeded, and a sweeper built on it
142
+ * would resume finished work.
143
+ *
144
+ * A crash sweep is therefore: list every run with durable state under the
145
+ * scope, intersect with the host's own run records, resume the difference.
146
+ */
147
+ export interface DurableRunEntry extends CheckpointRunScope {
148
+ /**
149
+ * When the run was attributed. Absent when it was never recorded.
150
+ *
151
+ * The only per-run key this store holds that does not move, which is why
152
+ * it is the one an oldest-first listing can page over — see
153
+ * {@link CheckpointStore.listDurableRuns} and
154
+ * `IterationCheckpoint.runCreatedAt`.
155
+ *
156
+ * **Absent means "not recorded", and a caller should render it that way
157
+ * rather than as a date it invents.** Every run checkpointed by a build
158
+ * carrying the stamp has one; a run that has none was checkpointed
159
+ * before the stamp existed.
160
+ */
161
+ readonly runCreatedAt?: number;
162
+ /** How many checkpoints the run has right now. Pruning lowers it. */
163
+ readonly checkpointCount: number;
164
+ /** Newest checkpoint by `createdAt` — the one a resume restores by default. */
165
+ readonly latestCheckpointId: CheckpointId;
166
+ /** `createdAt` of {@link DurableRunEntry.latestCheckpointId}. */
167
+ readonly latestCheckpointAt: number;
168
+ /** Absent when the run has never parked. */
169
+ readonly park?: ParkSummary;
170
+ }
171
+ /**
172
+ * Which order a listing comes back in.
173
+ *
174
+ * Explicit rather than implied, because the two available orders answer
175
+ * different questions and neither is right for both. "Show me every run
176
+ * waiting on a human" wants stable paging; "show me the one that has been
177
+ * waiting longest" wants chronology. A listing that silently picked one
178
+ * would be the same ambiguity the scope type removed by splitting.
179
+ */
180
+ export type DurableRunOrder =
181
+ /**
182
+ * By `runId` ascending. Stable and total, and meaningless as chronology —
183
+ * run ids carry no timestamp. The default, because it is what shipped.
184
+ */
185
+ 'runId'
186
+ /**
187
+ * Oldest first, by {@link DurableRunEntry.runCreatedAt} then `runId`.
188
+ * This is the triage order: it answers which run has been waiting
189
+ * longest. Safe to page over, because the stamp is recorded once at
190
+ * attribution and never rewritten.
191
+ *
192
+ * **Runs whose creation was never recorded come FIRST**, ordered among
193
+ * themselves by `runId`. That is not a guess dressed up as a date: the
194
+ * stamp is written by the checkpoint manager, so a run lacking it on
195
+ * every checkpoint was checkpointed by a build that predates the stamp,
196
+ * and therefore predates every run that has one. Their
197
+ * `runCreatedAt` is absent on the row, so a caller can render "unknown"
198
+ * instead of a date nobody recorded.
199
+ */
200
+ | 'createdAt';
201
+ /** Filters and paging for {@link CheckpointStore.listDurableRuns}. */
202
+ export interface ListDurableRunsOptions {
203
+ /**
204
+ * Ordering, and therefore what the cursor is a position in. Defaults to
205
+ * `'runId'`. A cursor is only meaningful within one order — do not carry
206
+ * one across a change of `orderBy`.
207
+ */
208
+ readonly orderBy?: DurableRunOrder;
209
+ /**
210
+ * Keep only runs whose park is in one of these states. A run that never
211
+ * parked has no state and is excluded by ANY value here; omit the filter
212
+ * to include it.
213
+ */
214
+ readonly park?: readonly ParkState[];
215
+ /** Page size. Defaults to 100, clamped to at least 1. */
216
+ readonly limit?: number;
217
+ /** Resume token from the previous page's {@link DurableRunPage.cursor}. */
218
+ readonly cursor?: string;
219
+ /**
220
+ * Clock for expiry, so a sweep can be tested and so every entry in one
221
+ * page is judged against the same instant. Defaults to `Date.now()` — the
222
+ * same seam `findPendingCheckpoint` already takes.
223
+ */
224
+ readonly now?: number;
225
+ }
226
+ /** One page of {@link DurableRunEntry}. */
227
+ export interface DurableRunPage {
228
+ readonly entries: readonly DurableRunEntry[];
229
+ /**
230
+ * Pass to the next call. **Absent means the listing is exhausted**, so
231
+ * `while (cursor)` terminates; a store never returns a cursor it already
232
+ * knows yields nothing.
233
+ */
234
+ readonly cursor?: string;
235
+ }
39
236
  /**
40
237
  * Persistence contract consumed by
41
238
  * {@link import('../../runtime/query/checkpoint.js').CheckpointManager} and
@@ -46,6 +243,27 @@ export interface CheckpointRunScope {
46
243
  * not-found error. `deleteCheckpoint` is idempotent: deleting an absent
47
244
  * checkpoint succeeds as a no-op (mirrors the disk store's ENOENT
48
245
  * swallowing).
246
+ *
247
+ * ## Optional capabilities, and the rule that comes with them
248
+ *
249
+ * {@link CheckpointStore.listDurableRuns} is optional, following
250
+ * `SessionStore.listSessionsByProject`. A required method would break every
251
+ * host that has already implemented this interface, which is a `major` for
252
+ * what is otherwise an additive capability.
253
+ *
254
+ * The rule optionality obliges: **a caller of an optional capability REFUSES
255
+ * when it is absent; it never degrades.** An approval inbox built on a store
256
+ * that cannot list has to throw, because an empty page would say "nothing is
257
+ * waiting on a human" when the truth is "I cannot tell" — an optional
258
+ * dependency degrading a check, which this repository has been bitten by
259
+ * before. Reach the capability through
260
+ * {@link import('../../store/run/listing.js').listDurableRuns}, which
261
+ * refuses on absence rather than answering.
262
+ *
263
+ * Any capability added here later takes the same shape — optional method,
264
+ * refusing helper. A cross-process claim is the next one, and a two-worker
265
+ * deployment against a store with no lease has to fail loudly rather than
266
+ * proceed.
49
267
  */
50
268
  export interface CheckpointStore {
51
269
  /** Persist one checkpoint. Overwrites an existing checkpoint with the same id. */
@@ -60,5 +278,46 @@ export interface CheckpointStore {
60
278
  listCheckpoints(scope: CheckpointRunScope): Promise<IterationCheckpoint[]>;
61
279
  /** Delete a checkpoint by id. Absent checkpoints succeed as a no-op. */
62
280
  deleteCheckpoint(scope: CheckpointRunScope, checkpointId: CheckpointId): Promise<void>;
281
+ /**
282
+ * Every run with durable checkpoint state under a scope ABOVE the run.
283
+ * OPTIONAL — see the optional-capability rule on this interface.
284
+ *
285
+ * This is the read an approval inbox and a park sweep are built from, and
286
+ * the one thing this contract had no way to express: every other accessor
287
+ * needs a `runId`, so a host could only ask about runs it already knew
288
+ * about. `hitlParkTtlMs` documents a host sweep as the reclamation path
289
+ * for an unanswered park, and until this existed the sweep had no way to
290
+ * enumerate what to sweep.
291
+ *
292
+ * ### Ordering
293
+ *
294
+ * Two orders, named by `options.orderBy`, and the cursor is a position in
295
+ * whichever one was asked for. See {@link DurableRunOrder}.
296
+ *
297
+ * Both sort on a key that cannot MOVE, which is the property a cursor
298
+ * needs — sort on a moving key and a paging caller skips rows and repeats
299
+ * rows. That rules out every time a checkpoint store can derive on its
300
+ * own: the newest checkpoint's timestamp advances whenever the run
301
+ * checkpoints again, and the oldest one's advances whenever
302
+ * `CheckpointManager.prune` deletes oldest-first, which is what pruning
303
+ * does. It leaves `runId`, which is immutable and unique but carries no
304
+ * timestamp, and `runCreatedAt`, which is recorded once at attribution
305
+ * and denormalized onto every checkpoint so pruning cannot reach it.
306
+ *
307
+ * `'runId'` alone is already a total order. `'createdAt'` tiebreaks on
308
+ * `runId`, which is the rule `orderChildren` follows: sort on a key that
309
+ * cannot move, make the order total with an id.
310
+ *
311
+ * A run whose FIRST checkpoint is written after paging began may be
312
+ * missed by that pass, in either order — it lands wherever its key puts
313
+ * it, possibly behind the cursor. That is the right trade for a queue:
314
+ * the sweep runs again and picks it up next pass, whereas a moving sort
315
+ * key loses runs that already existed.
316
+ *
317
+ * @param scope contiguous prefix; `tenantId` required. Implementations
318
+ * reject a hole (`sessionId` with no `projectId`) rather than guessing.
319
+ * @param options filters and paging. See {@link ListDurableRunsOptions}.
320
+ */
321
+ listDurableRuns?(scope: CheckpointListingScope, options?: ListDurableRunsOptions): Promise<DurableRunPage>;
63
322
  }
64
323
  //# sourceMappingURL=checkpoint-store.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"checkpoint-store.d.ts","sourceRoot":"","sources":["../../../src/types/run/checkpoint-store.ts"],"names":[],"mappings":"AAAA;;;;;;;;;GASG;AAEH,OAAO,KAAK,EAAE,YAAY,EAAE,mBAAmB,EAAE,MAAM,kBAAkB,CAAA;AACzE,OAAO,KAAK,EAAE,KAAK,EAAE,SAAS,EAAE,QAAQ,EAAE,MAAM,iBAAiB,CAAA;AACjE,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,mBAAmB,CAAA;AAElD;;;;;;;;GAQG;AACH,MAAM,WAAW,kBAAkB;IAClC,2CAA2C;IAC3C,QAAQ,EAAE,QAAQ,CAAA;IAClB,gDAAgD;IAChD,SAAS,EAAE,SAAS,CAAA;IACpB,wCAAwC;IACxC,SAAS,EAAE,SAAS,CAAA;IACpB,2CAA2C;IAC3C,KAAK,EAAE,KAAK,CAAA;IACZ;;;;OAIG;IACH,WAAW,CAAC,EAAE,KAAK,CAAA;CACnB;AAED;;;;;;;;;;GAUG;AACH,MAAM,WAAW,eAAe;IAC/B,kFAAkF;IAClF,eAAe,CAAC,KAAK,EAAE,kBAAkB,EAAE,UAAU,EAAE,mBAAmB,GAAG,OAAO,CAAC,IAAI,CAAC,CAAA;IAE1F,6EAA6E;IAC7E,cAAc,CACb,KAAK,EAAE,kBAAkB,EACzB,YAAY,EAAE,YAAY,GACxB,OAAO,CAAC,mBAAmB,GAAG,IAAI,CAAC,CAAA;IAEtC;;;;OAIG;IACH,eAAe,CAAC,KAAK,EAAE,kBAAkB,GAAG,OAAO,CAAC,mBAAmB,EAAE,CAAC,CAAA;IAE1E,wEAAwE;IACxE,gBAAgB,CAAC,KAAK,EAAE,kBAAkB,EAAE,YAAY,EAAE,YAAY,GAAG,OAAO,CAAC,IAAI,CAAC,CAAA;CACtF"}
1
+ {"version":3,"file":"checkpoint-store.d.ts","sourceRoot":"","sources":["../../../src/types/run/checkpoint-store.ts"],"names":[],"mappings":"AAAA;;;;;;;;;GASG;AAEH,OAAO,KAAK,EAAE,YAAY,EAAE,mBAAmB,EAAE,mBAAmB,EAAE,MAAM,kBAAkB,CAAA;AAC9F,OAAO,KAAK,EAAE,KAAK,EAAE,SAAS,EAAE,QAAQ,EAAE,MAAM,iBAAiB,CAAA;AACjE,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,mBAAmB,CAAA;AAElD;;;;;;;;GAQG;AACH,MAAM,WAAW,kBAAkB;IAClC,2CAA2C;IAC3C,QAAQ,EAAE,QAAQ,CAAA;IAClB,gDAAgD;IAChD,SAAS,EAAE,SAAS,CAAA;IACpB,wCAAwC;IACxC,SAAS,EAAE,SAAS,CAAA;IACpB,2CAA2C;IAC3C,KAAK,EAAE,KAAK,CAAA;IACZ;;;;OAIG;IACH,WAAW,CAAC,EAAE,KAAK,CAAA;CACnB;AAED;;;;;;;;;;;;;;;;;;;;;;;;;GAyBG;AACH,MAAM,WAAW,sBAAsB;IACtC,2DAA2D;IAC3D,QAAQ,CAAC,QAAQ,EAAE,QAAQ,CAAA;IAC3B,mEAAmE;IACnE,QAAQ,CAAC,SAAS,CAAC,EAAE,SAAS,CAAA;IAC9B,mDAAmD;IACnD,QAAQ,CAAC,SAAS,CAAC,EAAE,SAAS,CAAA;CAC9B;AAED;;;;;;;;GAQG;AACH,MAAM,MAAM,SAAS;AACpB,mFAAmF;AACjF,aAAa;AACf,8EAA8E;GAC5E,SAAS;AACX,6EAA6E;GAC3E,UAAU,CAAA;AAEb;;;;;;;;;;;;;;;;;;;;GAoBG;AAEH,+EAA+E;AAC/E,MAAM,WAAW,WAAW;IAC3B,QAAQ,CAAC,KAAK,EAAE,SAAS,CAAA;IACzB,yEAAyE;IACzE,QAAQ,CAAC,YAAY,EAAE,YAAY,CAAA;IACnC,gFAAgF;IAChF,QAAQ,CAAC,WAAW,EAAE,mBAAmB,CAAC,MAAM,CAAC,CAAA;IACjD,wCAAwC;IACxC,QAAQ,CAAC,QAAQ,EAAE,MAAM,CAAA;IACzB,kDAAkD;IAClD,QAAQ,CAAC,UAAU,CAAC,EAAE,MAAM,CAAA;IAC5B,gEAAgE;IAChE,QAAQ,CAAC,UAAU,CAAC,EAAE,MAAM,CAAA;CAC5B;AAED;;;;;;;;;;;;;;;;;;;;;;GAsBG;AACH,MAAM,WAAW,eAAgB,SAAQ,kBAAkB;IAC1D;;;;;;;;;;;;OAYG;IACH,QAAQ,CAAC,YAAY,CAAC,EAAE,MAAM,CAAA;IAE9B,qEAAqE;IACrE,QAAQ,CAAC,eAAe,EAAE,MAAM,CAAA;IAChC,+EAA+E;IAC/E,QAAQ,CAAC,kBAAkB,EAAE,YAAY,CAAA;IACzC,iEAAiE;IACjE,QAAQ,CAAC,kBAAkB,EAAE,MAAM,CAAA;IACnC,4CAA4C;IAC5C,QAAQ,CAAC,IAAI,CAAC,EAAE,WAAW,CAAA;CAC3B;AAED;;;;;;;;GAQG;AACH,MAAM,MAAM,eAAe;AAC1B;;;GAGG;AACD,OAAO;AACT;;;;;;;;;;;;;GAaG;GACD,WAAW,CAAA;AAEd,sEAAsE;AACtE,MAAM,WAAW,sBAAsB;IACtC;;;;OAIG;IACH,QAAQ,CAAC,OAAO,CAAC,EAAE,eAAe,CAAA;IAElC;;;;OAIG;IACH,QAAQ,CAAC,IAAI,CAAC,EAAE,SAAS,SAAS,EAAE,CAAA;IACpC,yDAAyD;IACzD,QAAQ,CAAC,KAAK,CAAC,EAAE,MAAM,CAAA;IACvB,2EAA2E;IAC3E,QAAQ,CAAC,MAAM,CAAC,EAAE,MAAM,CAAA;IACxB;;;;OAIG;IACH,QAAQ,CAAC,GAAG,CAAC,EAAE,MAAM,CAAA;CACrB;AAED,2CAA2C;AAC3C,MAAM,WAAW,cAAc;IAC9B,QAAQ,CAAC,OAAO,EAAE,SAAS,eAAe,EAAE,CAAA;IAC5C;;;;OAIG;IACH,QAAQ,CAAC,MAAM,CAAC,EAAE,MAAM,CAAA;CACxB;AAED;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA+BG;AACH,MAAM,WAAW,eAAe;IAC/B,kFAAkF;IAClF,eAAe,CAAC,KAAK,EAAE,kBAAkB,EAAE,UAAU,EAAE,mBAAmB,GAAG,OAAO,CAAC,IAAI,CAAC,CAAA;IAE1F,6EAA6E;IAC7E,cAAc,CACb,KAAK,EAAE,kBAAkB,EACzB,YAAY,EAAE,YAAY,GACxB,OAAO,CAAC,mBAAmB,GAAG,IAAI,CAAC,CAAA;IAEtC;;;;OAIG;IACH,eAAe,CAAC,KAAK,EAAE,kBAAkB,GAAG,OAAO,CAAC,mBAAmB,EAAE,CAAC,CAAA;IAE1E,wEAAwE;IACxE,gBAAgB,CAAC,KAAK,EAAE,kBAAkB,EAAE,YAAY,EAAE,YAAY,GAAG,OAAO,CAAC,IAAI,CAAC,CAAA;IAEtF;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;OAuCG;IACH,eAAe,CAAC,CACf,KAAK,EAAE,sBAAsB,EAC7B,OAAO,CAAC,EAAE,sBAAsB,GAC9B,OAAO,CAAC,cAAc,CAAC,CAAA;CAC1B"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@namzu/sdk",
3
- "version": "20.0.0",
3
+ "version": "20.2.0",
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",
@@ -45,12 +45,26 @@ export class RunPersistence {
45
45
 
46
46
  // Checkpoints go through the injectable seam; the disk layout under
47
47
  // `outputDir` (same tree the runStore writes to) stays the default.
48
+ //
49
+ // The attribution is handed over because the layout does not record
50
+ // it — there is no tenant segment in the path at all — and without it
51
+ // the default store can persist checkpoints but cannot ENUMERATE
52
+ // them, which is the state the contract just stopped being in. A
53
+ // listing capability the default store declines is a capability no
54
+ // host reaches.
48
55
  this.checkpointStore =
49
56
  config.checkpointStore ??
50
- new DiskCheckpointStore({
51
- baseDir: config.outputDir,
52
- logger: config.log,
53
- })
57
+ new DiskCheckpointStore(
58
+ {
59
+ baseDir: config.outputDir,
60
+ logger: config.log,
61
+ },
62
+ {
63
+ tenantId: config.tenantId,
64
+ projectId: config.projectId,
65
+ sessionId: config.sessionId,
66
+ },
67
+ )
54
68
 
55
69
  this.run = {
56
70
  id: config.runId,