@plurnk/plurnk-service 1.4.0 → 1.5.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 (227) hide show
  1. package/.env.defaults +20 -23
  2. package/INSTALL.md +6 -5
  3. package/README.md +1 -0
  4. package/SPEC.md +250 -149
  5. package/dist/Paths.d.ts.map +1 -1
  6. package/dist/Paths.js +2 -3
  7. package/dist/Paths.js.map +1 -1
  8. package/dist/build-info.json +1 -1
  9. package/dist/content/index.d.ts +1 -0
  10. package/dist/content/index.d.ts.map +1 -1
  11. package/dist/content/index.js +1 -0
  12. package/dist/content/index.js.map +1 -1
  13. package/dist/content/line-marker.d.ts +7 -3
  14. package/dist/content/line-marker.d.ts.map +1 -1
  15. package/dist/content/line-marker.js +2 -1
  16. package/dist/content/line-marker.js.map +1 -1
  17. package/dist/content/matcher.d.ts +1 -1
  18. package/dist/content/matcher.d.ts.map +1 -1
  19. package/dist/content/matcher.js +2 -2
  20. package/dist/content/matcher.js.map +1 -1
  21. package/dist/content/read-projector.d.ts +14 -0
  22. package/dist/content/read-projector.d.ts.map +1 -0
  23. package/dist/content/read-projector.js +86 -0
  24. package/dist/content/read-projector.js.map +1 -0
  25. package/dist/content/read-resolve.d.ts +2 -7
  26. package/dist/content/read-resolve.d.ts.map +1 -1
  27. package/dist/content/read-resolve.js +32 -107
  28. package/dist/content/read-resolve.js.map +1 -1
  29. package/dist/core/BranchReceipt.d.ts +0 -1
  30. package/dist/core/BranchReceipt.d.ts.map +1 -1
  31. package/dist/core/BranchReceipt.js +0 -3
  32. package/dist/core/BranchReceipt.js.map +1 -1
  33. package/dist/core/BudgetOverflow.d.ts +0 -3
  34. package/dist/core/BudgetOverflow.d.ts.map +1 -1
  35. package/dist/core/BudgetOverflow.js +3 -15
  36. package/dist/core/BudgetOverflow.js.map +1 -1
  37. package/dist/core/ChannelWrite.d.ts +3 -0
  38. package/dist/core/ChannelWrite.d.ts.map +1 -1
  39. package/dist/core/ChannelWrite.js +2 -2
  40. package/dist/core/ChannelWrite.js.map +1 -1
  41. package/dist/core/ChannelWrite.sql +4 -3
  42. package/dist/core/CoreSchemeServices.d.ts +10 -2
  43. package/dist/core/CoreSchemeServices.d.ts.map +1 -1
  44. package/dist/core/CoreSchemeServices.js.map +1 -1
  45. package/dist/core/Dispatcher.d.ts +3 -7
  46. package/dist/core/Dispatcher.d.ts.map +1 -1
  47. package/dist/core/Dispatcher.js +283 -217
  48. package/dist/core/Dispatcher.js.map +1 -1
  49. package/dist/core/Engine.d.ts +19 -12
  50. package/dist/core/Engine.d.ts.map +1 -1
  51. package/dist/core/Engine.js +261 -167
  52. package/dist/core/Engine.js.map +1 -1
  53. package/dist/core/Engine.sql +66 -63
  54. package/dist/core/LogBody.d.ts +2 -1
  55. package/dist/core/LogBody.d.ts.map +1 -1
  56. package/dist/core/LogBody.js +33 -1
  57. package/dist/core/LogBody.js.map +1 -1
  58. package/dist/core/LoopLifecycle.d.ts +1 -2
  59. package/dist/core/LoopLifecycle.d.ts.map +1 -1
  60. package/dist/core/LoopLifecycle.js +1 -4
  61. package/dist/core/LoopLifecycle.js.map +1 -1
  62. package/dist/core/LoopLifecycle.sql +1 -4
  63. package/dist/core/PacketBuilder.d.ts +3 -2
  64. package/dist/core/PacketBuilder.d.ts.map +1 -1
  65. package/dist/core/PacketBuilder.js +16 -16
  66. package/dist/core/PacketBuilder.js.map +1 -1
  67. package/dist/core/StrikeRail.d.ts +5 -1
  68. package/dist/core/StrikeRail.d.ts.map +1 -1
  69. package/dist/core/StrikeRail.js +4 -3
  70. package/dist/core/StrikeRail.js.map +1 -1
  71. package/dist/core/TerminalResult.d.ts +16 -0
  72. package/dist/core/TerminalResult.d.ts.map +1 -0
  73. package/dist/core/TerminalResult.js +49 -0
  74. package/dist/core/TerminalResult.js.map +1 -0
  75. package/dist/core/caps/CapsResolve.d.ts +5 -1
  76. package/dist/core/caps/CapsResolve.d.ts.map +1 -1
  77. package/dist/core/caps/CapsResolve.js +8 -4
  78. package/dist/core/caps/CapsResolve.js.map +1 -1
  79. package/dist/core/caps/DbChannelCaps.d.ts +1 -1
  80. package/dist/core/caps/DbChannelCaps.d.ts.map +1 -1
  81. package/dist/core/caps/DbChannelCaps.js +6 -4
  82. package/dist/core/caps/DbChannelCaps.js.map +1 -1
  83. package/dist/core/caps/DbEntryCaps.d.ts +1 -1
  84. package/dist/core/caps/DbEntryCaps.d.ts.map +1 -1
  85. package/dist/core/caps/DbEntryCaps.js +14 -4
  86. package/dist/core/caps/DbEntryCaps.js.map +1 -1
  87. package/dist/core/caps/DbNotifyCaps.d.ts +1 -1
  88. package/dist/core/caps/DbNotifyCaps.d.ts.map +1 -1
  89. package/dist/core/caps/DbNotifyCaps.js +6 -4
  90. package/dist/core/caps/DbNotifyCaps.js.map +1 -1
  91. package/dist/core/caps/DbSubscriptionCaps.d.ts +4 -6
  92. package/dist/core/caps/DbSubscriptionCaps.d.ts.map +1 -1
  93. package/dist/core/caps/DbSubscriptionCaps.js +27 -13
  94. package/dist/core/caps/DbSubscriptionCaps.js.map +1 -1
  95. package/dist/core/caps/DbTagCaps.d.ts +1 -1
  96. package/dist/core/caps/DbTagCaps.d.ts.map +1 -1
  97. package/dist/core/caps/DbTagCaps.js +6 -4
  98. package/dist/core/caps/DbTagCaps.js.map +1 -1
  99. package/dist/core/caps/SchemeCtxImpl.d.ts +6 -1
  100. package/dist/core/caps/SchemeCtxImpl.d.ts.map +1 -1
  101. package/dist/core/caps/SchemeCtxImpl.js +6 -6
  102. package/dist/core/caps/SchemeCtxImpl.js.map +1 -1
  103. package/dist/core/fork.sql +2 -2
  104. package/dist/core/git-iso.d.ts +3 -2
  105. package/dist/core/git-iso.d.ts.map +1 -1
  106. package/dist/core/git-iso.js +27 -12
  107. package/dist/core/git-iso.js.map +1 -1
  108. package/dist/core/git-membership.d.ts +1 -0
  109. package/dist/core/git-membership.d.ts.map +1 -1
  110. package/dist/core/git-membership.js +86 -24
  111. package/dist/core/git-membership.js.map +1 -1
  112. package/dist/core/git-state.d.ts +8 -1
  113. package/dist/core/git-state.d.ts.map +1 -1
  114. package/dist/core/git-state.js +35 -16
  115. package/dist/core/git-state.js.map +1 -1
  116. package/dist/core/namespace.d.ts +1 -0
  117. package/dist/core/namespace.d.ts.map +1 -1
  118. package/dist/core/namespace.js +20 -0
  119. package/dist/core/namespace.js.map +1 -1
  120. package/dist/core/optimistic-settlement.d.ts +2 -0
  121. package/dist/core/optimistic-settlement.d.ts.map +1 -0
  122. package/dist/core/optimistic-settlement.js +14 -0
  123. package/dist/core/optimistic-settlement.js.map +1 -0
  124. package/dist/core/packet-wire.d.ts +1 -1
  125. package/dist/core/packet-wire.d.ts.map +1 -1
  126. package/dist/core/packet-wire.js +81 -35
  127. package/dist/core/packet-wire.js.map +1 -1
  128. package/dist/core/results.d.ts +4 -2
  129. package/dist/core/results.d.ts.map +1 -1
  130. package/dist/core/results.js +6 -0
  131. package/dist/core/results.js.map +1 -1
  132. package/dist/core/scheme-types.d.ts +0 -12
  133. package/dist/core/scheme-types.d.ts.map +1 -1
  134. package/dist/core/scheme-types.js.map +1 -1
  135. package/dist/core/worker-ops.sql +4 -4
  136. package/dist/core/workspace-settings.js +1 -1
  137. package/dist/core/workspace-settings.js.map +1 -1
  138. package/dist/digest/Digest.d.ts.map +1 -1
  139. package/dist/digest/Digest.js +236 -74
  140. package/dist/digest/Digest.js.map +1 -1
  141. package/dist/digest/digest.sql +9 -5
  142. package/dist/schemes/Exec.d.ts +4 -4
  143. package/dist/schemes/Exec.d.ts.map +1 -1
  144. package/dist/schemes/Exec.js +56 -33
  145. package/dist/schemes/Exec.js.map +1 -1
  146. package/dist/schemes/ExecOutputScheme.d.ts +4 -5
  147. package/dist/schemes/ExecOutputScheme.d.ts.map +1 -1
  148. package/dist/schemes/ExecOutputScheme.js +12 -20
  149. package/dist/schemes/ExecOutputScheme.js.map +1 -1
  150. package/dist/schemes/File.d.ts +1 -3
  151. package/dist/schemes/File.d.ts.map +1 -1
  152. package/dist/schemes/File.js +11 -19
  153. package/dist/schemes/File.js.map +1 -1
  154. package/dist/schemes/Log.d.ts +5 -5
  155. package/dist/schemes/Log.d.ts.map +1 -1
  156. package/dist/schemes/Log.js +74 -172
  157. package/dist/schemes/Log.js.map +1 -1
  158. package/dist/schemes/Log.sql +20 -13
  159. package/dist/schemes/Prompt.d.ts +2 -3
  160. package/dist/schemes/Prompt.d.ts.map +1 -1
  161. package/dist/schemes/Prompt.js +1 -4
  162. package/dist/schemes/Prompt.js.map +1 -1
  163. package/dist/schemes/Skill.d.ts +2 -3
  164. package/dist/schemes/Skill.d.ts.map +1 -1
  165. package/dist/schemes/Skill.js +0 -3
  166. package/dist/schemes/Skill.js.map +1 -1
  167. package/dist/schemes/Worker.d.ts +5 -5
  168. package/dist/schemes/Worker.d.ts.map +1 -1
  169. package/dist/schemes/Worker.js +92 -81
  170. package/dist/schemes/Worker.js.map +1 -1
  171. package/dist/schemes/_entry-crud.d.ts +2 -1
  172. package/dist/schemes/_entry-crud.d.ts.map +1 -1
  173. package/dist/schemes/_entry-crud.js +14 -1
  174. package/dist/schemes/_entry-crud.js.map +1 -1
  175. package/dist/schemes/_entry-crud.sql +9 -3
  176. package/dist/schemes/_entry-find.d.ts +37 -11
  177. package/dist/schemes/_entry-find.d.ts.map +1 -1
  178. package/dist/schemes/_entry-find.js +141 -153
  179. package/dist/schemes/_entry-find.js.map +1 -1
  180. package/dist/schemes/_entry-ops.d.ts +9 -5
  181. package/dist/schemes/_entry-ops.d.ts.map +1 -1
  182. package/dist/schemes/_entry-ops.js +12 -73
  183. package/dist/schemes/_entry-ops.js.map +1 -1
  184. package/dist/schemes/_entry-ops.sql +1 -2
  185. package/dist/schemes/_entry-semantic.d.ts +5 -7
  186. package/dist/schemes/_entry-semantic.d.ts.map +1 -1
  187. package/dist/schemes/_entry-semantic.js +10 -31
  188. package/dist/schemes/_entry-semantic.js.map +1 -1
  189. package/dist/schemes/_entry-semantic.sql +2 -2
  190. package/dist/schemes/_search-index.d.ts.map +1 -1
  191. package/dist/schemes/_search-index.js +6 -4
  192. package/dist/schemes/_search-index.js.map +1 -1
  193. package/dist/server/BranchBatches.d.ts +1 -0
  194. package/dist/server/BranchBatches.d.ts.map +1 -1
  195. package/dist/server/BranchBatches.js +1 -0
  196. package/dist/server/BranchBatches.js.map +1 -1
  197. package/dist/server/Daemon.d.ts +5 -7
  198. package/dist/server/Daemon.d.ts.map +1 -1
  199. package/dist/server/Daemon.js +222 -54
  200. package/dist/server/Daemon.js.map +1 -1
  201. package/dist/server/DaemonModule.d.ts +3 -3
  202. package/dist/server/DaemonModule.d.ts.map +1 -1
  203. package/dist/server/branch-batch.sql +3 -1
  204. package/dist/server/client-input.d.ts +2 -1
  205. package/dist/server/client-input.d.ts.map +1 -1
  206. package/dist/server/client-input.js +7 -1
  207. package/dist/server/client-input.js.map +1 -1
  208. package/dist/server/drain.sql +6 -5
  209. package/dist/server/envelope.d.ts +2 -2
  210. package/dist/server/envelope.d.ts.map +1 -1
  211. package/dist/server/envelope.js +0 -1
  212. package/dist/server/envelope.js.map +1 -1
  213. package/dist/server/envelope.sql +1 -2
  214. package/dist/server/lifecycle-recovery.sql +34 -1
  215. package/dist/server/logEntry.d.ts +1 -1
  216. package/dist/server/logEntry.d.ts.map +1 -1
  217. package/dist/server/logEntry.js +2 -1
  218. package/dist/server/logEntry.js.map +1 -1
  219. package/dist/service.d.ts.map +1 -1
  220. package/dist/service.js +13 -1
  221. package/dist/service.js.map +1 -1
  222. package/migrations/001_schema.sql +238 -125
  223. package/package.json +48 -46
  224. package/dist/matrix/live-specimen.d.ts +0 -9
  225. package/dist/matrix/live-specimen.d.ts.map +0 -1
  226. package/dist/matrix/live-specimen.js +0 -37
  227. package/dist/matrix/live-specimen.js.map +0 -1
