stitchkit 0.99.0 → 0.100.1

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 (147) hide show
  1. package/CHANGELOG.md +124 -1
  2. package/dist/agent-runtime/contained-darwin.d.ts +0 -17
  3. package/dist/agent-runtime/contained-darwin.d.ts.map +1 -1
  4. package/dist/agent-runtime/contained-write.d.ts.map +1 -1
  5. package/dist/agent-runtime/invocation-attempt.d.ts +28 -0
  6. package/dist/agent-runtime/invocation-attempt.d.ts.map +1 -0
  7. package/dist/agent-runtime/invocation-failure.d.ts +6 -0
  8. package/dist/agent-runtime/invocation-failure.d.ts.map +1 -0
  9. package/dist/agent-runtime/invocation-payload.d.ts +20 -0
  10. package/dist/agent-runtime/invocation-payload.d.ts.map +1 -0
  11. package/dist/agent-runtime/invocation-read.d.ts +131 -0
  12. package/dist/agent-runtime/invocation-read.d.ts.map +1 -0
  13. package/dist/agent-runtime/invocation-schema.d.ts +378 -0
  14. package/dist/agent-runtime/invocation-schema.d.ts.map +1 -0
  15. package/dist/agent-runtime/invocations.d.ts +52 -0
  16. package/dist/agent-runtime/invocations.d.ts.map +1 -0
  17. package/dist/agent-runtime/projections.d.ts.map +1 -1
  18. package/dist/agent-runtime/run-acquisition.d.ts.map +1 -1
  19. package/dist/agent-runtime/run-execution-state.d.ts +4 -2
  20. package/dist/agent-runtime/run-execution-state.d.ts.map +1 -1
  21. package/dist/agent-runtime/run-execution.d.ts.map +1 -1
  22. package/dist/agent-runtime/run-failure.d.ts.map +1 -1
  23. package/dist/agent-runtime/run-model-attempts.d.ts.map +1 -1
  24. package/dist/agent-runtime/run-operation-lifecycle.d.ts +2 -2
  25. package/dist/agent-runtime/run-operation-lifecycle.d.ts.map +1 -1
  26. package/dist/agent-runtime/run-provider-ledger.d.ts +1 -0
  27. package/dist/agent-runtime/run-provider-ledger.d.ts.map +1 -1
  28. package/dist/agent-runtime/runtime.d.ts +11 -0
  29. package/dist/agent-runtime/runtime.d.ts.map +1 -1
  30. package/dist/agent-runtime/schedule-dispatch.d.ts +9 -2
  31. package/dist/agent-runtime/schedule-dispatch.d.ts.map +1 -1
  32. package/dist/agent-runtime/schedule-records.d.ts +8 -2
  33. package/dist/agent-runtime/schedule-records.d.ts.map +1 -1
  34. package/dist/agent-runtime/schedules.d.ts +5 -0
  35. package/dist/agent-runtime/schedules.d.ts.map +1 -1
  36. package/dist/agent-runtime/sqlite-events.d.ts.map +1 -1
  37. package/dist/agent-runtime/store-create.d.ts.map +1 -1
  38. package/dist/agent-runtime/store-driver-contract.d.ts +9 -0
  39. package/dist/agent-runtime/store-driver-contract.d.ts.map +1 -1
  40. package/dist/agent-runtime/store-event-once.d.ts +37 -0
  41. package/dist/agent-runtime/store-event-once.d.ts.map +1 -0
  42. package/dist/agent-runtime/store-memory.d.ts.map +1 -1
  43. package/dist/agent-runtime/store.d.ts +11 -0
  44. package/dist/agent-runtime/store.d.ts.map +1 -1
  45. package/dist/application/change-subscription.d.ts +36 -0
  46. package/dist/application/change-subscription.d.ts.map +1 -0
  47. package/dist/application/diagnostic-journal-contract.d.ts +3 -6
  48. package/dist/application/diagnostic-journal-contract.d.ts.map +1 -1
  49. package/dist/application/notification-delivery.d.ts +55 -0
  50. package/dist/application/notification-delivery.d.ts.map +1 -0
  51. package/dist/application/notification-outbox-state.d.ts +41 -0
  52. package/dist/application/notification-outbox-state.d.ts.map +1 -0
  53. package/dist/application/notification-outbox.d.ts +7 -1
  54. package/dist/application/notification-outbox.d.ts.map +1 -1
  55. package/dist/application/watch-hub-core.d.ts +14 -84
  56. package/dist/application/watch-hub-core.d.ts.map +1 -1
  57. package/dist/application/watch-hub-source.d.ts +98 -0
  58. package/dist/application/watch-hub-source.d.ts.map +1 -0
  59. package/dist/application/watch-hub.d.ts +10 -2
  60. package/dist/application/watch-hub.d.ts.map +1 -1
  61. package/dist/browser/session-credentials.d.ts +26 -0
  62. package/dist/browser/session-credentials.d.ts.map +1 -0
  63. package/dist/browser/session.d.ts +33 -0
  64. package/dist/browser/session.d.ts.map +1 -0
  65. package/dist/durability/events.d.ts +6 -0
  66. package/dist/durability/events.d.ts.map +1 -1
  67. package/dist/entrypoints/agent-runtime/coding-tools.js +3 -2
  68. package/dist/entrypoints/agent-runtime/harness.js +5 -3
  69. package/dist/entrypoints/agent-runtime/sandbox.js +3 -2
  70. package/dist/entrypoints/agent-runtime/sqlite/bun.js +3 -3
  71. package/dist/entrypoints/agent-runtime/sqlite/node.js +3 -3
  72. package/dist/entrypoints/agent-runtime/testing.js +3 -3
  73. package/dist/entrypoints/agent-runtime.d.ts +3 -0
  74. package/dist/entrypoints/agent-runtime.d.ts.map +1 -1
  75. package/dist/entrypoints/agent-runtime.js +65 -20
  76. package/dist/entrypoints/application/diagnostic-journal.js +2 -1
  77. package/dist/entrypoints/application.d.ts +3 -1
  78. package/dist/entrypoints/application.d.ts.map +1 -1
  79. package/dist/entrypoints/application.js +820 -294
  80. package/dist/entrypoints/files.js +9 -2
  81. package/dist/entrypoints/index.d.ts +2 -0
  82. package/dist/entrypoints/index.d.ts.map +1 -1
  83. package/dist/entrypoints/index.js +199 -0
  84. package/dist/entrypoints/live.js +78 -19
  85. package/dist/entrypoints/node.js +1 -1
  86. package/dist/entrypoints/react.d.ts +1 -1
  87. package/dist/entrypoints/react.d.ts.map +1 -1
  88. package/dist/entrypoints/react.js +59 -16
  89. package/dist/entrypoints/server.js +4 -4
  90. package/dist/{index-sp1tzwnb.js → index-10x2hbx0.js} +5 -2
  91. package/dist/{index-8p52kd5p.js → index-c6bxbsnc.js} +100 -14
  92. package/dist/{index-gxrt5h6v.js → index-cyktc4bp.js} +3 -0
  93. package/dist/{index-1m2thnq0.js → index-eaysmdtq.js} +11 -2
  94. package/dist/{index-jhx828hc.js → index-f4fx2tza.js} +948 -279
  95. package/dist/{index-px2gm2jp.js → index-fhwqwxe0.js} +17 -55
  96. package/dist/{index-e4hkgm5t.js → index-gw8bmyaj.js} +4 -2
  97. package/dist/{index-p3vsv1fb.js → index-hadmp193.js} +14 -5
  98. package/dist/{index-wt743f7f.js → index-k6gpggb9.js} +2 -1
  99. package/dist/index-q3pyb9n0.js +22 -0
  100. package/dist/{index-wsm5w4ee.js → index-vqr7f7v8.js} +51 -3
  101. package/dist/index-zjjyynm3.js +42 -0
  102. package/dist/internal/coalesced-task.d.ts +17 -0
  103. package/dist/internal/coalesced-task.d.ts.map +1 -0
  104. package/dist/internal/darwin-binding.d.ts +19 -0
  105. package/dist/internal/darwin-binding.d.ts.map +1 -0
  106. package/dist/internal/exclusive-lock.d.ts +20 -7
  107. package/dist/internal/exclusive-lock.d.ts.map +1 -1
  108. package/dist/internal/mutation-queue.d.ts +4 -0
  109. package/dist/internal/mutation-queue.d.ts.map +1 -0
  110. package/dist/internal/process-identity.d.ts +1 -1
  111. package/dist/internal/process-identity.d.ts.map +1 -1
  112. package/dist/internal/process-instance.d.ts +26 -0
  113. package/dist/internal/process-instance.d.ts.map +1 -0
  114. package/dist/internal/with-exclusive-lock.d.ts.map +1 -1
  115. package/dist/live/watch-client-state.d.ts +71 -0
  116. package/dist/live/watch-client-state.d.ts.map +1 -0
  117. package/dist/live/watch-client.d.ts +5 -1
  118. package/dist/live/watch-client.d.ts.map +1 -1
  119. package/dist/live/watch-contract.d.ts +12 -0
  120. package/dist/live/watch-contract.d.ts.map +1 -1
  121. package/dist/react/cache-bridge.d.ts +10 -0
  122. package/dist/react/cache-bridge.d.ts.map +1 -1
  123. package/dist/server/realtime.d.ts.map +1 -1
  124. package/llms/agent-runtime.2.txt +102 -0
  125. package/llms/agent-runtime.3.txt +30 -1
  126. package/llms/agent-runtime.txt +8 -3
  127. package/llms/application.2.txt +84 -2
  128. package/llms/application.txt +32 -2
  129. package/llms/files.txt +1 -1
  130. package/llms/live.txt +8 -0
  131. package/llms/react.txt +8 -0
  132. package/llms/server.3.txt +57 -0
  133. package/llms/stitchkit.2.txt +41 -0
  134. package/llms/stitchkit.3.txt +26 -0
  135. package/llms/stitchkit.txt +3 -3
  136. package/llms/upgrading-0.37.0.txt +176 -0
  137. package/llms/{upgrading-0.37.0-0.58.0.txt → upgrading-0.44.0-0.60.0.txt} +229 -169
  138. package/llms/{upgrading-0.59.0-0.71.0.txt → upgrading-0.61.0-0.73.0.txt} +122 -229
  139. package/llms/{upgrading-0.72.0-0.99.0.txt → upgrading-0.74.0-0.100.0.txt} +80 -123
  140. package/llms/upgrading.txt +4 -3
  141. package/llms-full.txt +471 -11
  142. package/llms.txt +10 -9
  143. package/native/darwin-arm64.node +0 -0
  144. package/native/darwin-x64.node +0 -0
  145. package/package.json +1 -1
  146. package/dist/agent-runtime/run-mutation-queue.d.ts +0 -21
  147. package/dist/agent-runtime/run-mutation-queue.d.ts.map +0 -1