@@ -71,13 +71,19 @@ CREATE TABLE IF NOT EXISTS ambient_events (
71
71
  rx TEXT,
72
72
  attrs TEXT NOT NULL DEFAULT '{}' CHECK (json_valid(attrs)),
73
73
  status_rx INTEGER NOT NULL CHECK (status_rx BETWEEN 100 AND 599),
74
- prompt TEXT,
75
74
  terminated_by TEXT CHECK (terminated_by IS NULL OR terminated_by = 'cancel'),
76
75
  created_at TEXT NOT NULL DEFAULT (strftime('%Y-%m-%dT%H:%M:%fZ', 'now')),
77
76
  CHECK (
78
- (kind = 'edit' AND op = 'EDIT' AND rx IS NOT NULL AND prompt IS NULL AND terminated_by IS NULL)
77
+ (kind = 'edit' AND op = 'EDIT' AND rx IS NOT NULL AND terminated_by IS NULL)
79
78
  OR
80
- (kind = 'loop_termination' AND op = 'SEND' AND scheme = 'worker' AND prompt IS NOT NULL)
79
+ (kind = 'loop_termination'
80
+ AND op = 'SEND'
81
+ AND scheme = 'worker'
82
+ AND rx IS NOT NULL
83
+ AND json_valid(rx)
84
+ AND json_type(rx) = 'object'
85
+ AND json_type(rx, '$.status') = 'integer'
86
+ AND json_extract(rx, '$.status') = status_rx)
81
87
  ),
82
88
  FOREIGN KEY (workspace_id) REFERENCES workspaces(id) ON DELETE CASCADE,
83
89
  FOREIGN KEY (producer_worker_id) REFERENCES workers(id) ON DELETE CASCADE
@@ -102,6 +108,7 @@ CREATE TABLE IF NOT EXISTS loops (
102
108
  prompt TEXT NOT NULL,
103
109
  flags TEXT NOT NULL DEFAULT '{}' CHECK (json_valid(flags)),
104
110
  provider_spec TEXT NOT NULL DEFAULT 'null' CHECK (json_valid(provider_spec)),
111
+ child_provider_spec TEXT NOT NULL DEFAULT 'null' CHECK (json_valid(child_provider_spec)),
105
112
  max_turns INTEGER NOT NULL DEFAULT 50 CHECK (max_turns >= -1),
106
113
  -- {§methods-loop-run-open-paths}: the initial prompt frame's selected paths,
107
114
  -- held here until turn 1 materializes that frame (string[] JSON).
@@ -110,22 +117,56 @@ CREATE TABLE IF NOT EXISTS loops (
110
117
  -- complete orphan frame set of one concluded source loop.
111
118
  orphan_source_loop_id INTEGER,
112
119
  -- {§worker-scheme} loop-termination delta: terminated_at is stamped by the trigger
113
- -- below when status crosses into terminal (every death-path, uniformly);
114
- -- terminal_message is the deliverable — the SEND[200] body or the abandonment
115
- -- reason — set by the guarded terminal lifecycle transition.
120
+ -- below when status crosses into terminal (every death-path, uniformly).
116
121
  terminated_at TEXT,
117
- terminal_message TEXT,
118
- terminal_result TEXT CHECK (terminal_result IS NULL OR json_valid(terminal_result)),
122
+ terminal_result TEXT,
119
123
  -- {§loop-terminal-authorship}: 'cancel' names an external loop.cancel;
120
124
  -- NULL covers model terminals and engine verdicts whose result carries the story.
121
125
  terminated_by TEXT CHECK (terminated_by IS NULL OR terminated_by = 'cancel'),
126
+ CONSTRAINT loops_terminal_result_contract CHECK (
127
+ CASE
128
+ WHEN status IN (100, 102, 202) THEN terminal_result IS NULL
129
+ WHEN terminal_result IS NULL OR NOT json_valid(terminal_result) THEN 0
130
+ ELSE
131
+ json_type(terminal_result) IS 'object'
132
+ AND json_type(terminal_result, '$.status') IS 'integer'
133
+ AND (
134
+ json_extract(terminal_result, '$.status') = status
135
+ OR (
136
+ status = 200
137
+ AND json_extract(terminal_result, '$.status') BETWEEN 200 AND 399
138
+ AND json_extract(terminal_result, '$.status') != 202
139
+ )
140
+ OR (
141
+ status = 500
142
+ AND json_extract(terminal_result, '$.status') BETWEEN 400 AND 599
143
+ )
144
+ )
145
+ AND CASE
146
+ WHEN json_extract(terminal_result, '$.status') < 400 THEN
147
+ json_type(terminal_result, '$.problem') IS NULL
148
+ ELSE
149
+ json_type(terminal_result, '$.problem') IS 'object'
150
+ AND json_type(terminal_result, '$.problem.status') IS 'integer'
151
+ AND json_extract(terminal_result, '$.problem.status')
152
+ = json_extract(terminal_result, '$.status')
153
+ AND json_type(terminal_result, '$.problem.type') IS 'text'
154
+ AND length(json_extract(terminal_result, '$.problem.type')) > 0
155
+ AND json_type(terminal_result, '$.problem.title') IS 'text'
156
+ AND length(json_extract(terminal_result, '$.problem.title')) > 0
157
+ AND json_type(terminal_result, '$.problem.detail') IS 'text'
158
+ AND length(json_extract(terminal_result, '$.problem.detail')) > 0
159
+ AND json_type(terminal_result, '$.problem.instance') IS 'text'
160
+ AND length(json_extract(terminal_result, '$.problem.instance')) > 0
161
+ END
162
+ END
163
+ ),
122
164
  FOREIGN KEY (worker_id) REFERENCES workers(id) ON DELETE CASCADE,
123
165
  FOREIGN KEY (orphan_source_loop_id) REFERENCES loops(id)
124
166
  ) STRICT;
125
167
 
126
168
  CREATE UNIQUE INDEX IF NOT EXISTS loops_worker_id_sequence ON loops (worker_id, sequence);
127
169
  CREATE UNIQUE INDEX IF NOT EXISTS loops_orphan_source_loop_id ON loops (orphan_source_loop_id);
128
-
129
170
  -- {§worker-scheme}: a loop crossing into a terminal status stamps terminated_at, so sibling
130
171
  -- workers pull the termination as a folded ambient delta — caught uniformly across every
131
172
  -- death-path (SEND, grinder, max-turns, strike, KILL). The stamp updates terminated_at,
@@ -147,96 +188,15 @@ WHEN NEW.status IN (200, 413, 429, 499, 500, 504, 508) AND OLD.status NOT IN (20
147
188
  BEGIN
148
189
  INSERT INTO ambient_events (
149
190
  workspace_id, producer_worker_id, kind, source_record_id, source,
150
- op, scheme, pathname, rx, status_rx, prompt, terminated_by
191
+ op, scheme, pathname, rx, status_rx, terminated_by
151
192
  )
152
193
  SELECT w.workspace_id, NEW.worker_id, 'loop_termination', NEW.id, NULL,
153
- 'SEND', 'worker', '/' || w.name, NEW.terminal_message, NEW.status, NEW.prompt, NEW.terminated_by
194
+ 'SEND', 'worker', '/' || w.name, NEW.terminal_result,
195
+ json_extract(NEW.terminal_result, '$.status'), NEW.terminated_by
154
196
  FROM workers w
155
197
  WHERE w.id = NEW.worker_id;
156
198
  END;
157
199
 
158
- CREATE TRIGGER IF NOT EXISTS loops_result_contract_insert
159
- BEFORE INSERT ON loops
160
- WHEN NEW.status IN (100, 102, 200, 202, 413, 429, 499, 500, 504, 508)
161
- AND NOT (
162
- (NEW.status IN (100, 102, 202) AND NEW.terminal_result IS NULL)
163
- OR (
164
- NEW.status IN (200, 413, 429, 499, 500, 504, 508)
165
- AND NEW.terminal_result IS NOT NULL
166
- AND json_valid(NEW.terminal_result)
167
- AND json_type(NEW.terminal_result, '$.status') = 'integer'
168
- AND (
169
- json_extract(NEW.terminal_result, '$.status') = NEW.status
170
- OR (
171
- NEW.status = 200
172
- AND json_extract(NEW.terminal_result, '$.status') BETWEEN 200 AND 399
173
- AND json_extract(NEW.terminal_result, '$.status') != 202
174
- )
175
- OR (
176
- NEW.status = 500
177
- AND json_extract(NEW.terminal_result, '$.status') BETWEEN 400 AND 599
178
- )
179
- )
180
- AND (
181
- (NEW.status < 400 AND json_type(NEW.terminal_result, '$.problem') IS NULL)
182
- OR (
183
- NEW.status >= 400
184
- AND json_type(NEW.terminal_result, '$.problem') = 'object'
185
- AND json_extract(NEW.terminal_result, '$.problem.status')
186
- = json_extract(NEW.terminal_result, '$.status')
187
- AND length(json_extract(NEW.terminal_result, '$.problem.type')) > 0
188
- AND length(json_extract(NEW.terminal_result, '$.problem.title')) > 0
189
- AND length(json_extract(NEW.terminal_result, '$.problem.detail')) > 0
190
- AND length(json_extract(NEW.terminal_result, '$.problem.instance')) > 0
191
- )
192
- )
193
- )
194
- )
195
- BEGIN
196
- SELECT RAISE(ABORT, 'loop terminal result violates the operation-result contract');
197
- END;
198
-
199
- CREATE TRIGGER IF NOT EXISTS loops_result_contract_update
200
- BEFORE UPDATE OF status, terminal_result ON loops
201
- WHEN NEW.status IN (100, 102, 200, 202, 413, 429, 499, 500, 504, 508)
202
- AND NOT (
203
- (NEW.status IN (100, 102, 202) AND NEW.terminal_result IS NULL)
204
- OR (
205
- NEW.status IN (200, 413, 429, 499, 500, 504, 508)
206
- AND NEW.terminal_result IS NOT NULL
207
- AND json_valid(NEW.terminal_result)
208
- AND json_type(NEW.terminal_result, '$.status') = 'integer'
209
- AND (
210
- json_extract(NEW.terminal_result, '$.status') = NEW.status
211
- OR (
212
- NEW.status = 200
213
- AND json_extract(NEW.terminal_result, '$.status') BETWEEN 200 AND 399
214
- AND json_extract(NEW.terminal_result, '$.status') != 202
215
- )
216
- OR (
217
- NEW.status = 500
218
- AND json_extract(NEW.terminal_result, '$.status') BETWEEN 400 AND 599
219
- )
220
- )
221
- AND (
222
- (NEW.status < 400 AND json_type(NEW.terminal_result, '$.problem') IS NULL)
223
- OR (
224
- NEW.status >= 400
225
- AND json_type(NEW.terminal_result, '$.problem') = 'object'
226
- AND json_extract(NEW.terminal_result, '$.problem.status')
227
- = json_extract(NEW.terminal_result, '$.status')
228
- AND length(json_extract(NEW.terminal_result, '$.problem.type')) > 0
229
- AND length(json_extract(NEW.terminal_result, '$.problem.title')) > 0
230
- AND length(json_extract(NEW.terminal_result, '$.problem.detail')) > 0
231
- AND length(json_extract(NEW.terminal_result, '$.problem.instance')) > 0
232
- )
233
- )
234
- )
235
- )
236
- BEGIN
237
- SELECT RAISE(ABORT, 'loop terminal result violates the operation-result contract');
238
- END;
239
-
240
200
  -- turns
241
201
  -- finish_reason / model: provider-call metadata from the provider response contract.
242
202
  -- Properties of the call, not of the model's emission payload — kept on
@@ -305,23 +265,46 @@ CREATE TABLE IF NOT EXISTS turn_attempts (
305
265
  id INTEGER NOT NULL PRIMARY KEY,
306
266
  turn_id INTEGER NOT NULL,
307
267
  sequence INTEGER NOT NULL CHECK (sequence >= 1),
308
- accepted INTEGER NOT NULL CHECK (accepted IN (0, 1)),
309
- response TEXT NOT NULL CHECK (json_valid(response)),
268
+ state TEXT NOT NULL DEFAULT 'pending' CHECK (state IN ('pending', 'response', 'error')),
269
+ accepted INTEGER CHECK (accepted IS NULL OR accepted IN (0, 1)),
270
+ response TEXT CHECK (response IS NULL OR json_valid(response)),
271
+ failure TEXT CHECK (failure IS NULL OR json_valid(failure)),
310
272
  parse_errors TEXT NOT NULL DEFAULT '[]' CHECK (json_valid(parse_errors)),
311
- -- Exact opaque tag set forwarded with this response-bearing provider call.
273
+ -- Exact opaque tag set forwarded with this provider call.
312
274
  -- {§attribution}
313
275
  attributions TEXT NOT NULL DEFAULT '[]' CHECK (
314
276
  json_valid(attributions) AND json_type(attributions) = 'array'
315
277
  ),
316
- usage_prompt INTEGER NOT NULL DEFAULT 0 CHECK (usage_prompt >= 0),
317
- usage_completion INTEGER NOT NULL DEFAULT 0 CHECK (usage_completion >= 0),
318
- usage_reasoning INTEGER NOT NULL DEFAULT 0 CHECK (usage_reasoning >= 0),
319
- usage_cached INTEGER NOT NULL DEFAULT 0 CHECK (usage_cached >= 0),
320
- usage_cost TEXT NOT NULL CHECK (json_valid(usage_cost) AND json_type(usage_cost) = 'object'),
278
+ usage_prompt INTEGER CHECK (usage_prompt IS NULL OR usage_prompt >= 0),
279
+ usage_completion INTEGER CHECK (usage_completion IS NULL OR usage_completion >= 0),
280
+ usage_reasoning INTEGER CHECK (usage_reasoning IS NULL OR usage_reasoning >= 0),
281
+ usage_cached INTEGER CHECK (usage_cached IS NULL OR usage_cached >= 0),
282
+ usage_cost TEXT CHECK (usage_cost IS NULL OR (json_valid(usage_cost) AND json_type(usage_cost) = 'object')),
321
283
  usage_cost_usd REAL CHECK (usage_cost_usd IS NULL OR usage_cost_usd >= 0),
322
284
  finish_reason TEXT,
323
285
  model TEXT NOT NULL CHECK (length(model) >= 1),
324
286
  timestamp TEXT NOT NULL DEFAULT (strftime('%Y-%m-%dT%H:%M:%fZ', 'now')),
287
+ completed_at TEXT,
288
+ CHECK (
289
+ (state = 'pending'
290
+ AND accepted IS NULL AND response IS NULL AND failure IS NULL
291
+ AND usage_prompt IS NULL AND usage_completion IS NULL
292
+ AND usage_reasoning IS NULL AND usage_cached IS NULL
293
+ AND usage_cost IS NULL AND usage_cost_usd IS NULL
294
+ AND finish_reason IS NULL AND completed_at IS NULL)
295
+ OR
296
+ (state = 'response'
297
+ AND response IS NOT NULL
298
+ AND usage_prompt IS NOT NULL AND usage_completion IS NOT NULL
299
+ AND usage_reasoning IS NOT NULL AND usage_cached IS NOT NULL
300
+ AND usage_cost IS NOT NULL AND completed_at IS NOT NULL)
301
+ OR
302
+ (state = 'error'
303
+ AND accepted IS NULL AND response IS NULL AND failure IS NOT NULL
304
+ AND usage_prompt = 0 AND usage_completion = 0
305
+ AND usage_reasoning = 0 AND usage_cached = 0
306
+ AND usage_cost IS NOT NULL AND completed_at IS NOT NULL)
307
+ ),
325
308
  UNIQUE (turn_id, sequence),
326
309
  FOREIGN KEY (turn_id) REFERENCES turns(id) ON DELETE CASCADE
327
310
  ) STRICT;
@@ -331,6 +314,94 @@ CREATE UNIQUE INDEX IF NOT EXISTS turn_attempts_one_accepted_per_turn
331
314
  ON turn_attempts (turn_id)
332
315
  WHERE accepted = 1;
333
316
 
317
+ CREATE TRIGGER IF NOT EXISTS turn_attempts_request_identity_immutable
318
+ BEFORE UPDATE OF turn_id, sequence, attributions, timestamp ON turn_attempts
319
+ BEGIN
320
+ SELECT RAISE(ABORT, 'provider attempt request identity is immutable');
321
+ END;
322
+
323
+ CREATE TRIGGER IF NOT EXISTS turn_attempts_state_forward_only
324
+ BEFORE UPDATE OF state ON turn_attempts
325
+ WHEN NOT (
326
+ NEW.state = OLD.state
327
+ OR (OLD.state = 'pending' AND NEW.state IN ('response', 'error'))
328
+ )
329
+ BEGIN
330
+ SELECT RAISE(ABORT, 'provider attempt state may only close once');
331
+ END;
332
+
333
+ CREATE TRIGGER IF NOT EXISTS turn_attempts_observation_immutable
334
+ BEFORE UPDATE OF response, usage_prompt, usage_completion, usage_reasoning,
335
+ usage_cached, finish_reason, model, completed_at
336
+ ON turn_attempts
337
+ WHEN OLD.state != 'pending'
338
+ BEGIN
339
+ SELECT RAISE(ABORT, 'provider attempt observation is immutable');
340
+ END;
341
+
342
+ CREATE TRIGGER IF NOT EXISTS turn_attempts_classification_once
343
+ BEFORE UPDATE OF accepted, parse_errors, failure, usage_cost, usage_cost_usd
344
+ ON turn_attempts
345
+ WHEN OLD.state = 'error' OR (OLD.state = 'response' AND OLD.accepted IS NOT NULL)
346
+ BEGIN
347
+ SELECT RAISE(ABORT, 'provider attempt classification is immutable');
348
+ END;
349
+
350
+ -- Attempt rows are the monetary and provider-usage authority. Turns retain a
351
+ -- denormalized projection for their public read contract, maintained here so a
352
+ -- crash between provider I/O and engine closure cannot leave a false zero.
353
+ CREATE VIEW IF NOT EXISTS turn_attempt_rollups AS
354
+ SELECT t.id AS turn_id,
355
+ COALESCE(SUM(a.usage_prompt), 0) AS usage_prompt,
356
+ COALESCE(SUM(a.usage_completion), 0) AS usage_completion,
357
+ COALESCE(SUM(a.usage_reasoning), 0) AS usage_reasoning,
358
+ COALESCE(SUM(a.usage_cached), 0) AS usage_cached,
359
+ COALESCE((
360
+ SELECT json_group_array(json(ordered.usage_cost))
361
+ FROM (
362
+ SELECT observed.usage_cost
363
+ FROM turn_attempts observed
364
+ WHERE observed.turn_id = t.id AND observed.usage_cost IS NOT NULL
365
+ ORDER BY observed.sequence
366
+ ) ordered
367
+ ), '[]') AS usage_cost,
368
+ CASE
369
+ WHEN COUNT(a.id) = 0 THEN 0
370
+ WHEN COUNT(a.id) FILTER (WHERE a.usage_cost_usd IS NULL) > 0 THEN NULL
371
+ ELSE COALESCE(SUM(a.usage_cost_usd), 0)
372
+ END AS usage_cost_usd
373
+ FROM turns t
374
+ LEFT JOIN turn_attempts a ON a.turn_id = t.id
375
+ GROUP BY t.id;
376
+
377
+ CREATE TRIGGER IF NOT EXISTS turn_attempts_rollup_insert
378
+ AFTER INSERT ON turn_attempts
379
+ BEGIN
380
+ UPDATE turns SET
381
+ usage_prompt = (SELECT usage_prompt FROM turn_attempt_rollups WHERE turn_id = NEW.turn_id),
382
+ usage_completion = (SELECT usage_completion FROM turn_attempt_rollups WHERE turn_id = NEW.turn_id),
383
+ usage_reasoning = (SELECT usage_reasoning FROM turn_attempt_rollups WHERE turn_id = NEW.turn_id),
384
+ usage_cached = (SELECT usage_cached FROM turn_attempt_rollups WHERE turn_id = NEW.turn_id),
385
+ usage_cost = (SELECT usage_cost FROM turn_attempt_rollups WHERE turn_id = NEW.turn_id),
386
+ usage_cost_usd = (SELECT usage_cost_usd FROM turn_attempt_rollups WHERE turn_id = NEW.turn_id)
387
+ WHERE id = NEW.turn_id;
388
+ END;
389
+
390
+ CREATE TRIGGER IF NOT EXISTS turn_attempts_rollup_update
391
+ AFTER UPDATE OF state, usage_prompt, usage_completion, usage_reasoning,
392
+ usage_cached, usage_cost, usage_cost_usd
393
+ ON turn_attempts
394
+ BEGIN
395
+ UPDATE turns SET
396
+ usage_prompt = (SELECT usage_prompt FROM turn_attempt_rollups WHERE turn_id = NEW.turn_id),
397
+ usage_completion = (SELECT usage_completion FROM turn_attempt_rollups WHERE turn_id = NEW.turn_id),
398
+ usage_reasoning = (SELECT usage_reasoning FROM turn_attempt_rollups WHERE turn_id = NEW.turn_id),
399
+ usage_cached = (SELECT usage_cached FROM turn_attempt_rollups WHERE turn_id = NEW.turn_id),
400
+ usage_cost = (SELECT usage_cost FROM turn_attempt_rollups WHERE turn_id = NEW.turn_id),
401
+ usage_cost_usd = (SELECT usage_cost_usd FROM turn_attempt_rollups WHERE turn_id = NEW.turn_id)
402
+ WHERE id = NEW.turn_id;
403
+ END;
404
+
334
405
  -- derivations
335
406
  -- Content-addressed deep projections. Entries point at a COMPLETE artifact by
336
407
  -- deep_hash; graph, FTS, and vectors are stored once regardless of how many
@@ -377,7 +448,8 @@ CREATE TABLE IF NOT EXISTS entries (
377
448
  -- unchanged entry is skipped, never re-metadatafied every turn.
378
449
  deep_hash TEXT,
379
450
  -- SPEC {§membership-change-gated-sync} — the per-member sync stat-detect:
380
- -- "<mtimeMs>:<size>" of the disk file at its last materialization. The pre-turn
451
+ -- "<mtimeMs>:<size>" of the disk file at its last materialization, or `absent`
452
+ -- after an observed deletion. The pre-turn
381
453
  -- sync stat()s every member but re-reads/re-tokenizes/rewrites only one whose
382
454
  -- signature changed; an unchanged member is a no-op. NULL = never synced.
383
455
  synced_sig TEXT,
@@ -409,6 +481,36 @@ CREATE TABLE IF NOT EXISTS entry_channels (
409
481
  -- NULL). The per-tokenizer token cache it once keyed was retired — {§tokenomics-agnostic-ruler}.
410
482
  content_hash TEXT,
411
483
  state TEXT NOT NULL DEFAULT 'static' CHECK (state IN ('static', 'active', 'closed', 'errored')),
484
+ -- Exact terminal producer evidence for this representation channel. NULL is
485
+ -- the ordinary implicit {status:200}; selection/projection metadata belongs
486
+ -- to core and is never stored here.
487
+ producer_result TEXT,
488
+ CONSTRAINT entry_channel_producer_result_contract CHECK (
489
+ CASE
490
+ WHEN producer_result IS NULL THEN 1
491
+ WHEN NOT json_valid(producer_result) THEN 0
492
+ ELSE
493
+ json_type(producer_result) IS 'object'
494
+ AND json_type(producer_result, '$.status') IS 'integer'
495
+ AND json_extract(producer_result, '$.status') BETWEEN 200 AND 599
496
+ AND json_extract(producer_result, '$.status') != 202
497
+ AND CASE
498
+ WHEN json_extract(producer_result, '$.status') < 400 THEN
499
+ json_type(producer_result, '$.problem') IS NULL
500
+ ELSE
501
+ json_type(producer_result, '$.problem') IS 'object'
502
+ AND json_type(producer_result, '$.problem.status') IS 'integer'
503
+ AND json_extract(producer_result, '$.problem.status')
504
+ = json_extract(producer_result, '$.status')
505
+ AND json_type(producer_result, '$.problem.type') IS 'text'
506
+ AND length(json_extract(producer_result, '$.problem.type')) > 0
507
+ AND json_type(producer_result, '$.problem.title') IS 'text'
508
+ AND length(json_extract(producer_result, '$.problem.title')) > 0
509
+ AND json_type(producer_result, '$.problem.detail') IS 'text'
510
+ AND length(json_extract(producer_result, '$.problem.detail')) > 0
511
+ END
512
+ END
513
+ ),
412
514
  PRIMARY KEY (entry_id, name),
413
515
  FOREIGN KEY (entry_id) REFERENCES entries(id) ON DELETE CASCADE
414
516
  ) STRICT, WITHOUT ROWID;
@@ -525,14 +627,13 @@ CREATE TABLE IF NOT EXISTS log_entries (
525
627
  -- 'error' is an ACTIONLESS row ({§operation-results} — errors are log items): a parse failure that
526
628
  -- produced no op still records a log entry (op='error', status_rx≥400, no target) so the model
527
629
  -- can fold/kill/recall its own mistakes like any other log row — one budget surface, the log.
528
- -- 'model' is an ACTIONLESS row too ({§model-entry}): the model's own verbatim emission, mirrored
529
- -- back as a foldable log item so it can finally SEE its prior output (born folded; the turn-0
530
- -- exemplar is born open). text/vnd.plurnk-typed; OPEN/FOLD/KILL-able like any row.
630
+ -- A model-emission artifact ({§model-entry}) carries NULL here and
631
+ -- attrs.kind='model_emission': no operation was executed or fabricated.
531
632
  -- No op enum here: the grammar op set is grammar's contract (PlurnkOp), and this column is written
532
- -- only by the PlurnkOp-typed engine (grammar ops) or with the two service markers ('error','model').
633
+ -- only by the PlurnkOp-typed engine (grammar ops), service row selectors, or NULL for no op.
533
634
  -- A SQL enum would be a hand-copy of grammar's op list that silently goes stale on every new verb
534
635
  -- (it did — FORK/WORK). Validity lives at the parse + type layer, not duplicated in DDL.
535
- op TEXT NOT NULL,
636
+ op TEXT,
536
637
  suffix TEXT NOT NULL DEFAULT '',
537
638
  signal TEXT CHECK (signal IS NULL OR json_valid(signal)),
538
639
 
@@ -564,6 +665,8 @@ CREATE TABLE IF NOT EXISTS log_entries (
564
665
 
565
666
  expanded INTEGER NOT NULL DEFAULT 1 CHECK (expanded IN (0, 1)),
566
667
 
668
+ CHECK ((op IS NULL) = COALESCE(json_extract(attrs, '$.kind') = 'model_emission', 0)),
669
+
567
670
  FOREIGN KEY (worker_id) REFERENCES workers(id) ON DELETE CASCADE,
568
671
  FOREIGN KEY (loop_id) REFERENCES loops(id) ON DELETE CASCADE,
569
672
  FOREIGN KEY (turn_id) REFERENCES turns(id) ON DELETE CASCADE
@@ -667,6 +770,18 @@ BEGIN
667
770
  UPDATE log_entries SET ambient_event_id = last_insert_rowid() WHERE id = NEW.id;
668
771
  END;
669
772
 
773
+ -- One loop's cost is the complete sum of its provider attempts. One unknown
774
+ -- contributing turn makes the aggregate unknown rather than silently zero.
775
+ CREATE VIEW IF NOT EXISTS loop_costs AS
776
+ SELECT l.id, l.worker_id,
777
+ CASE
778
+ WHEN COUNT(t.id) FILTER (WHERE t.usage_cost_usd IS NULL) > 0 THEN NULL
779
+ ELSE COALESCE(SUM(t.usage_cost_usd), 0)
780
+ END AS cost_usd
781
+ FROM loops l
782
+ LEFT JOIN turns t ON t.loop_id = l.id
783
+ GROUP BY l.id;
784
+
670
785
  -- cost_rollups
671
786
  -- Triggers maintaining denormalized USD totals on workers and workspaces
672
787
  -- as turns insert/update. Pure denormalization (textbook trigger use);
@@ -676,10 +791,10 @@ AFTER INSERT ON turns
676
791
  BEGIN
677
792
  UPDATE workers
678
793
  SET cost_usd = (
679
- SELECT CASE WHEN COUNT(*) FILTER (WHERE t.usage_cost_usd IS NULL) > 0
680
- THEN NULL ELSE COALESCE(SUM(t.usage_cost_usd), 0) END
681
- FROM turns t JOIN loops l ON l.id = t.loop_id
682
- WHERE l.worker_id = workers.id
794
+ SELECT CASE WHEN COUNT(*) FILTER (WHERE lc.cost_usd IS NULL) > 0
795
+ THEN NULL ELSE COALESCE(SUM(lc.cost_usd), 0) END
796
+ FROM loop_costs lc
797
+ WHERE lc.worker_id = workers.id
683
798
  )
684
799
  WHERE id = (SELECT worker_id FROM loops WHERE id = NEW.loop_id);
685
800
  END;
@@ -689,11 +804,10 @@ AFTER INSERT ON turns
689
804
  BEGIN
690
805
  UPDATE workspaces
691
806
  SET cost_usd = (
692
- SELECT CASE WHEN COUNT(*) FILTER (WHERE t.usage_cost_usd IS NULL) > 0
693
- THEN NULL ELSE COALESCE(SUM(t.usage_cost_usd), 0) END
694
- FROM turns t
695
- JOIN loops l ON l.id = t.loop_id
696
- JOIN workers r ON r.id = l.worker_id
807
+ SELECT CASE WHEN COUNT(*) FILTER (WHERE lc.cost_usd IS NULL) > 0
808
+ THEN NULL ELSE COALESCE(SUM(lc.cost_usd), 0) END
809
+ FROM loop_costs lc
810
+ JOIN workers r ON r.id = lc.worker_id
697
811
  WHERE r.workspace_id = workspaces.id
698
812
  )
699
813
  WHERE id = (
@@ -710,10 +824,10 @@ WHEN NEW.usage_cost_usd IS NOT OLD.usage_cost_usd
710
824
  BEGIN
711
825
  UPDATE workers
712
826
  SET cost_usd = (
713
- SELECT CASE WHEN COUNT(*) FILTER (WHERE t.usage_cost_usd IS NULL) > 0
714
- THEN NULL ELSE COALESCE(SUM(t.usage_cost_usd), 0) END
715
- FROM turns t JOIN loops l ON l.id = t.loop_id
716
- WHERE l.worker_id = workers.id
827
+ SELECT CASE WHEN COUNT(*) FILTER (WHERE lc.cost_usd IS NULL) > 0
828
+ THEN NULL ELSE COALESCE(SUM(lc.cost_usd), 0) END
829
+ FROM loop_costs lc
830
+ WHERE lc.worker_id = workers.id
717
831
  )
718
832
  WHERE id = (SELECT worker_id FROM loops WHERE id = NEW.loop_id);
719
833
  END;
@@ -724,11 +838,10 @@ WHEN NEW.usage_cost_usd IS NOT OLD.usage_cost_usd
724
838
  BEGIN
725
839
  UPDATE workspaces
726
840
  SET cost_usd = (
727
- SELECT CASE WHEN COUNT(*) FILTER (WHERE t.usage_cost_usd IS NULL) > 0
728
- THEN NULL ELSE COALESCE(SUM(t.usage_cost_usd), 0) END
729
- FROM turns t
730
- JOIN loops l ON l.id = t.loop_id
731
- JOIN workers r ON r.id = l.worker_id
841
+ SELECT CASE WHEN COUNT(*) FILTER (WHERE lc.cost_usd IS NULL) > 0
842
+ THEN NULL ELSE COALESCE(SUM(lc.cost_usd), 0) END
843
+ FROM loop_costs lc
844
+ JOIN workers r ON r.id = lc.worker_id
732
845
  WHERE r.workspace_id = workspaces.id
733
846
  )
734
847
  WHERE id = (
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@plurnk/plurnk-service",
3
- "version": "1.4.0",
3
+ "version": "1.5.0",
4
4
  "description": "Plurnk agent runtime — the server / engine / core. Implements the @plurnk/plurnk-contracts contract.",
5
5
  "type": "module",
6
6
  "license": "MIT",
@@ -37,22 +37,22 @@
37
37
  "scripts": {
38
38
  "start": "node --conditions=plurnk-dev src/service.ts",
39
39
  "types:sqlrite": "node scripts/sqlrite-types.mjs --write",
40
- "test:sqlrite-types": "node scripts/sqlrite-types.mjs",
41
- "test:artifacts:begin": "node ../scripts/test-artifacts.mjs begin",
42
- "pretest:intg": "npm run test:artifacts:begin",
43
- "test:lint": "npm run test:sqlrite-types && tsc --noEmit && tsc --noEmit -p tsconfig.test.json",
44
- "test:unit": "node --conditions=plurnk-dev --import=./test/setup.ts --env-file-if-exists=.env.defaults --test --test-timeout=30000 src/**/*.test.ts",
40
+ "types:sqlrite:check": "node scripts/sqlrite-types.mjs",
41
+ "artifacts:begin": "node ../scripts/test-artifacts.mjs begin",
42
+ "pretest:intg": "npm run artifacts:begin",
43
+ "test:lint": "npm run types:sqlrite:check && tsc --noEmit && tsc --noEmit -p tsconfig.test.json",
44
+ "test:unit": "node --conditions=plurnk-dev --import=./test/setup.ts --env-file-if-exists=.env.defaults --test --test-timeout=30000 scripts/*.test.mjs src/**/*.test.ts",
45
45
  "test:intg": "PLURNK_SERVICE_FILES_ITEMS=0 node --conditions=plurnk-dev --import=./test/setup.ts --env-file-if-exists=.env.defaults --test --test-concurrency=8 --test-timeout=30000 test/intg/*.test.ts",
46
- "test:live": "PLURNK_SERVICE_POLICY=../plurnk-meta/PLURNK_PERSONALITY.md node --conditions=plurnk-dev --import=./test/floor.ts --env-file-if-exists=.env.defaults --env-file-if-exists=$HOME/.plurnk/.env --env-file-if-exists=.env --env-file-if-exists=.env.test --test --test-concurrency=1 test/live/*.test.ts",
47
- "test:live:specimen": "node --conditions=plurnk-dev bin/live-specimen.ts",
48
- "test:live:zeropin": "PLURNK_ZERO_PIN=1 PLURNK_SERVICE_POLICY=../plurnk-meta/PLURNK_PERSONALITY.md node --conditions=plurnk-dev --import=./test/floor.ts --env-file-if-exists=.env.defaults --env-file-if-exists=$HOME/.plurnk/.env --env-file-if-exists=.env --env-file-if-exists=.env.test --test --test-concurrency=1 test/live/*.test.ts",
49
- "test:demo": "PLURNK_SERVICE_POLICY=../plurnk-meta/PLURNK_PERSONALITY.md node --conditions=plurnk-dev --import=./test/floor.ts --env-file-if-exists=.env.defaults --env-file-if-exists=$HOME/.plurnk/.env --env-file-if-exists=.env --env-file-if-exists=.env.test --test --test-concurrency=1 test/demo/*.test.ts",
50
- "test:demo:zeropin": "PLURNK_ZERO_PIN=1 PLURNK_SERVICE_POLICY=../plurnk-meta/PLURNK_PERSONALITY.md node --conditions=plurnk-dev --import=./test/floor.ts --env-file-if-exists=.env.defaults --env-file-if-exists=$HOME/.plurnk/.env --env-file-if-exists=.env --env-file-if-exists=.env.test --test --test-concurrency=1 test/demo/*.test.ts",
46
+ "test:live": "bash ../scripts/operator-environment.sh node --conditions=plurnk-dev scripts/live.mjs",
47
+ "test:live:specimen": "bash ../scripts/operator-environment.sh node --conditions=plurnk-dev scripts/live.mjs --specimen",
48
+ "test:live:zeropin": "PLURNK_ZERO_PIN=1 npm run test:live",
49
+ "test:demo": "bash ../scripts/operator-environment.sh env PLURNK_SERVICE_POLICY=../plurnk-meta/PLURNK_PERSONALITY.md node --conditions=plurnk-dev --import=./test/floor.ts --env-file-if-exists=.env.defaults --env-file-if-exists=$HOME/.plurnk/.env --env-file-if-exists=.env --env-file-if-exists=.env.test --test --test-concurrency=1 test/demo/*.test.ts",
50
+ "test:demo:zeropin": "bash ../scripts/operator-environment.sh env PLURNK_ZERO_PIN=1 PLURNK_SERVICE_POLICY=../plurnk-meta/PLURNK_PERSONALITY.md node --conditions=plurnk-dev --import=./test/floor.ts --env-file-if-exists=.env.defaults --env-file-if-exists=$HOME/.plurnk/.env --env-file-if-exists=.env --env-file-if-exists=.env.test --test --test-concurrency=1 test/demo/*.test.ts",
51
+ "test:benchlet": "node scripts/benchlet.mjs",
51
52
  "fixture:demo": "node --conditions=plurnk-dev test/demo/_fixture.ts",
52
- "test:all": "npm run test:lint && npm run test:unit && npm run test:intg && npm run test:demo",
53
- "test:digest": "node --conditions=plurnk-dev bin/digest.ts",
53
+ "test": "npm run test:lint && npm run test:unit && npm run test:intg",
54
54
  "digest:missing": "node --conditions=plurnk-dev bin/digest-missing.ts",
55
- "test:clean-tmp": "node ../scripts/test-artifacts.mjs clean",
55
+ "artifacts:clean": "node ../scripts/test-artifacts.mjs clean",
56
56
  "dev:digest": "node --conditions=plurnk-dev bin/digest.ts",
57
57
  "build:clean": "rm -rf dist",
58
58
  "build:dist": "tsc -p tsconfig.build.json",
@@ -65,6 +65,7 @@
65
65
  "build:local:uninstall": "node --conditions=plurnk-dev scripts/install-sandbox.mjs uninstall",
66
66
  "test:installation": "node --conditions=plurnk-dev scripts/test-installation.mjs",
67
67
  "deps:audit": "node --conditions=plurnk-dev scripts/deps-audit.ts",
68
+ "release:check": "npm run deps:audit && npm run test:installation",
68
69
  "prepublishOnly": "npm run deps:audit && npm run test:installation",
69
70
  "prepack": "npm run build"
70
71
  },
@@ -76,41 +77,42 @@
76
77
  "@opentelemetry/resources": "^2.10.0",
77
78
  "@opentelemetry/sdk-metrics": "^2.10.0",
78
79
  "@opentelemetry/sdk-trace-base": "^2.10.0",
79
- "@plurnk/gbnf": "1.4.0",
80
- "@plurnk/plurnk-agui": "1.4.0",
81
- "@plurnk/plurnk-contracts": "1.4.0",
82
- "@plurnk/plurnk-execs": "1.4.0",
83
- "@plurnk/plurnk-execs-common": "1.4.0",
84
- "@plurnk/plurnk-execs-git": "1.4.0",
85
- "@plurnk/plurnk-execs-jq": "1.4.0",
86
- "@plurnk/plurnk-execs-search": "1.4.0",
87
- "@plurnk/plurnk-execs-sqlite": "1.4.0",
88
- "@plurnk/plurnk-execs-wasm": "1.4.0",
89
- "@plurnk/plurnk-mcp": "1.4.0",
90
- "@plurnk/plurnk-meta": "1.4.0",
91
- "@plurnk/plurnk-mimetypes": "1.4.0",
92
- "@plurnk/plurnk-mimetypes-application-ipynb": "1.4.0",
93
- "@plurnk/plurnk-mimetypes-application-json": "1.4.0",
94
- "@plurnk/plurnk-mimetypes-application-jsonl": "1.4.0",
95
- "@plurnk/plurnk-mimetypes-application-pdf": "1.4.0",
96
- "@plurnk/plurnk-mimetypes-application-xml": "1.4.0",
97
- "@plurnk/plurnk-mimetypes-embeddings": "1.4.0",
98
- "@plurnk/plurnk-mimetypes-text-csv": "1.4.0",
99
- "@plurnk/plurnk-mimetypes-text-diff": "1.4.0",
100
- "@plurnk/plurnk-mimetypes-text-dotenv": "1.4.0",
101
- "@plurnk/plurnk-mimetypes-text-html": "1.4.0",
102
- "@plurnk/plurnk-mimetypes-text-ini": "1.4.0",
103
- "@plurnk/plurnk-mimetypes-text-markdown": "1.4.0",
104
- "@plurnk/plurnk-mimetypes-text-plain": "1.4.0",
105
- "@plurnk/plurnk-mimetypes-tokenizers": "1.4.0",
106
- "@plurnk/plurnk-models": "1.4.0",
107
- "@plurnk/plurnk-providers": "1.4.0",
108
- "@plurnk/plurnk-schemes": "1.4.0",
109
- "@plurnk/plurnk-schemes-http": "1.4.0",
80
+ "@plurnk/gbnf": "1.5.0",
81
+ "@plurnk/plurnk-agui": "1.5.0",
82
+ "@plurnk/plurnk-contracts": "1.5.0",
83
+ "@plurnk/plurnk-execs": "1.5.0",
84
+ "@plurnk/plurnk-execs-common": "1.5.0",
85
+ "@plurnk/plurnk-execs-git": "1.5.0",
86
+ "@plurnk/plurnk-execs-jq": "1.5.0",
87
+ "@plurnk/plurnk-execs-search": "1.5.0",
88
+ "@plurnk/plurnk-execs-sqlite": "1.5.0",
89
+ "@plurnk/plurnk-execs-wasm": "1.5.0",
90
+ "@plurnk/plurnk-hooks": "1.5.0",
91
+ "@plurnk/plurnk-mcp": "1.5.0",
92
+ "@plurnk/plurnk-meta": "1.5.0",
93
+ "@plurnk/plurnk-mimetypes": "1.5.0",
94
+ "@plurnk/plurnk-mimetypes-application-ipynb": "1.5.0",
95
+ "@plurnk/plurnk-mimetypes-application-json": "1.5.0",
96
+ "@plurnk/plurnk-mimetypes-application-jsonl": "1.5.0",
97
+ "@plurnk/plurnk-mimetypes-application-pdf": "1.5.0",
98
+ "@plurnk/plurnk-mimetypes-application-xml": "1.5.0",
99
+ "@plurnk/plurnk-mimetypes-embeddings": "1.5.0",
100
+ "@plurnk/plurnk-mimetypes-text-csv": "1.5.0",
101
+ "@plurnk/plurnk-mimetypes-text-diff": "1.5.0",
102
+ "@plurnk/plurnk-mimetypes-text-dotenv": "1.5.0",
103
+ "@plurnk/plurnk-mimetypes-text-html": "1.5.0",
104
+ "@plurnk/plurnk-mimetypes-text-ini": "1.5.0",
105
+ "@plurnk/plurnk-mimetypes-text-markdown": "1.5.0",
106
+ "@plurnk/plurnk-mimetypes-text-plain": "1.5.0",
107
+ "@plurnk/plurnk-mimetypes-tokenizers": "1.5.0",
108
+ "@plurnk/plurnk-models": "1.5.0",
109
+ "@plurnk/plurnk-providers": "1.5.0",
110
+ "@plurnk/plurnk-schemes": "1.5.0",
111
+ "@plurnk/plurnk-schemes-http": "1.5.0",
110
112
  "@possumtech/sqlrite": "^6.5.2",
111
113
  "diff": "^9.0.0",
112
114
  "ignore": "7.0.6",
113
- "isomorphic-git": "1.40.0"
115
+ "isomorphic-git": "1.41.3"
114
116
  },
115
117
  "devDependencies": {
116
118
  "@opentelemetry/core": "^2.10.0",
@@ -1,9 +0,0 @@
1
- declare const LIVE_ENV: {
2
- readonly PLURNK_SERVICE_POLICY: "../plurnk-meta/PLURNK_PERSONALITY.md";
3
- };
4
- export declare const liveSpecimenInvocation: (pattern: string) => {
5
- args: string[];
6
- env: typeof LIVE_ENV;
7
- };
8
- export {};
9
- //# sourceMappingURL=live-specimen.d.ts.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"live-specimen.d.ts","sourceRoot":"","sources":["../../src/matrix/live-specimen.ts"],"names":[],"mappings":"AAUA,QAAA,MAAM,QAAQ;aACV,qBAAqB,EAAE,sCAAsC;CACvD,CAAC;AAKX,eAAO,MAAM,sBAAsB,YAAa,MAAM,KAAG;IAAE,IAAI,EAAE,MAAM,EAAE,CAAC;IAAC,GAAG,EAAE,OAAO,QAAQ,CAAA;CAoB9F,CAAC"}