@@ -1 +1 @@
1
- {"version":3,"file":"watch-client.d.ts","sourceRoot":"","sources":["../../src/live/watch-client.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"watch-client.d.ts","sourceRoot":"","sources":["../../src/live/watch-client.ts"],"names":[],"mappings":"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"}
@@ -22,6 +22,7 @@ import { z } from 'zod';
22
22
  /** The identity of one watched read: an operation plus the arguments it was asked with. */
23
23
  export declare const WatchKeySchema: z.ZodReadonly<z.ZodObject<{
24
24
  service: z.ZodString;
25
+ instance: z.ZodOptional<z.ZodString>;
25
26
  action: z.ZodString;
26
27
  digest: z.ZodString;
27
28
  }, z.core.$strict>>;
@@ -43,6 +44,7 @@ export type WatchHave = z.infer<typeof WatchHaveSchema>;
43
44
  export declare const WatchOpenSchema: z.ZodReadonly<z.ZodObject<{
44
45
  key: z.ZodReadonly<z.ZodObject<{
45
46
  service: z.ZodString;
47
+ instance: z.ZodOptional<z.ZodString>;
46
48
  action: z.ZodString;
47
49
  digest: z.ZodString;
48
50
  }, z.core.$strict>>;
@@ -59,6 +61,7 @@ export declare const WatchAcceptedSchema: z.ZodReadonly<z.ZodObject<{
59
61
  export declare const WatchValueSchema: z.ZodDiscriminatedUnion<[z.ZodReadonly<z.ZodObject<{
60
62
  key: z.ZodReadonly<z.ZodObject<{
61
63
  service: z.ZodString;
64
+ instance: z.ZodOptional<z.ZodString>;
62
65
  action: z.ZodString;
63
66
  digest: z.ZodString;
64
67
  }, z.core.$strict>>;
@@ -69,6 +72,7 @@ export declare const WatchValueSchema: z.ZodDiscriminatedUnion<[z.ZodReadonly<z.
69
72
  }, z.core.$strip>>, z.ZodReadonly<z.ZodObject<{
70
73
  key: z.ZodReadonly<z.ZodObject<{
71
74
  service: z.ZodString;
75
+ instance: z.ZodOptional<z.ZodString>;
72
76
  action: z.ZodString;
73
77
  digest: z.ZodString;
74
78
  }, z.core.$strict>>;
@@ -80,6 +84,7 @@ export declare const WatchValueSchema: z.ZodDiscriminatedUnion<[z.ZodReadonly<z.
80
84
  }, z.core.$strip>>, z.ZodReadonly<z.ZodObject<{
81
85
  key: z.ZodReadonly<z.ZodObject<{
82
86
  service: z.ZodString;
87
+ instance: z.ZodOptional<z.ZodString>;
83
88
  action: z.ZodString;
84
89
  digest: z.ZodString;
85
90
  }, z.core.$strict>>;
@@ -90,6 +95,7 @@ export declare const WatchValueSchema: z.ZodDiscriminatedUnion<[z.ZodReadonly<z.
90
95
  export declare const WatchStateSchema: z.ZodReadonly<z.ZodObject<{
91
96
  key: z.ZodReadonly<z.ZodObject<{
92
97
  service: z.ZodString;
98
+ instance: z.ZodOptional<z.ZodString>;
93
99
  action: z.ZodString;
94
100
  digest: z.ZodString;
95
101
  }, z.core.$strict>>;
@@ -131,6 +137,7 @@ export declare const watchContract: {
131
137
  readonly args: z.ZodTuple<[z.ZodDiscriminatedUnion<[z.ZodReadonly<z.ZodObject<{
132
138
  key: z.ZodReadonly<z.ZodObject<{
133
139
  service: z.ZodString;
140
+ instance: z.ZodOptional<z.ZodString>;
134
141
  action: z.ZodString;
135
142
  digest: z.ZodString;
136
143
  }, z.core.$strict>>;
@@ -141,6 +148,7 @@ export declare const watchContract: {
141
148
  }, z.core.$strip>>, z.ZodReadonly<z.ZodObject<{
142
149
  key: z.ZodReadonly<z.ZodObject<{
143
150
  service: z.ZodString;
151
+ instance: z.ZodOptional<z.ZodString>;
144
152
  action: z.ZodString;
145
153
  digest: z.ZodString;
146
154
  }, z.core.$strict>>;
@@ -152,6 +160,7 @@ export declare const watchContract: {
152
160
  }, z.core.$strip>>, z.ZodReadonly<z.ZodObject<{
153
161
  key: z.ZodReadonly<z.ZodObject<{
154
162
  service: z.ZodString;
163
+ instance: z.ZodOptional<z.ZodString>;
155
164
  action: z.ZodString;
156
165
  digest: z.ZodString;
157
166
  }, z.core.$strict>>;
@@ -164,6 +173,7 @@ export declare const watchContract: {
164
173
  readonly args: z.ZodTuple<[z.ZodReadonly<z.ZodObject<{
165
174
  key: z.ZodReadonly<z.ZodObject<{
166
175
  service: z.ZodString;
176
+ instance: z.ZodOptional<z.ZodString>;
167
177
  action: z.ZodString;
168
178
  digest: z.ZodString;
169
179
  }, z.core.$strict>>;
@@ -193,6 +203,7 @@ export declare const watchContract: {
193
203
  readonly args: z.ZodTuple<[z.ZodReadonly<z.ZodObject<{
194
204
  key: z.ZodReadonly<z.ZodObject<{
195
205
  service: z.ZodString;
206
+ instance: z.ZodOptional<z.ZodString>;
196
207
  action: z.ZodString;
197
208
  digest: z.ZodString;
198
209
  }, z.core.$strict>>;
@@ -211,6 +222,7 @@ export declare const watchContract: {
211
222
  readonly args: z.ZodTuple<[z.ZodReadonly<z.ZodObject<{
212
223
  key: z.ZodReadonly<z.ZodObject<{
213
224
  service: z.ZodString;
225
+ instance: z.ZodOptional<z.ZodString>;
214
226
  action: z.ZodString;
215
227
  digest: z.ZodString;
216
228
  }, z.core.$strict>>;
@@ -1 +1 @@
1
- {"version":3,"file":"watch-contract.d.ts","sourceRoot":"","sources":["../../src/live/watch-contract.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;GAmBG;AACH,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AAKxB,2FAA2F;AAC3F,eAAO,MAAM,cAAc;;;;mBAkBd,CAAC;AACd,MAAM,MAAM,QAAQ,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,cAAc,CAAC,CAAC;AAEtD;;;;;;;;GAQG;AACH,eAAO,MAAM,eAAe;;;mBAGf,CAAC;AACd,MAAM,MAAM,SAAS,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,eAAe,CAAC,CAAC;AAExD,eAAO,MAAM,eAAe;;;;;;;;;;;kBAEf,CAAC;AAEd,eAAO,MAAM,mBAAmB;;;mBAOnB,CAAC;AA6Bd,eAAO,MAAM,gBAAgB;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;4BAmB3B,CAAC;AAEH,eAAO,MAAM,gBAAgB;;;;;;;;;;;;;;;;;;;;;;;;kBAShB,CAAC;AAEd,MAAM,MAAM,eAAe,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,gBAAgB,CAAC,CAAC;AAC/D,MAAM,MAAM,eAAe,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,gBAAgB,CAAC,CAAC;AAE/D,eAAO,MAAM,UAAU,yBAAyB,CAAC;AACjD,eAAO,MAAM,WAAW,0BAA0B,CAAC;AACnD,eAAO,MAAM,WAAW,0BAA0B,CAAC;AACnD,eAAO,MAAM,WAAW,0BAA0B,CAAC;AAEnD;;;;;;GAMG;AACH,eAAO,MAAM,aAAa;;;qBAEL,IAAI;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;qBACJ,IAAI;;;;;;;;;;;;;;;;;;;;;;;;;;;;;qBAGL,IAAI;;;;;;;;;;;;qBAA8B,GAAG;;;;;;qBACpC,IAAI;;;;;;;;;CAKxB,CAAC;AAEF,wEAAwE;AACxE,wBAAgB,cAAc,CAAC,GAAG,EAAE,QAAQ,GAAG,MAAM,CAEpD"}
1
+ {"version":3,"file":"watch-contract.d.ts","sourceRoot":"","sources":["../../src/live/watch-contract.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;GAmBG;AACH,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AAKxB,2FAA2F;AAC3F,eAAO,MAAM,cAAc;;;;;mBAoBd,CAAC;AACd,MAAM,MAAM,QAAQ,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,cAAc,CAAC,CAAC;AAEtD;;;;;;;;GAQG;AACH,eAAO,MAAM,eAAe;;;mBAGf,CAAC;AACd,MAAM,MAAM,SAAS,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,eAAe,CAAC,CAAC;AAExD,eAAO,MAAM,eAAe;;;;;;;;;;;;kBAEf,CAAC;AAEd,eAAO,MAAM,mBAAmB;;;mBAOnB,CAAC;AA6Bd,eAAO,MAAM,gBAAgB;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;4BAmB3B,CAAC;AAEH,eAAO,MAAM,gBAAgB;;;;;;;;;;;;;;;;;;;;;;;;;kBAShB,CAAC;AAEd,MAAM,MAAM,eAAe,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,gBAAgB,CAAC,CAAC;AAC/D,MAAM,MAAM,eAAe,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,gBAAgB,CAAC,CAAC;AAE/D,eAAO,MAAM,UAAU,yBAAyB,CAAC;AACjD,eAAO,MAAM,WAAW,0BAA0B,CAAC;AACnD,eAAO,MAAM,WAAW,0BAA0B,CAAC;AACnD,eAAO,MAAM,WAAW,0BAA0B,CAAC;AAEnD;;;;;;GAMG;AACH,eAAO,MAAM,aAAa;;;qBAEL,IAAI;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;qBACJ,IAAI;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;qBAGL,IAAI;;;;;;;;;;;;;qBAA8B,GAAG;;;;;;qBACpC,IAAI;;;;;;;;;;CAKxB,CAAC;AAEF,wEAAwE;AACxE,wBAAgB,cAAc,CAAC,GAAG,EAAE,QAAQ,GAAG,MAAM,CAEpD"}
@@ -1,3 +1,6 @@
1
+ import type { SessionOperation } from '../browser/session.js';
2
+ import type { WatchHandle } from '../live/watch-client.js';
3
+ import type { WatchStateFrame } from '../live/watch-contract.js';
1
4
  /**
2
5
  * Cache bridge — wire socket events into the TanStack Query cache.
3
6
  *
@@ -30,7 +33,14 @@ export type CacheBridgeHandler<TPayload> = (data: TPayload, ctx: CacheBridgeCont
30
33
  export type CacheBridgeHandlers<TEvents> = {
31
34
  [K in keyof TEvents & string]?: CacheBridgeHandler<EventPayload<TEvents[K]>>;
32
35
  };
36
+ export interface WatchCacheBinding {
37
+ readonly handle: WatchHandle<unknown>;
38
+ readonly queryKey: QueryKey;
39
+ readonly state?: (state: WatchStateFrame) => void;
40
+ }
33
41
  export interface CacheBridgeConfig<TEvents> {
42
+ readonly watched?: readonly WatchCacheBinding[];
43
+ readonly session?: SessionOperation<unknown>;
34
44
  socket: CacheBridgeSocket<TEvents>;
35
45
  /**
36
46
  * The TanStack Query client, or a thunk returning it. A thunk is resolved
@@ -1 +1 @@
1
- {"version":3,"file":"cache-bridge.d.ts","sourceRoot":"","sources":["../../src/react/cache-bridge.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;GAaG;AAEH,OAAO,KAAK,EAAE,WAAW,EAAE,QAAQ,EAAE,MAAM,uBAAuB,CAAC;AAEnE,wEAAwE;AACxE,OAAO,KAAK,EAAE,qBAAqB,EAAE,qBAAqB,EAAE,MAAM,sBAAsB,CAAC;AACzF,OAAO,KAAK,EAAE,uBAAuB,EAAE,MAAM,oBAAoB,CAAC;AAElE,MAAM,WAAW,iBAAiB,CAAC,OAAO;IACxC,EAAE,CAAC,CAAC,SAAS,MAAM,OAAO,GAAG,MAAM,EAAE,KAAK,EAAE,CAAC,EAAE,OAAO,EAAE,OAAO,CAAC,CAAC,CAAC,GAAG,MAAM,IAAI,CAAC;CACjF;AAED,MAAM,WAAW,kBAAkB;IACjC,WAAW,EAAE,WAAW,CAAC;IACzB,gFAAgF;IAChF,OAAO,CAAC,GAAG,EAAE,QAAQ,GAAG,OAAO,CAAC;CACjC;AAED,oEAAoE;AACpE,KAAK,YAAY,CAAC,CAAC,IAAI,CAAC,SAAS,CAAC,OAAO,EAAE,MAAM,CAAC,KAAK,OAAO,GAAG,CAAC,GAAG,KAAK,CAAC;AAE3E,MAAM,MAAM,kBAAkB,CAAC,QAAQ,IAAI,CAAC,IAAI,EAAE,QAAQ,EAAE,GAAG,EAAE,kBAAkB,KAAK,IAAI,CAAC;AAE7F,MAAM,MAAM,mBAAmB,CAAC,OAAO,IAAI;KACxC,CAAC,IAAI,MAAM,OAAO,GAAG,MAAM,CAAC,CAAC,EAAE,kBAAkB,CAAC,YAAY,CAAC,OAAO,CAAC,CAAC,CAAC,CAAC,CAAC;CAC7E,CAAC;AAEF,MAAM,WAAW,iBAAiB,CAAC,OAAO;IACxC,MAAM,EAAE,iBAAiB,CAAC,OAAO,CAAC,CAAC;IACnC;;;;;OAKG;IACH,WAAW,EAAE,WAAW,GAAG,CAAC,MAAM,WAAW,CAAC,CAAC;IAC/C,QAAQ,EAAE,mBAAmB,CAAC,OAAO,CAAC,CAAC;IACvC,0FAA0F;IAC1F,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,0FAA0F;IAC1F,YAAY,CAAC,EAAE,MAAM,CAAC;CACvB;AAED,MAAM,WAAW,WAAW;IAC1B,OAAO,IAAI,IAAI,CAAC;IAChB,UAAU,IAAI,IAAI,CAAC;IACnB;qEACiE;IACjE,SAAS,CAAC,GAAG,EAAE,QAAQ,GAAG,IAAI,CAAC;IAC/B,2EAA2E;IAC3E,UAAU,IAAI,IAAI,CAAC;CACpB;AAED;;;;;;;;GAQG;AACH,MAAM,WAAW,yBAAyB,CAAC,QAAQ,SAAS,qBAAqB,CAC/E,SAAQ,IAAI,CAAC,iBAAiB,CAAC,qBAAqB,CAAC,QAAQ,CAAC,CAAC,EAAE,QAAQ,CAAC;IAC1E,MAAM,EAAE,uBAAuB,CAAC,QAAQ,EAAE,qBAAqB,CAAC,CAAC;CAClE;AAED,wBAAgB,iBAAiB,CAAC,OAAO,EAAE,MAAM,EAAE,iBAAiB,CAAC,OAAO,CAAC,GAAG,WAAW,CAsF1F;AAED;;;;;;;;GAQG;AACH,wBAAgB,yBAAyB,CAAC,QAAQ,SAAS,qBAAqB,EAC9E,MAAM,EAAE,yBAAyB,CAAC,QAAQ,CAAC,GAC1C,WAAW,CAKb"}
1
+ {"version":3,"file":"cache-bridge.d.ts","sourceRoot":"","sources":["../../src/react/cache-bridge.ts"],"names":[],"mappings":"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"}
@@ -1 +1 @@
1
- {"version":3,"file":"realtime.d.ts","sourceRoot":"","sources":["../../src/server/realtime.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,EAAE,MAAM,IAAI,cAAc,EAAE,MAAM,WAAW,CAAC;AACpF,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,sBAAsB,CAAC;AAC3D,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,oBAAoB,CAAC;AACvD,OAAO,KAAK,EACV,gBAAgB,EAChB,qBAAqB,EACrB,yBAAyB,EAC1B,MAAM,sBAAsB,CAAC;AAC9B,OAAO,EAEL,KAAK,uBAAuB,EAC7B,MAAM,oBAAoB,CAAC;AAE5B,MAAM,WAAW,wBAAwB,CACvC,eAAe,SAAS,qBAAqB,EAC7C,eAAe,SAAS,qBAAqB,EAC7C,KAAK,GAAG,GAAG;IAEX;;;;OAIG;IACH,GAAG,EAAE,MAAM,CAAC,cAAc,EAAE,cAAc,EAAE,gBAAgB,EAAE,KAAK,CAAC,CAAC;IACrE,MAAM,EAAE,uBAAuB,CAAC,eAAe,EAAE,eAAe,CAAC,CAAC;IAClE,EAAE,CACA,IAAI,EAAE,MAAM,GACX,IAAI,CAAC,uBAAuB,CAAC,qBAAqB,EAAE,eAAe,CAAC,EAAE,MAAM,CAAC,CAAC;CAClF;AAED,MAAM,WAAW,cAAc,CAC7B,eAAe,SAAS,qBAAqB,EAC7C,eAAe,SAAS,qBAAqB,EAC7C,KAAK,GAAG,GAAG;IAEX,YAAY,CACV,OAAO,EAAE,CACP,UAAU,EAAE,wBAAwB,CAAC,eAAe,EAAE,eAAe,EAAE,KAAK,CAAC,KAC1E,IAAI,GAAG,OAAO,CAAC,IAAI,CAAC,GACxB,MAAM,IAAI,CAAC;IACd,IAAI,EAAE,uBAAuB,CAAC,qBAAqB,EAAE,eAAe,CAAC,CAAC,MAAM,CAAC,CAAC;IAC9E,EAAE,CACA,IAAI,EAAE,MAAM,GACX,IAAI,CAAC,uBAAuB,CAAC,qBAAqB,EAAE,eAAe,CAAC,EAAE,MAAM,CAAC,CAAC;CAClF;AAED,MAAM,WAAW,oBAAoB,CAAC,KAAK,GAAG,GAAG;IAC/C,EAAE,EAAE,cAAc,CAAC,cAAc,EAAE,cAAc,EAAE,gBAAgB,EAAE,KAAK,CAAC,CAAC;CAC7E;AAED,wBAAgB,kBAAkB,CAChC,KAAK,CAAC,eAAe,SAAS,qBAAqB,EACnD,KAAK,CAAC,eAAe,SAAS,qBAAqB,EACnD,KAAK,GAAG,GAAG,EAEX,QAAQ,EAAE,gBAAgB,CAAC,eAAe,EAAE,eAAe,CAAC,EAC5D,MAAM,EAAE,oBAAoB,CAAC,KAAK,CAAC,EACnC,OAAO,GAAE;IAAE,UAAU,CAAC,EAAE,yBAAyB,CAAC;IAAC,MAAM,CAAC,EAAE,YAAY,CAAA;CAAO,GAC9E,cAAc,CAAC,eAAe,EAAE,eAAe,EAAE,KAAK,CAAC,CAwCzD"}
1
+ {"version":3,"file":"realtime.d.ts","sourceRoot":"","sources":["../../src/server/realtime.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,EAAE,MAAM,IAAI,cAAc,EAAE,MAAM,WAAW,CAAC;AACpF,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,sBAAsB,CAAC;AAC3D,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,oBAAoB,CAAC;AACvD,OAAO,KAAK,EACV,gBAAgB,EAChB,qBAAqB,EACrB,yBAAyB,EAC1B,MAAM,sBAAsB,CAAC;AAC9B,OAAO,EAEL,KAAK,uBAAuB,EAC7B,MAAM,oBAAoB,CAAC;AAE5B,MAAM,WAAW,wBAAwB,CACvC,eAAe,SAAS,qBAAqB,EAC7C,eAAe,SAAS,qBAAqB,EAC7C,KAAK,GAAG,GAAG;IAEX;;;;OAIG;IACH,GAAG,EAAE,MAAM,CAAC,cAAc,EAAE,cAAc,EAAE,gBAAgB,EAAE,KAAK,CAAC,CAAC;IACrE,MAAM,EAAE,uBAAuB,CAAC,eAAe,EAAE,eAAe,CAAC,CAAC;IAClE,EAAE,CACA,IAAI,EAAE,MAAM,GACX,IAAI,CAAC,uBAAuB,CAAC,qBAAqB,EAAE,eAAe,CAAC,EAAE,MAAM,CAAC,CAAC;CAClF;AAED,MAAM,WAAW,cAAc,CAC7B,eAAe,SAAS,qBAAqB,EAC7C,eAAe,SAAS,qBAAqB,EAC7C,KAAK,GAAG,GAAG;IAEX,YAAY,CACV,OAAO,EAAE,CACP,UAAU,EAAE,wBAAwB,CAAC,eAAe,EAAE,eAAe,EAAE,KAAK,CAAC,KAC1E,IAAI,GAAG,OAAO,CAAC,IAAI,CAAC,GACxB,MAAM,IAAI,CAAC;IACd,IAAI,EAAE,uBAAuB,CAAC,qBAAqB,EAAE,eAAe,CAAC,CAAC,MAAM,CAAC,CAAC;IAC9E,EAAE,CACA,IAAI,EAAE,MAAM,GACX,IAAI,CAAC,uBAAuB,CAAC,qBAAqB,EAAE,eAAe,CAAC,EAAE,MAAM,CAAC,CAAC;CAClF;AAED,MAAM,WAAW,oBAAoB,CAAC,KAAK,GAAG,GAAG;IAC/C,EAAE,EAAE,cAAc,CAAC,cAAc,EAAE,cAAc,EAAE,gBAAgB,EAAE,KAAK,CAAC,CAAC;CAC7E;AAED,wBAAgB,kBAAkB,CAChC,KAAK,CAAC,eAAe,SAAS,qBAAqB,EACnD,KAAK,CAAC,eAAe,SAAS,qBAAqB,EACnD,KAAK,GAAG,GAAG,EAEX,QAAQ,EAAE,gBAAgB,CAAC,eAAe,EAAE,eAAe,CAAC,EAC5D,MAAM,EAAE,oBAAoB,CAAC,KAAK,CAAC,EACnC,OAAO,GAAE;IAAE,UAAU,CAAC,EAAE,yBAAyB,CAAC;IAAC,MAAM,CAAC,EAAE,YAAY,CAAA;CAAO,GAC9E,cAAc,CAAC,eAAe,EAAE,eAAe,EAAE,KAAK,CAAC,CAyDzD"}
@@ -772,3 +772,105 @@ first mutation**, so an adapter whose runtime rows reference an application-owne
772
772
  can provision those parents; the optional `cleanup(context)` removes them again, and runs once
773
773
  whether the scenario passed or failed. A factory that owns no fixture state ignores the argument and
774
774
  keeps working unchanged.
775
+
776
+ ## Plain completions and shared invocation receipts
777
+
778
+ Use `createModelInvocationLedger` from `stitchkit/agent-runtime` when a direct text
779
+ completion and an agent must share causal provider evidence. It uses the existing
780
+ runtime store, not a second database. The completion path sends exactly one user
781
+ prompt, no framework instructions and no tools. It never starts an agent loop.
782
+
783
+ ```ts
784
+ import { createModelInvocationLedger } from 'stitchkit/agent-runtime';
785
+
786
+ const invocations = createModelInvocationLedger({
787
+ store, // the same AgentRuntimeStore object passed to createAgentRuntime
788
+ models, // an existing defineModelRegistry result
789
+ payloadKey, // 32 bytes from the host's secret store; retain separately from archives
790
+ authorize: async ({ context, conversationId, action, trace }) => {
791
+ const session = await authenticate(context);
792
+ await authorizeConversation(session, conversationId, action, trace);
793
+ return { subject: session.subject }; // verified identity, never a body field
794
+ },
795
+ });
796
+
797
+ const completion = await invocations.complete({
798
+ conversationId: 'evaluation-42',
799
+ idempotencyKey: 'summary-case-3',
800
+ trace: {
801
+ operationId: 'summary-42', purpose: 'summarize', project: 'example',
802
+ parent: { traceId: 'trace-42' }, experiment: 'evaluation', case: 'case-3',
803
+ },
804
+ prompt: 'Summarize these supplied facts.',
805
+ models: ['primary', 'fallback'], // registry keys; repeat a key for an explicit retry
806
+ settings: { maxOutputTokens: 500 },
807
+ timeoutMs: 30_000,
808
+ }, authenticatedContext);
809
+
810
+ // Add to the existing createAgentRuntime configuration:
811
+ const receiptConfig = {
812
+ ledger: invocations,
813
+ trace: ({ run }) => ({
814
+ operationId: run.id, purpose: 'assistant-turn', project: 'example',
815
+ }),
816
+ };
817
+ // createAgentRuntime({ ...existingConfig, invocations: receiptConfig });
818
+
819
+ const page = await invocations.read({
820
+ conversationId: 'evaluation-42', limit: 100,
821
+ }, authenticatedContext);
822
+ // Continue with fromSeq: page.nextSeq while it is defined.
823
+ ```
824
+
825
+ `complete` returns `invocationId`, `outcome` and, on success, `text`. `duplicate`
826
+ returns the existing ID without provider execution or replaying plaintext. Changed
827
+ input, trace or caller under the same key is a conflict. Model attempts are explicit
828
+ and bounded to eight; SDK retries are disabled. Only provider failures trigger the
829
+ next attempt. Abort, audit refusal and configuration errors do not. An admitted call
830
+ whose process died stays claimed: inspect the receipt before choosing a new key.
831
+
832
+ The agent retains its existing prompt, tools and loop. Both modes produce
833
+ `invocation/started`, `provider/request`, `provider/response` and
834
+ `invocation/finished` records through `read`. Each attempt has its own ID; response
835
+ usage is counted once and keeps `unavailable` distinct from measured zero. Requested
836
+ registry selection, sent adapter identity and effective provider identity are
837
+ separate. Effective identity is null when not reported. A gateway's hidden retries
838
+ are not visible as additional attempts.
839
+
840
+ `currentModelInvocationAttempt()` returns the causal context inside a provider's
841
+ `fetch` callback or streamed read. Use it to join a host transport audit to
842
+ `operationId`, `invocationId`, `attemptId`, optional `runId` and `step`.
843
+ `onAttempt` is an awaited admission hook; a rejected hook prevents the provider call.
844
+ SDK payload hashes are not represented as hashes of HTTP wire bytes.
845
+
846
+ Prompts and output are AES-256-GCM payload artifacts. `read` returns references and
847
+ hashes; `readPayload({ conversationId, artifactId }, context)` separately authorizes
848
+ `read-payload` and checks authentication tags and hashes. `payloadKey` must be 32
849
+ bytes and is copied at construction. Keep it outside the event store/backups; retain
850
+ the appropriate key when restoring an archive. `maxPayloadBytes` defaults to 4 MiB
851
+ (range 1 KiB–64 MiB). Streaming output evidence keeps parts up to half of it; past
852
+ that the evidence carries `truncated: { parts, sha256 }` over the whole stream, and
853
+ the answer itself is never cut. A receipt that cannot be written never changes an
854
+ outcome: `complete()` returns it with `receiptError` beside it, and a succeeded
855
+ answer keeps its `text`. Request headers
856
+ are excluded. Protect existing agent history independently: enabling receipts does
857
+ not encrypt its ordinary conversation records.
858
+
859
+ The built-in memory and SQLite stores implement `appendEventOnce`. Custom stores
860
+ must implement its once-only check and append atomically, returning the original
861
+ event on a duplicate key scoped by conversation and kind. A factory without this
862
+ capability refuses receipt setup. The driver-backed implementation finds the keyed
863
+ event by its identity through the driver's optional `events.find` — one index probe
864
+ in SQLite — so admission costs the same on a long conversation as on a new one; a
865
+ custom driver without `find` falls back to paging the log in one transaction.
866
+ `store.findEventOnce({ conversationId, kind, key })` reads the same event back.
867
+ Invocation payload artifacts are keyed by their artifact id the same way.
868
+
869
+ ### Migration from direct SDK completions
870
+
871
+ **Who must act:** applications opting into shared completion/agent receipts.
872
+ Replace the direct `generateText` call with `invocations.complete`, configure host
873
+ authorization and a retained payload key, and pass the same ledger in the agent's
874
+ `invocations` option. Use the returned invocation ID and the paginated `read` method
875
+ for receipt queries; do not import runtime internals. Available since 0.100.0;
876
+ existing runtime configurations need no migration.
@@ -111,7 +111,7 @@ Server-only optional application runtime. See the
111
111
  | `AgentSandboxProcess` / `AgentSandboxOutputStream` | _types_ | structural child/output interface for optional lifecycle-owned `AgentProcessSandbox.spawn`, without Node ambient type dependencies |
112
112
  | `AgentEventSearchResultSchema` / `AgentEventSearchResult` / `createSqliteAgentEventSearch` / `createAgentEventSearchTools` | schema / _type_ / functions | authorized FTS5 search with exact event addresses and `session_*` tools |
113
113
  | `createSqliteAgentSpillStore` | function | durable content-address-checked artifact storage, bounded read/search, retention facts and archive participation |
114
- | `AgentScheduleSchema` / `AgentSchedule` / `AgentScheduleService` / `AgentScheduleDeliveryOutcomeSchema` / `AgentScheduleDeliveryOutcome` / `createAgentScheduleService` / `createAgentScheduleTools` | schemas / _types_ / functions | durable `at`/`after`/timezone-explicit `every`, indexed retry eligibility, typed retry/terminal failure, bounded dispatch and fenced stable occurrence identity (ADR 0202) |
114
+ | `AgentScheduleSchema` / `AgentSchedule` / `AgentScheduleService` / `AgentScheduleDeliveryOutcomeSchema` / `AgentScheduleDeliveryOutcome` / `createAgentScheduleService` / `createAgentScheduleTools` | schemas / _types_ / functions | durable `at`/`after`/timezone-explicit `every`, indexed retry eligibility, typed retry/terminal failure (any other returned value delivers), `maxAttempts` (default 1000) per occurrence — a one-off ends `failed`, a recurring schedule skips to its next slot — bounded dispatch and fenced stable occurrence identity (ADR 0202) |
115
115
  | `AgentChildBudgetSchema` / `AgentChildBudget` / `AgentChildStateSchema` / `AgentChildState` / `AgentChildRecordSchema` / `AgentChildRecord` | schema / _type_ | durable child graph, bounded seed and measured budget state |
116
116
  | `AgentChildBlockingKindSchema` / `AgentChildBlockingKind` / `AgentChildBlockingSourceSchema` / `AgentChildBlockingSource` / `AgentChildBlockingEventSchema` / `AgentChildBlockingEvent` / `AgentChildBlockingDecision` | schemas / _types_ | parent-owned request identities; responses discriminate approval decisions from JSON input values |
117
117
  | `AgentChildHandle` / `AgentChildManager` / `SqliteAgentChildManagerConfig` / `createSqliteAgentChildManager` / `createAgentChildTools` / `agentChildBudgetStopPolicy` | _type_ / functions | host execution port, child lifecycle, cascade (given to `createAgentRuntime` as `children`), messaging, Agent tools, and the child runtime's own budget stop policy — `recordStepUsage` at every step boundary, `policy_stop` as `child-budget` when spent |
@@ -266,6 +266,35 @@ Managed effects and operator telemetry additionally export `AgentToolFenceConfig
266
266
  may accompany checkpoint/terminal writes and tool context; internal causes are redacted unless an
267
267
  operator-only observability sink explicitly opts in.
268
268
 
269
+ ### Completion and agent invocation receipts
270
+
271
+ `createModelInvocationLedger` constructs a `ModelInvocationLedger` from
272
+ `ModelInvocationConfig`: the existing store and model registry, a 32-byte payload
273
+ key, required host authorization, optional bounded payload size and `onAttempt`.
274
+ `complete(input, context, signal?)` executes only the supplied prompt, with no tools
275
+ or framework instructions; repeated keys return the existing invocation ID. It
276
+ resolves `{ invocationId, outcome, text?, receiptError? }`: `receiptError` says a
277
+ receipt could not be written and never changes `outcome` or drops `text`.
278
+ `read(input, context)` returns a bounded event page shared by agent and completion;
279
+ `readPayload(input, context)` requires a separate authorization action to decrypt
280
+ one protected artifact. See the [guide and migration example](../guide/agent-runtime.md#plain-completions-and-shared-invocation-receipts).
281
+
282
+ | Export | Kind | Purpose |
283
+ | --- | --- | --- |
284
+ | `CompletionInvocationInputSchema` / `CompletionInvocationInput` | schema/type | strict prompt, model-attempt list, deadline, idempotency key and trace input |
285
+ | `ModelInvocationTraceSchema` / `ModelInvocationTrace` | schema/type | operation, purpose, project, parent trace and optional experiment/case/profile |
286
+ | `ModelInvocationRecordSchema` / `ModelInvocationRecord` | schema/type | discriminated invocation start/finish and per-attempt requested/sent/effective evidence |
287
+ | `ModelInvocationAttemptContext` | type | conversation, operation, invocation, attempt, step and optional agent run identity |
288
+ | `currentModelInvocationAttempt` | function | returns causal IDs inside the provider transport; undefined outside an invocation |
289
+
290
+ The runtime `invocations` option takes this ledger and a trace callback; it requires
291
+ the same store and preserves the existing tool loop. `AgentRuntimeStore.appendEventOnce`
292
+ is an optional atomic capability required by receipt admission, and
293
+ `AgentRuntimeStore.findEventOnce` reads the event it wrote by kind and key. Built-in
294
+ stores supply both; custom adapters must honor the once-only transaction contract.
295
+ A driver's optional `events.find(transaction, { conversationId, eventId })` makes
296
+ both one lookup instead of a scan of the conversation log.
297
+
269
298
  ==============================================================================
270
299
  # API reference: `stitchkit-tui` (docs/api/reference.md)
271
300
  ==============================================================================
@@ -19,7 +19,7 @@ description: Configure Stitchkit's optional durable history, stream loop, run co
19
19
  type: architecture
20
20
  status: active
21
21
  created: 2026-08-22
22
- updated: 2026-09-26 16:00 +07:00
22
+ updated: 2026-09-28 18:39 +07:00
23
23
  ---
24
24
 
25
25
  # Agent application runtime
@@ -636,9 +636,14 @@ has invoked a tool is never automatically replayed.
636
636
  `createAgentScheduleService` persists `at`, `after` and `every` input. Repeating
637
637
  schedules require an explicit IANA time zone. Dispatch uses a stable
638
638
  `schedule:<id>:<occurrence>` idempotency key, and restart lateness is recorded.
639
- Resolve `void` after durable admission; return `{ status: 'retry', reason }` for a
639
+ Resolve after durable admission; return `{ status: 'retry', reason }` for a
640
640
  transient refusal or `{ status: 'terminal', reason }` to stop the entire schedule in
641
- `failed` state. Throws retry too. Backoff is 1, 2, 4, 8, 16, 32, then 60 seconds,
641
+ `failed` state. Only those two shapes are failures: any other returned value — a
642
+ queue length, a receipt — means the callback returned, so it delivered. Throws retry
643
+ too. `maxAttempts` (default 1000, about sixteen hours at the retry ceiling) bounds
644
+ one occurrence: a one-off schedule then becomes `failed`, a recurring one gives up
645
+ that occurrence (`schedule/failed` with `skipped: true` and the `nextAt` it moves
646
+ to) and keeps its cadence. A failure reason is kept to 1000 characters. Backoff is 1, 2, 4, 8, 16, 32, then 60 seconds,
642
647
  capped at 60 seconds and persisted across restart. `retryAt`, `attempts` and `lastError`
643
648
  show retry diagnostics; success resets them. `nextAt` and `lateByMs` retain the original
644
649
  occurrence time. Recurring schedules fire once after an idle stretch and advance to the
@@ -5,7 +5,42 @@
5
5
 
6
6
  Parts of this slice:
7
7
  - `llms/application.txt`: Guide: Managed application kernel (docs/guide/application-kernel.md)
8
- - `llms/application.2.txt`: Guide: Application migration recipes (docs/guide/application-migration-recipes.md) · API reference: `stitchkit/application` (docs/api/reference.md)
8
+ - `llms/application.2.txt`: Guide: Managed application kernel (docs/guide/application-kernel.md) · Guide: Application migration recipes (docs/guide/application-migration-recipes.md) · API reference: `stitchkit/application` (docs/api/reference.md)
9
+
10
+ ==============================================================================
11
+ # Guide: Managed application kernel (docs/guide/application-kernel.md) (continued)
12
+ ==============================================================================
13
+
14
+ ## Multi-action notification delivery
15
+
16
+ Opt into `delivery: { version, actions, project }` on `createNotificationOutbox`.
17
+ The pure `actions(payload)` selector runs at enqueue; the versioned plan remains
18
+ fixed throughout retry. Each `send` receives its action and a stable idempotency
19
+ key; return a small JSON receipt such as a remote message or uploaded object ID.
20
+ An action that returned is confirmed and is never sent again: a result that is not
21
+ JSON, or does not fit the state's byte budget, is kept as `receipt: null` with
22
+ `unrecorded: 'not-json' | 'too-large'` and reported to `onError`.
23
+ `project(notification, receipts)` applies all confirmed results locally and must
24
+ be idempotent. Checkpoints and the final projection timestamp live in the existing
25
+ atomic StateStore; completed receipts retain them within retention/byte limits.
26
+
27
+ This supports, for example, text plus attachment delivery with a local timeline
28
+ projection, or upload plus publication with a local asset index. These are protocol
29
+ examples, not claims of deployed consumer adoption. A failure in projection does
30
+ not repeat confirmed sends. A crash after remote success but before receipt commit
31
+ is ambiguous: the provider must deduplicate the action key or reconcile its result.
32
+ A projection can also repeat if its completion checkpoint is lost.
33
+
34
+ A plan keeps its actions from enqueue, so an older version needs only its
35
+ projection to finish: a new executor lists it in `retiredVersions: { v1: project }`
36
+ until the queue has drained. A plan version the executor does not know is reported
37
+ to `onError` as `NotificationPlanVersionError` and waits — at least a poll interval,
38
+ spending no attempt, without `classify` — for a process that knows it: the other
39
+ side of a rolling deploy, the version a rollback returns to, or this one once it
40
+ lists the version. Whole-state file and memory stores
41
+ remain supported. Atomic enqueue with an unrelated business transaction is not
42
+ provided by this contract; retain the application's transactional adapter when that
43
+ boundary is required. Send and projection callbacks own their external deadlines.
9
44
 
10
45
  ==============================================================================
11
46
  # Guide: Application migration recipes (docs/guide/application-migration-recipes.md)
@@ -386,7 +421,7 @@ cutovers are covered by the executable
386
421
  | `DiagnosticJournalConfig` / `DiagnosticJournal` | _type_ | owner schema/path/limits/failure observer and the synchronous `submit`, bounded-wait `flush`/`close`, status handle |
387
422
  | `DiagnosticJournalLimitsSchema` / `DiagnosticJournalLimits` | schema / _type_ | positive event, pending-item, pending-byte, file-byte and retained-file limits |
388
423
  | `DiagnosticJournalLockPolicySchema` / `DiagnosticJournalLockPolicy` | schema / _type_ | `refuse` (default) or `reclaim-stale`, which reclaims only a lock whose recorded owner is provably gone |
389
- | `readDiagnosticJournalLockDiagnosis` / `DiagnosticJournalLockDiagnosis` | function / _type_ | why a `reclaim-stale` acquisition refused — owner alive, another machine, or a lock this host cannot attribute — read off the thrown `EEXIST` |
424
+ | `readDiagnosticJournalLockDiagnosis` / `DiagnosticJournalLockDiagnosis` | function / _type_ | why a `reclaim-stale` acquisition refused — attribution, PID liveness and optional process `identity` evidence (`matched`, `different-boot`, `reused-pid`, `pid-gone`, `legacy`, `unavailable`) — read off the thrown `EEXIST` |
390
425
  | `DiagnosticJournalSubmitResultSchema` / `DiagnosticJournalSubmitResult` | schema / _type_ | accepted epoch/sequence or explicit invalid, oversized, capacity, closed or failed refusal |
391
426
  | `DiagnosticJournalStatusSchema` / `DiagnosticJournalStatus` | schema / _type_ | state, limits, exact admission/write/failure counters, pending ownership, rotations, partial tails and last safe sequences |
392
427
  | `DiagnosticJournalFrameSchema` / `DiagnosticJournalFrame` | schema / _type_ | version-1 JSONL frame carrying process epoch, contiguous accepted sequence and schema-validated JSON event |
@@ -488,3 +523,50 @@ vocabulary with an event topic declared `mode: 'decision'`.
488
523
 
489
524
  → [ADR 0152](../decisions/0152-a-keyspace-is-memory-that-nothing-reaches-before-it-is-durable.md),
490
525
  [ADR 0153](../decisions/0153-a-watched-read-is-one-read-per-question.md).
526
+
527
+ ### Managed change subscriptions and scoped watches
528
+
529
+ `changeSubscriptionResource` (`stitchkit/application`) accepts
530
+ `ChangeSubscriptionConfig`: `id`, unique `keys` (1–128, at most 256 characters each),
531
+ `connect(signal)`, `reconcile(key, context)`, required `reconcileIntervalMs` (10 ms–1 h),
532
+ optional `timeoutMs` (30000; 1 ms–1 h), `backoff`, and `onError`.
533
+ `ChangeConnection` supplies `subscribe({ signal, hint, disconnected })`, which completes subscription
534
+ before the first read; `close()` releases it. `ChangeReconciliation` exposes `signal`
535
+ and a synchronous `commit(callback)` guard against late publication. Drivers must
536
+ honor cancellation. Uncooperative work retains its slot until settled instead of
537
+ allowing overlapping connections/reads. Errors reach `onError`; no raw payload or
538
+ connection string is logged by this resource. Recovery runs after reconnect and
539
+ periodically even when no notification arrives.
540
+
541
+ `WatchHubConfig` adds `maxSources` (1024), `maxSubscribers` (1024), and optional
542
+ `reconcileIntervalMs` (10 ms–1 h). `hub.attach(subscriber, scope?)` accepts a
543
+ `WatchAdmissionScope` containing a **server-verified** `key` (1–512 characters) and
544
+ revocation `signal`. The key separates sharing and is the optional third argument
545
+ of `read(operation, args, scope)`; a key's `instance` routes frames and never
546
+ separates sources. Attached over `maxSubscribers`, a subscriber gets a watcher whose
547
+ `open` refuses with `Watch subscriber capacity exceeded`; `attach` does not throw
548
+ for capacity. It must represent account, session and permissions;
549
+ never trust a client-supplied owner ID as that scope.
550
+
551
+
552
+
553
+ ### Notification action and projection receipts
554
+
555
+ `NotificationOutboxConfig.delivery` accepts `NotificationDeliveryConfig`:
556
+ immutable executor `version`, pure `actions(payload)` plan selector (1–128 unique
557
+ names, each at most 128 characters), and idempotent `project(notification, receipts)`.
558
+ `send` receives optional `action` and stable `idempotencyKey`, and returns a JSON
559
+ remote receipt (void becomes null). A result that is not JSON or does not fit the
560
+ byte budget is kept as `receipt: null` with `unrecorded: 'not-json' | 'too-large'`;
561
+ the action stays confirmed and is not sent again. `retiredVersions` maps earlier
562
+ plan versions to their `NotificationProjection` so queued items drain after an
563
+ executor upgrade; an unknown version is reported to `onError` as
564
+ `NotificationPlanVersionError` and waits, spending no attempt and not consulting
565
+ `classify`, for an executor that knows it. `NotificationDeliveryStateSchema` validates the
566
+ optional `NotificationDeliveryState` on queued items and completed receipts:
567
+ `version`, `actions`, `receipts` and optional `projectedAt`. Checkpoints share the
568
+ existing atomic StateStore and lease fence. Receipt retention and serialized byte
569
+ budgets still apply. Single-send configuration remains valid without `delivery`.
570
+ A remote result lost before its checkpoint may be sent again; provider idempotency
571
+ or reconciliation is required. A projection may repeat after a crash before its
572
+ checkpoint. Business-transaction enqueue and durable quarantine are not implied.
@@ -6,7 +6,7 @@
6
6
 
7
7
  Parts of this slice:
8
8
  - `llms/application.txt`: Guide: Managed application kernel (docs/guide/application-kernel.md)
9
- - `llms/application.2.txt`: Guide: Application migration recipes (docs/guide/application-migration-recipes.md) · API reference: `stitchkit/application` (docs/api/reference.md)
9
+ - `llms/application.2.txt`: Guide: Managed application kernel (docs/guide/application-kernel.md) · Guide: Application migration recipes (docs/guide/application-migration-recipes.md) · API reference: `stitchkit/application` (docs/api/reference.md)
10
10
 
11
11
  ==============================================================================
12
12
  # Guide: Managed application kernel (docs/guide/application-kernel.md)
@@ -656,7 +656,12 @@ refusals are explicit; accepted ordered frames are never evicted.
656
656
  The absolute path's parent must already exist and be operator-controlled. One manager owns it via
657
657
  an exclusive `.lock`; new files use mode `0600` by default. `maxFiles` includes the active file,
658
658
  and a non-newline startup tail is rotated intact rather than guessed or repaired. An abrupt process
659
- death may leave the lock for an operator to remove only after proving the former owner is gone.
659
+ death may leave a lock. The default `refuse` policy leaves recovery to the operator;
660
+ `lock: 'reclaim-stale'` compares machine, boot and process birth identity before
661
+ recovery. A reused PID cannot impersonate a modern owner. Legacy records with a
662
+ live PID, foreign namespaces and unavailable identity refuse automatic recovery;
663
+ see the upgrading guide for quiescent legacy recovery. The same mechanism owns the
664
+ short-lived reclaim guard.
660
665
 
661
666
  `flush()` means every accepted append through that call's boundary settled. It is not `fsync`, a
662
667
  durable receipt, exactly-once execution or remote delivery. Timeout/cancellation bound only the
@@ -986,3 +991,28 @@ so a scheduler stall on a loaded host cannot pull a live lock from under its
986
991
  holder — after which the heartbeat wins and the lock is abandoned. Temporary files a crashed writer left beside the state are swept on
987
992
  the store's first update. Ledger corruption may be declared reconstructable;
988
993
  an outbox must fail closed rather than silently discard pending delivery.
994
+
995
+ ## Recovering change subscriptions
996
+
997
+ `changeSubscriptionResource` is an optional resource over a consumer-owned driver.
998
+ It uses a finite declared key set, subscribes before reading, reconciles after
999
+ reconnect and periodically repairs lost hints. `reconcileIntervalMs` is explicit;
1000
+ notifications alone cannot prove freshness. Within a key, hints coalesce into one
1001
+ trailing read and a failed read retries with backoff. Use the supplied
1002
+ `context.commit(() => publish(value))` after awaits to reject an obsolete connection.
1003
+
1004
+ Drivers implement `connect(signal)` and return `subscribe({ signal, hint,
1005
+ disconnected })` plus `close()`. Subscribe must establish the notification boundary
1006
+ before resolving. A database LISTEN driver owns its connection, channels, decoding
1007
+ and transaction ordering; no SQL or database driver is included here. The resource
1008
+ owns reconnect, deadlines and shutdown. Drivers must honor abort. If one ignores it,
1009
+ its slot remains occupied until settlement; deadlines cannot safely manufacture
1010
+ successful cleanup or permit an overlapping connection.
1011
+
1012
+ For watched reads, set `reconcileIntervalMs` on the existing `createWatchHub` rather
1013
+ than building a second read loop. Its per-key machinery is shared with managed
1014
+ subscriptions. Limits default to 1024 sources and 1024 subscribers per hub; set
1015
+ explicit finite values for larger workloads. Supply a server-verified admission
1016
+ scope to `attach` and abort it on logout, permission revocation or session replacement.
1017
+ The read callback receives the trusted scope as its third argument. A client owner
1018
+ ID in arguments is not authentication.
package/llms/files.txt CHANGED
@@ -27,7 +27,7 @@ available from `stitchkit/contract`.
27
27
  | `ManagedFileInspector` | _type_ | bounded-prefix read/write inspection callback with a finite cancellation signal that cannot own path or size |
28
28
  | `ManagedFileInspectionInput` / `ManagedFileInspection` | _type_ | inspector prefix/name/declared media/signal input and validated metadata-only result |
29
29
  | `writeFileAtomic` / `writeFileAtomicSync` / `WriteFileAtomicOptions` | function / _type_ | replace a file atomically: a random staging name created exclusively (never through a planted link), the mode set on the descriptor before the file is visible (default `0o600`, not masked by the umask), `fsync`, rename; a failure leaves the target and no staging file. The asynchronous form keeps the event loop running |
30
- | `withExclusiveLock` / `ExclusiveLockOptions` / `ExclusiveLock` / `ExclusiveLockOwner` | function / _type_ | run work under an exclusive lock between processes — a file recording its owner (pid, host, machine identity, time); waits up to `timeoutMs` (default 10 s) and stops on `signal`; a dead owner on this machine is taken over, a live, slow or foreign one never is; an ownerless lock only after `ownerlessGraceMs` |
30
+ | `withExclusiveLock` / `ExclusiveLockOptions` / `ExclusiveLock` / `ExclusiveLockOwner` | function / _type_ | run work under an exclusive lock between processes — a file recording its owner (pid, host, machine identity, time and nullable kernel process identity); waits up to `timeoutMs` (default 10 s) and stops on `signal`; a dead owner on this machine is taken over, a live, slow or foreign one never is; an ownerless lock only after `ownerlessGraceMs` |
31
31
  | `ExclusiveLockError` | class | `LOCK_TIMEOUT` naming the resource and its holder, or `LOCK_ABORTED` with the signal's reason |
32
32
 
33
33
  ---
package/llms/live.txt CHANGED
@@ -469,3 +469,11 @@ realtime contract from `stitchkit`, and the server halves live in `stitchkit/app
469
469
  | `watchDiff` / `applyWatchDelta` / `watchDeltaWins` | functions | build a difference (`undefined` when equal), rebuild the value from one (throws rather than inventing), and whether it is actually smaller than the value |
470
470
 
471
471
  ---
472
+
473
+ ### Session-scoped watch lifetime
474
+
475
+ `WatchClientConfig.session` captures a `SessionOperation`; `maxKeys` (1024) and
476
+ `maxListenersPerKey` (128) bound retained subscriptions; a handle takes its key on
477
+ `subscribe`, which is where capacity refuses. Its lifetime nonce travels
478
+ in optional `WatchKey.instance`, preventing old-session frames from matching a new
479
+ client on the same socket. This is routing identity, never authorization.
package/llms/react.txt CHANGED
@@ -182,3 +182,11 @@ Browser- and server-render-safe React data-layer helpers. Needs the
182
182
  For the rationale behind these APIs — why `Bun.serve` and not a framework, why
183
183
  two context types, why thin wrappers — see the
184
184
  [Architecture Decisions](../decisions/).
185
+
186
+ ### Watched handles in the query cache
187
+
188
+ `CacheBridgeConfig.watched` accepts `WatchCacheBinding` entries with `handle`,
189
+ `queryKey` and optional `state(frame)` observer. Include the session in query keys.
190
+ `CacheBridgeConfig.session` fences events and removes bound queries when that login
191
+ ends. Watch loss marks a query stale without triggering an independent refetch;
192
+ recovery belongs to the watched read.
package/llms/server.3.txt CHANGED
@@ -1029,3 +1029,60 @@ registry, and a name seen once does not live on in a map. This ordering exists o
1029
1029
  through `emitTo`; a broadcast through `realtime.to(room).emit` reaches the
1030
1030
  socket immediately, replay or not, so keep room traffic whose order matters
1031
1031
  relative to the snapshot on the registry.
1032
+
1033
+ ## Session-scoped watches and query cache
1034
+
1035
+ Pass the captured login operation as `createWatchClient(contract, { transport,
1036
+ session })`. It adds a lifetime nonce to watch keys and detaches on invalidation;
1037
+ a late frame for a previous login cannot match a new client's key on the same socket.
1038
+ Both client and server must support the new optional `WatchKey.instance` field.
1039
+ The nonce is not authorization: the server still admits a verified identity and
1040
+ uses `hub.attach(subscriber, { key: verifiedScope, signal: revocationSignal })`.
1041
+ The scope key must change with session and permission boundaries.
1042
+
1043
+ One scope and one question share one source and one read, however many client
1044
+ instances watch it: the hub routes each frame to every instance under its own
1045
+ key. A new tab of the same session costs a route, not a read.
1046
+
1047
+ ### Capacity
1048
+
1049
+ A hub admits at most `maxSources` sources (1024) and `maxSubscribers` attached
1050
+ subscribers (1024); a client holds at most `maxKeys` keys (1024) and
1051
+ `maxListenersPerKey` listeners per key (128). Every excess is a refusal, never
1052
+ unbounded state: `open` answers `{ accepted: false, reason }` — including for a
1053
+ subscriber attached over capacity, whose `attach` returns a watcher that refuses
1054
+ every `open` — and a client's `subscribe` throws. A client handle takes its key
1055
+ when it subscribes, so handles a render creates and never subscribes cost
1056
+ nothing. A connection handler that throws closes that connection and is logged;
1057
+ the server goes on. A subscriber attached over capacity is not tracked: its
1058
+ refusals stand until it reconnects.
1059
+
1060
+ A read that fails sends its subscribers `unavailable` / `source-error` with the
1061
+ `code` and `message` of an `AppError`, which is written for its caller. Any other
1062
+ error reaches only the hub's `logger`; the browser reads `The watched read failed`. Set larger finite limits for larger workloads, and
1063
+ `reconcileIntervalMs` when a lost invalidation must recover without a reconnect.
1064
+
1065
+ `createCacheBridge` can bind watched handles directly:
1066
+
1067
+ ```ts
1068
+ const bridge = createCacheBridge({
1069
+ socket, queryClient, handlers: {}, session,
1070
+ watched: [{
1071
+ handle: watches.list({ folderId }),
1072
+ queryKey: ['items', session.id, folderId],
1073
+ state: frame => showWatchState(frame),
1074
+ }],
1075
+ })
1076
+ bridge.connect()
1077
+ ```
1078
+
1079
+ A value updates that exact query; non-live state marks it stale while retaining its
1080
+ value. The existing phases (`opening`, `live`, `unavailable`, `resync-required`)
1081
+ remain the status model. Do not replace unavailable data with an empty collection.
1082
+ Session invalidation removes bound queries. Include the session identity in query
1083
+ keys and guard any application-level side effects with that same operation.
1084
+
1085
+ Use existing shared watches for paginated lists and selected-detail queries; bind
1086
+ each exact argument set to its query key. No global domain/query registry or new
1087
+ UI components are needed. Reconnect and revision/delta recovery remain owned by the
1088
+ watch client; silent lost notifications are repaired by hub reconciliation.