@plurnk/plurnk-service 1.14.2 → 1.16.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 (308) hide show
  1. package/.env.defaults +2 -2
  2. package/SPEC.md +243 -173
  3. package/digest-sql/curation/curation.sql +1 -1
  4. package/dist/build-info.json +1 -1
  5. package/dist/content/byte-view.d.ts +14 -0
  6. package/dist/content/byte-view.d.ts.map +1 -0
  7. package/dist/content/byte-view.js +33 -0
  8. package/dist/content/byte-view.js.map +1 -0
  9. package/dist/content/edit-receipt.d.ts.map +1 -1
  10. package/dist/content/edit-receipt.js +12 -1
  11. package/dist/content/edit-receipt.js.map +1 -1
  12. package/dist/content/line-marker.d.ts +2 -1
  13. package/dist/content/line-marker.d.ts.map +1 -1
  14. package/dist/content/line-marker.js +1 -0
  15. package/dist/content/line-marker.js.map +1 -1
  16. package/dist/content/matcher.d.ts +1 -0
  17. package/dist/content/matcher.d.ts.map +1 -1
  18. package/dist/content/matcher.js +1 -0
  19. package/dist/content/matcher.js.map +1 -1
  20. package/dist/content/read-projector.d.ts +4 -1
  21. package/dist/content/read-projector.d.ts.map +1 -1
  22. package/dist/content/read-projector.js +80 -3
  23. package/dist/content/read-projector.js.map +1 -1
  24. package/dist/core/AdmittedTurnExecutor.d.ts +43 -0
  25. package/dist/core/AdmittedTurnExecutor.d.ts.map +1 -0
  26. package/dist/core/AdmittedTurnExecutor.js +245 -0
  27. package/dist/core/AdmittedTurnExecutor.js.map +1 -0
  28. package/dist/core/BareBatchRunner.d.ts +26 -0
  29. package/dist/core/BareBatchRunner.d.ts.map +1 -0
  30. package/dist/core/BareBatchRunner.js +104 -0
  31. package/dist/core/BareBatchRunner.js.map +1 -0
  32. package/dist/core/BudgetReadout.d.ts +1 -1
  33. package/dist/core/BudgetReadout.d.ts.map +1 -1
  34. package/dist/core/BudgetReadout.js +42 -47
  35. package/dist/core/BudgetReadout.js.map +1 -1
  36. package/dist/core/CapabilityResolver.d.ts +2 -1
  37. package/dist/core/CapabilityResolver.d.ts.map +1 -1
  38. package/dist/core/CapabilityResolver.js +8 -9
  39. package/dist/core/CapabilityResolver.js.map +1 -1
  40. package/dist/core/ChannelWrite.d.ts +1 -1
  41. package/dist/core/ChannelWrite.d.ts.map +1 -1
  42. package/dist/core/DataStatementRunner.d.ts +35 -0
  43. package/dist/core/DataStatementRunner.d.ts.map +1 -0
  44. package/dist/core/DataStatementRunner.js +252 -0
  45. package/dist/core/DataStatementRunner.js.map +1 -0
  46. package/dist/core/Dispatcher.d.ts +8 -3
  47. package/dist/core/Dispatcher.d.ts.map +1 -1
  48. package/dist/core/Dispatcher.js +88 -738
  49. package/dist/core/Dispatcher.js.map +1 -1
  50. package/dist/core/EditMutations.d.ts +39 -0
  51. package/dist/core/EditMutations.d.ts.map +1 -0
  52. package/dist/core/EditMutations.js +418 -0
  53. package/dist/core/EditMutations.js.map +1 -0
  54. package/dist/core/Engine.d.ts +2 -23
  55. package/dist/core/Engine.d.ts.map +1 -1
  56. package/dist/core/Engine.js +18 -240
  57. package/dist/core/Engine.js.map +1 -1
  58. package/dist/core/Engine.sql +24 -23
  59. package/dist/core/KillHandler.d.ts +32 -0
  60. package/dist/core/KillHandler.d.ts.map +1 -0
  61. package/dist/core/KillHandler.js +179 -0
  62. package/dist/core/KillHandler.js.map +1 -0
  63. package/dist/core/LogVisibility.d.ts +1 -1
  64. package/dist/core/LogVisibility.d.ts.map +1 -1
  65. package/dist/core/LogVisibility.js +3 -4
  66. package/dist/core/LogVisibility.js.map +1 -1
  67. package/dist/core/LogWriter.d.ts +42 -0
  68. package/dist/core/LogWriter.d.ts.map +1 -0
  69. package/dist/core/LogWriter.js +136 -0
  70. package/dist/core/LogWriter.js.map +1 -0
  71. package/dist/core/LoopDriver.d.ts +46 -0
  72. package/dist/core/LoopDriver.d.ts.map +1 -0
  73. package/dist/core/LoopDriver.js +263 -0
  74. package/dist/core/LoopDriver.js.map +1 -0
  75. package/dist/core/LoopLifecycle.d.ts +2 -1
  76. package/dist/core/LoopLifecycle.d.ts.map +1 -1
  77. package/dist/core/MembershipMaterialization.d.ts +7 -0
  78. package/dist/core/MembershipMaterialization.d.ts.map +1 -0
  79. package/dist/core/MembershipMaterialization.js +283 -0
  80. package/dist/core/MembershipMaterialization.js.map +1 -0
  81. package/dist/core/MutationEffects.d.ts +29 -0
  82. package/dist/core/MutationEffects.d.ts.map +1 -0
  83. package/dist/core/MutationEffects.js +318 -0
  84. package/dist/core/MutationEffects.js.map +1 -0
  85. package/dist/core/OverflowTurn.d.ts +4 -4
  86. package/dist/core/OverflowTurn.d.ts.map +1 -1
  87. package/dist/core/OverflowTurn.js +6 -7
  88. package/dist/core/OverflowTurn.js.map +1 -1
  89. package/dist/core/PacketBuilder.d.ts.map +1 -1
  90. package/dist/core/PacketBuilder.js +31 -9
  91. package/dist/core/PacketBuilder.js.map +1 -1
  92. package/dist/core/ResourceMutations.d.ts +12 -36
  93. package/dist/core/ResourceMutations.d.ts.map +1 -1
  94. package/dist/core/ResourceMutations.js +27 -1351
  95. package/dist/core/ResourceMutations.js.map +1 -1
  96. package/dist/core/ResourceSelector.d.ts +21 -0
  97. package/dist/core/ResourceSelector.d.ts.map +1 -0
  98. package/dist/core/ResourceSelector.js +233 -0
  99. package/dist/core/ResourceSelector.js.map +1 -0
  100. package/dist/core/ResourceTransfers.d.ts +55 -0
  101. package/dist/core/ResourceTransfers.d.ts.map +1 -0
  102. package/dist/core/ResourceTransfers.js +525 -0
  103. package/dist/core/ResourceTransfers.js.map +1 -0
  104. package/dist/core/SchemeRegistry.js +2 -2
  105. package/dist/core/SchemeRegistry.js.map +1 -1
  106. package/dist/core/SendBroadcastHandler.d.ts +40 -0
  107. package/dist/core/SendBroadcastHandler.d.ts.map +1 -0
  108. package/dist/core/SendBroadcastHandler.js +159 -0
  109. package/dist/core/SendBroadcastHandler.js.map +1 -0
  110. package/dist/core/StoredPacket.d.ts +11 -0
  111. package/dist/core/StoredPacket.d.ts.map +1 -1
  112. package/dist/core/StoredPacket.js +22 -1
  113. package/dist/core/StoredPacket.js.map +1 -1
  114. package/dist/core/StrikeRail.d.ts.map +1 -1
  115. package/dist/core/StrikeRail.js +19 -9
  116. package/dist/core/StrikeRail.js.map +1 -1
  117. package/dist/core/TokenCalibration.d.ts +16 -0
  118. package/dist/core/TokenCalibration.d.ts.map +1 -0
  119. package/dist/core/TokenCalibration.js +35 -0
  120. package/dist/core/TokenCalibration.js.map +1 -0
  121. package/dist/core/ToolResources.d.ts.map +1 -1
  122. package/dist/core/ToolResources.js +15 -12
  123. package/dist/core/ToolResources.js.map +1 -1
  124. package/dist/core/TurnMaterialization.d.ts +37 -0
  125. package/dist/core/TurnMaterialization.d.ts.map +1 -0
  126. package/dist/core/TurnMaterialization.js +296 -0
  127. package/dist/core/TurnMaterialization.js.map +1 -0
  128. package/dist/core/TurnOps.d.ts.map +1 -1
  129. package/dist/core/TurnOps.js +6 -8
  130. package/dist/core/TurnOps.js.map +1 -1
  131. package/dist/core/TurnRunner.d.ts +15 -27
  132. package/dist/core/TurnRunner.d.ts.map +1 -1
  133. package/dist/core/TurnRunner.js +76 -670
  134. package/dist/core/TurnRunner.js.map +1 -1
  135. package/dist/core/WorkerControlHandler.d.ts +15 -0
  136. package/dist/core/WorkerControlHandler.d.ts.map +1 -0
  137. package/dist/core/WorkerControlHandler.js +89 -0
  138. package/dist/core/WorkerControlHandler.js.map +1 -0
  139. package/dist/core/attachments.d.ts +14 -0
  140. package/dist/core/attachments.d.ts.map +1 -0
  141. package/dist/core/attachments.js +18 -0
  142. package/dist/core/attachments.js.map +1 -0
  143. package/dist/core/fork.d.ts.map +1 -1
  144. package/dist/core/fork.js +0 -4
  145. package/dist/core/fork.js.map +1 -1
  146. package/dist/core/fork.sql +5 -16
  147. package/dist/core/git-membership.d.ts +15 -0
  148. package/dist/core/git-membership.d.ts.map +1 -1
  149. package/dist/core/git-membership.js +4 -273
  150. package/dist/core/git-membership.js.map +1 -1
  151. package/dist/core/git-state.d.ts +2 -1
  152. package/dist/core/git-state.d.ts.map +1 -1
  153. package/dist/core/mutation-types.d.ts +102 -0
  154. package/dist/core/mutation-types.d.ts.map +1 -0
  155. package/dist/core/mutation-types.js +2 -0
  156. package/dist/core/mutation-types.js.map +1 -0
  157. package/dist/core/operation-target-groups.js +1 -1
  158. package/dist/core/operation-target-groups.js.map +1 -1
  159. package/dist/core/packet-wire.d.ts +7 -6
  160. package/dist/core/packet-wire.d.ts.map +1 -1
  161. package/dist/core/packet-wire.js +96 -68
  162. package/dist/core/packet-wire.js.map +1 -1
  163. package/dist/core/plurnk-uri.d.ts +0 -1
  164. package/dist/core/plurnk-uri.d.ts.map +1 -1
  165. package/dist/core/plurnk-uri.js +1 -1
  166. package/dist/core/plurnk-uri.js.map +1 -1
  167. package/dist/core/statement-primary.d.ts +4 -0
  168. package/dist/core/statement-primary.d.ts.map +1 -0
  169. package/dist/core/statement-primary.js +3 -0
  170. package/dist/core/statement-primary.js.map +1 -0
  171. package/dist/core/teaching-corpus.d.ts +0 -1
  172. package/dist/core/teaching-corpus.d.ts.map +1 -1
  173. package/dist/core/teaching-corpus.js +0 -9
  174. package/dist/core/teaching-corpus.js.map +1 -1
  175. package/dist/core/turn-scheduler.js +3 -3
  176. package/dist/core/turn-scheduler.js.map +1 -1
  177. package/dist/core/turn-signals.d.ts +15 -0
  178. package/dist/core/turn-signals.d.ts.map +1 -0
  179. package/dist/core/turn-signals.js +19 -0
  180. package/dist/core/turn-signals.js.map +1 -0
  181. package/dist/core/worker-settings.d.ts +0 -1
  182. package/dist/core/worker-settings.d.ts.map +1 -1
  183. package/dist/core/worker-settings.js +1 -1
  184. package/dist/core/worker-settings.js.map +1 -1
  185. package/dist/digest/Digest.d.ts +3 -16
  186. package/dist/digest/Digest.d.ts.map +1 -1
  187. package/dist/digest/Digest.js +10 -958
  188. package/dist/digest/Digest.js.map +1 -1
  189. package/dist/digest/DigestRender.d.ts +12 -0
  190. package/dist/digest/DigestRender.d.ts.map +1 -0
  191. package/dist/digest/DigestRender.js +641 -0
  192. package/dist/digest/DigestRender.js.map +1 -0
  193. package/dist/digest/DigestRequiem.d.ts +13 -0
  194. package/dist/digest/DigestRequiem.d.ts.map +1 -0
  195. package/dist/digest/DigestRequiem.js +332 -0
  196. package/dist/digest/DigestRequiem.js.map +1 -0
  197. package/dist/digest/digest-rows.d.ts +303 -0
  198. package/dist/digest/digest-rows.d.ts.map +1 -0
  199. package/dist/digest/digest-rows.js +2 -0
  200. package/dist/digest/digest-rows.js.map +1 -0
  201. package/dist/digest/digest.sql +1 -7
  202. package/dist/observe/api.d.ts +0 -2
  203. package/dist/observe/api.d.ts.map +1 -1
  204. package/dist/observe/api.js +2 -2
  205. package/dist/observe/api.js.map +1 -1
  206. package/dist/observe/metrics.d.ts +0 -1
  207. package/dist/observe/metrics.d.ts.map +1 -1
  208. package/dist/observe/metrics.js +0 -1
  209. package/dist/observe/metrics.js.map +1 -1
  210. package/dist/schemes/Exec.d.ts +4 -1
  211. package/dist/schemes/Exec.d.ts.map +1 -1
  212. package/dist/schemes/Exec.js +89 -48
  213. package/dist/schemes/Exec.js.map +1 -1
  214. package/dist/schemes/ExecOutputScheme.d.ts +2 -1
  215. package/dist/schemes/ExecOutputScheme.d.ts.map +1 -1
  216. package/dist/schemes/ExecOutputScheme.js +3 -3
  217. package/dist/schemes/ExecOutputScheme.js.map +1 -1
  218. package/dist/schemes/File.d.ts +4 -1
  219. package/dist/schemes/File.d.ts.map +1 -1
  220. package/dist/schemes/File.js +100 -13
  221. package/dist/schemes/File.js.map +1 -1
  222. package/dist/schemes/Log.d.ts +4 -5
  223. package/dist/schemes/Log.d.ts.map +1 -1
  224. package/dist/schemes/Log.js +26 -118
  225. package/dist/schemes/Log.js.map +1 -1
  226. package/dist/schemes/Log.sql +1 -66
  227. package/dist/schemes/Prompt.js +1 -1
  228. package/dist/schemes/Prompt.js.map +1 -1
  229. package/dist/schemes/Worker.d.ts.map +1 -1
  230. package/dist/schemes/Worker.js +1 -13
  231. package/dist/schemes/Worker.js.map +1 -1
  232. package/dist/schemes/_entry-crud.d.ts +3 -1
  233. package/dist/schemes/_entry-crud.d.ts.map +1 -1
  234. package/dist/schemes/_entry-crud.js +18 -3
  235. package/dist/schemes/_entry-crud.js.map +1 -1
  236. package/dist/schemes/_entry-find.d.ts +4 -2
  237. package/dist/schemes/_entry-find.d.ts.map +1 -1
  238. package/dist/schemes/_entry-find.js +79 -10
  239. package/dist/schemes/_entry-find.js.map +1 -1
  240. package/dist/schemes/_entry-manifest.d.ts +1 -2
  241. package/dist/schemes/_entry-manifest.d.ts.map +1 -1
  242. package/dist/schemes/_entry-ops.d.ts +2 -1
  243. package/dist/schemes/_entry-ops.d.ts.map +1 -1
  244. package/dist/schemes/_entry-ops.js +20 -2
  245. package/dist/schemes/_entry-ops.js.map +1 -1
  246. package/dist/schemes/_entry-semantic.d.ts +1 -0
  247. package/dist/schemes/_entry-semantic.d.ts.map +1 -1
  248. package/dist/schemes/_entry-semantic.js +3 -0
  249. package/dist/schemes/_entry-semantic.js.map +1 -1
  250. package/dist/schemes/_entry-semantic.sql +2 -2
  251. package/dist/schemes/_entry-send.d.ts +0 -1
  252. package/dist/schemes/_entry-send.d.ts.map +1 -1
  253. package/dist/schemes/_entry-send.js +5 -80
  254. package/dist/schemes/_entry-send.js.map +1 -1
  255. package/dist/schemes/exec-runtime.d.ts +7 -0
  256. package/dist/schemes/exec-runtime.d.ts.map +1 -0
  257. package/dist/schemes/exec-runtime.js +2 -0
  258. package/dist/schemes/exec-runtime.js.map +1 -0
  259. package/dist/server/ClientReads.d.ts +34 -0
  260. package/dist/server/ClientReads.d.ts.map +1 -0
  261. package/dist/server/ClientReads.js +210 -0
  262. package/dist/server/ClientReads.js.map +1 -0
  263. package/dist/server/Daemon.d.ts +12 -22
  264. package/dist/server/Daemon.d.ts.map +1 -1
  265. package/dist/server/Daemon.js +31 -362
  266. package/dist/server/Daemon.js.map +1 -1
  267. package/dist/server/DaemonModule.d.ts +6 -5
  268. package/dist/server/DaemonModule.d.ts.map +1 -1
  269. package/dist/server/DrainSupervisor.d.ts +3 -2
  270. package/dist/server/DrainSupervisor.d.ts.map +1 -1
  271. package/dist/server/DrainSupervisor.js +7 -3
  272. package/dist/server/DrainSupervisor.js.map +1 -1
  273. package/dist/server/Functionality.d.ts +0 -12
  274. package/dist/server/Functionality.d.ts.map +1 -1
  275. package/dist/server/Functionality.js.map +1 -1
  276. package/dist/server/FunctionalityManager.d.ts +0 -1
  277. package/dist/server/FunctionalityManager.d.ts.map +1 -1
  278. package/dist/server/FunctionalityManager.js +3 -3
  279. package/dist/server/FunctionalityManager.js.map +1 -1
  280. package/dist/server/MembersFunctionality.d.ts +2 -13
  281. package/dist/server/MembersFunctionality.d.ts.map +1 -1
  282. package/dist/server/MembersFunctionality.js +4 -4
  283. package/dist/server/MembersFunctionality.js.map +1 -1
  284. package/dist/server/SkillsFunctionality.d.ts +1 -7
  285. package/dist/server/SkillsFunctionality.d.ts.map +1 -1
  286. package/dist/server/SkillsFunctionality.js +3 -3
  287. package/dist/server/SkillsFunctionality.js.map +1 -1
  288. package/dist/server/WorkerModelResolver.d.ts +17 -0
  289. package/dist/server/WorkerModelResolver.d.ts.map +1 -0
  290. package/dist/server/WorkerModelResolver.js +166 -0
  291. package/dist/server/WorkerModelResolver.js.map +1 -0
  292. package/dist/server/daemon-results.d.ts +5 -0
  293. package/dist/server/daemon-results.d.ts.map +1 -0
  294. package/dist/server/daemon-results.js +7 -0
  295. package/dist/server/daemon-results.js.map +1 -0
  296. package/dist/server/dispatch-as-plurnk.d.ts.map +1 -1
  297. package/dist/server/dispatch-as-plurnk.js +4 -6
  298. package/dist/server/dispatch-as-plurnk.js.map +1 -1
  299. package/dist/server/logEntry.d.ts +0 -1
  300. package/dist/server/logEntry.d.ts.map +1 -1
  301. package/dist/server/logEntry.js +1 -13
  302. package/dist/server/logEntry.js.map +1 -1
  303. package/dist/server/logEntry.sql +1 -5
  304. package/dist/server/loopDocs.d.ts.map +1 -1
  305. package/dist/server/loopDocs.js +11 -2
  306. package/dist/server/loopDocs.js.map +1 -1
  307. package/migrations/001_schema.sql +30 -347
  308. package/package.json +30 -30
@@ -0,0 +1,263 @@
1
+ import { setTimeout as delay } from "node:timers/promises";
2
+ import Results from "./results.js";
3
+ import { LOOP_TIMEOUT_REASON } from "./TurnRunner.js";
4
+ import { observed } from "../observe/spans.js";
5
+ const readMaxStrikes = () => {
6
+ const raw = process.env.PLURNK_SERVICE_MAX_STRIKES;
7
+ if (raw === undefined || raw.length === 0)
8
+ return DEFAULT_MAX_STRIKES;
9
+ const n = Number.parseInt(raw, 10);
10
+ if (!Number.isFinite(n) || n < 0)
11
+ return DEFAULT_MAX_STRIKES;
12
+ return n;
13
+ };
14
+ const DEFAULT_MIN_CYCLES = 3;
15
+ const DEFAULT_MAX_CYCLE_PERIOD = 4;
16
+ const readPositiveInt = (envVar, fallback) => {
17
+ const raw = process.env[envVar];
18
+ if (raw === undefined || raw.length === 0)
19
+ return fallback;
20
+ const n = Number.parseInt(raw, 10);
21
+ if (!Number.isFinite(n) || n < 1)
22
+ return fallback;
23
+ return n;
24
+ };
25
+ const readLoopTimeoutMs = () => readPositiveInt("PLURNK_SERVICE_LOOP_TIMEOUT", DEFAULT_LOOP_TIMEOUT_MS);
26
+ const DEFAULT_MAX_STRIKES = 3;
27
+ // {§operator-config-loop-timeout} — the loop's wall-clock budget (PLURNK_SERVICE_LOOP_TIMEOUT).
28
+ const DEFAULT_LOOP_TIMEOUT_MS = 86400000;
29
+ export default class LoopDriver {
30
+ #loopAborts;
31
+ #db;
32
+ #lifecycle;
33
+ #schemes;
34
+ #notices;
35
+ #strikes;
36
+ #acquireWorkspaceTurn;
37
+ #workspaceTurnStarting;
38
+ #runTurn;
39
+ constructor({ loopAborts, db, lifecycle, schemes, notices, strikes, acquireWorkspaceTurn, workspaceTurnStarting, runTurn }) {
40
+ this.#loopAborts = loopAborts;
41
+ this.#db = db;
42
+ this.#lifecycle = lifecycle;
43
+ this.#schemes = schemes;
44
+ this.#notices = notices;
45
+ this.#strikes = strikes;
46
+ this.#acquireWorkspaceTurn = acquireWorkspaceTurn;
47
+ this.#workspaceTurnStarting = workspaceTurnStarting;
48
+ this.#runTurn = runTurn;
49
+ }
50
+ async runLoop({ provider, childProvider = provider, messages, recap = "", workspaceId, workerId, loopId, maxTurns = 50, maxStrikes = readMaxStrikes(), minCycles = readPositiveInt("PLURNK_SERVICE_MIN_CYCLES", DEFAULT_MIN_CYCLES), maxCyclePeriod = readPositiveInt("PLURNK_SERVICE_MAX_CYCLE_PERIOD", DEFAULT_MAX_CYCLE_PERIOD), signal, onDispatch, onSettled }) {
51
+ // A 202 park suspends this durable loop and a later wake re-enters runLoop.
52
+ // Its ceiling therefore counts every prior turn, not merely this process-local
53
+ // execution segment.
54
+ const turnIds = await this.#lifecycle.turnIds(loopId);
55
+ let modelTurnCount = await this.#lifecycle.modelTurnCount(loopId);
56
+ let invalidEmissionRecoveryEntryId = null;
57
+ // Per-loop AbortController for scheme-side cancellation propagation.
58
+ // Chained from the caller's `signal` so an external abort cascades.
59
+ const loopAbort = new AbortController();
60
+ if (signal !== undefined) {
61
+ if (signal.aborted)
62
+ loopAbort.abort(signal.reason);
63
+ else
64
+ signal.addEventListener("abort", () => loopAbort.abort(signal.reason), { once: true });
65
+ }
66
+ this.#loopAborts.set(loopId, loopAbort);
67
+ // {§operator-config-loop-timeout} — the wall-clock budget. Expiry aborts the loop signal, so a
68
+ // mid-flight provider call (generate rides this signal) and in-flight spawns tear down; the
69
+ // loop terminates 504 (kin to the exec <T> reap's 504, {§exec-timeout}) — a legible engine
70
+ // terminal, never an outside kill. unref'd: the wall never holds the process open.
71
+ const wall = setTimeout(() => loopAbort.abort(LOOP_TIMEOUT_REASON), readLoopTimeoutMs());
72
+ wall.unref();
73
+ const timedOut = () => loopAbort.signal.aborted && loopAbort.signal.reason === LOOP_TIMEOUT_REASON;
74
+ const ruleTimeout = async () => {
75
+ const failure = Results.failure("engine:rails", "loop-timeout", 504, `The loop exceeded its wall-clock deadline after ${modelTurnCount} model turns.`, {}, {
76
+ turns: modelTurnCount,
77
+ stage: "loop",
78
+ retryable: false
79
+ });
80
+ const result = await this.#lifecycle.finish(loopId, failure);
81
+ if (result === null)
82
+ throw new Error(`loop ${loopId} became terminal before timeout settlement`);
83
+ cleanup("forceful", "loop_timeout");
84
+ return { turnIds, result, hitMaxTurns: false, reason: "loop_timeout" };
85
+ };
86
+ // Cleanup splits by termination kind:
87
+ // - "graceful" (SEND signal 202 Accepted): in-flight streaming-scheme spawns
88
+ // are ALLOWED to outlive the loop — they complete naturally, write final
89
+ // channel state, and wake-on-completion (E.4) opens a fresh loop. 202 is
90
+ // the only terminal that means "keep my async work."
91
+ // - "forceful" (SEND signal 200 done, max_turns, strike, cancel, context-envelope rejection, 4xx/5xx):
92
+ // fire the loop-level abort so leftover spawns tear down. "Done" reaps.
93
+ const cleanup = (kind, reason) => {
94
+ clearTimeout(wall);
95
+ if (kind === "forceful" && !loopAbort.signal.aborted) {
96
+ loopAbort.abort(reason ?? "loop_forceful_termination");
97
+ }
98
+ this.#loopAborts.delete(loopId);
99
+ this.#strikes.delete(loopId);
100
+ this.#notices.delete(loopId);
101
+ };
102
+ while (true) {
103
+ const row = await this.#db.engine_loop_status.get({ loop_id: loopId });
104
+ if (row === undefined)
105
+ throw new Error(`Engine.runLoop: loop ${loopId} not found`);
106
+ if (row.status === 100) {
107
+ // NOT a terminal — a wake re-queued this loop while its own live drain was
108
+ // between turns (a child concluded in the gap between our 202 write and this
109
+ // check, {§worker-lifecycle-wake-requeue-not-terminal}). The wake's intent is KEEP
110
+ // RUNNING: re-claim atomically and continue — the injected prompt is already
111
+ // this loop's next turn. Returning it as "external" broadcast a QUEUED loop
112
+ // as a terminal result with status 100 — the delegation-policy race.
113
+ await this.#db.engine_reclaim_queued_loop.run({ loop_id: loopId });
114
+ continue; // claimed (or a racer flipped it first — the re-read decides)
115
+ }
116
+ if (row.status !== 102) {
117
+ // Only 202 (Accepted) lets spawns outlive — it IS the async wake
118
+ // contract (E.4). Every other terminal, 200 included, reaps: "done"
119
+ // must not leak running execs. Trust the code's declared intent.
120
+ cleanup(row.status === 202 ? "graceful" : "forceful", `loop_terminal_${row.status}`);
121
+ if (row.status === 202) {
122
+ return { turnIds, result: { status: 202 }, hitMaxTurns: false, reason: "external" };
123
+ }
124
+ const result = await this.#lifecycle.result(loopId);
125
+ if (result === null) {
126
+ throw new Error(`terminal loop ${loopId} status ${row.status} has no operation result`);
127
+ }
128
+ return { turnIds, result, hitMaxTurns: false, reason: "external" };
129
+ }
130
+ // Durable disposition outranks a later process-local cancellation observation.
131
+ // SEND may commit 202 immediately before daemon shutdown aborts this drain; reading
132
+ // the abort first launders that lawful park into 499 under load. Only a still-running
133
+ // 102 loop can be cancelled or time out at this boundary.
134
+ if (timedOut())
135
+ return await ruleTimeout();
136
+ signal?.throwIfAborted();
137
+ if (maxTurns >= 0 && modelTurnCount >= maxTurns) {
138
+ const failure = Results.failure("engine:rails", "max-turns", 429, `The configured turn ceiling (${maxTurns}) is exhausted.`, {}, {
139
+ maximumTurns: maxTurns,
140
+ stage: "loop",
141
+ retryable: false
142
+ });
143
+ const result = await this.#lifecycle.finish(loopId, failure);
144
+ if (result === null)
145
+ throw new Error(`loop ${loopId} became terminal before max-turn settlement`);
146
+ cleanup("forceful", "max_turns");
147
+ return { turnIds, result, hitMaxTurns: true, reason: "max_turns" };
148
+ }
149
+ const execHandler = this.#schemes.get("exec");
150
+ // {§exec-hold-until-concluded} — hold matching runtime/effect
151
+ // streams until conclusion or the fail-open cap, then resume the
152
+ // ordinary cycle without altering stream state.
153
+ const holdSet = new Set((process.env.PLURNK_SERVICE_EXEC_HOLD ?? "").split(",").map((x) => x.trim()).filter((x) => x.length > 0));
154
+ const holdCapMs = Number(process.env.PLURNK_SERVICE_EXEC_HOLD_MS ?? "300000");
155
+ if (holdSet.size > 0 && holdCapMs > 0 && execHandler?.hasActiveHoldSpawns !== undefined) {
156
+ const holdStart = Date.now();
157
+ while (execHandler.hasActiveHoldSpawns(workerId, holdSet) && Date.now() - holdStart < holdCapMs) {
158
+ await delay(150, undefined, { signal });
159
+ }
160
+ }
161
+ let turn;
162
+ const releaseWorkspace = await this.#acquireWorkspaceTurn(workspaceId, workerId);
163
+ try {
164
+ await this.#workspaceTurnStarting?.({ workspaceId, workerId, loopId });
165
+ turn = await observed(// {§observability-boundary}
166
+ "loop.turn", { workerId, "loop.id": loopId }, async (span) => {
167
+ const t = await this.#runTurn({
168
+ provider, childProvider, messages, recap, workspaceId, workerId, loopId, signal, onDispatch, onSettled,
169
+ turnNumber: modelTurnCount + 1, maxTurns,
170
+ invalidEmissionRecoveryEntryId
171
+ });
172
+ span.setAttribute("turn.id", t.turnId);
173
+ span.setAttribute("turn.producer", t.producer);
174
+ span.setAttribute("turn.kind", t.kind);
175
+ return t;
176
+ });
177
+ }
178
+ catch (err) {
179
+ // The wall fired mid-turn — the abort tore the turn down (generate rides the loop
180
+ // signal); rule the legible 504, never a generic drain error.
181
+ if (timedOut())
182
+ return await ruleTimeout();
183
+ throw err;
184
+ }
185
+ finally {
186
+ releaseWorkspace();
187
+ }
188
+ turnIds.push(...turn.createdTurnIds);
189
+ // {§overflow-turn-only} — packetless kernel chronology is not a
190
+ // model attempt and never enters emission or strike accounting.
191
+ if (turn.kind === "overflow") {
192
+ if (turn.curationFailure !== undefined) {
193
+ const result = await this.#lifecycle.finish(loopId, turn.curationFailure);
194
+ if (result === null)
195
+ throw new Error(`loop ${loopId} became terminal before token-overflow settlement`);
196
+ cleanup("forceful", "token_budget_overflow");
197
+ return { turnIds, result, hitMaxTurns: false, reason: "token_budget" };
198
+ }
199
+ continue;
200
+ }
201
+ modelTurnCount++;
202
+ // {§engine-rails} Contract Strikes: every emission exhaustion is one
203
+ // frame-contract violation. The next turn is always informed (it carries
204
+ // the rejected emission), and the strike rail — not a bespoke terminal —
205
+ // decides how many consecutive violations the loop survives.
206
+ if (turn.emissionExhausted) {
207
+ if (turn.rejectedModelEntryId === undefined) {
208
+ throw new Error("an invalid-emission recovery requires its rejected emissionAttempt identity");
209
+ }
210
+ invalidEmissionRecoveryEntryId = turn.rejectedModelEntryId;
211
+ }
212
+ else {
213
+ invalidEmissionRecoveryEntryId = null;
214
+ }
215
+ // {§provider-surface-capacity}: the provider rejected the changed request for capacity.
216
+ if (turn.capacityHardStop) {
217
+ if (turn.capacityFailure === undefined) {
218
+ throw new Error("a provider-capacity stop requires its exact failure");
219
+ }
220
+ const result = await this.#lifecycle.finish(loopId, turn.capacityFailure);
221
+ if (result === null)
222
+ throw new Error(`loop ${loopId} became terminal before provider-capacity settlement`);
223
+ cleanup("forceful", "provider_capacity");
224
+ return { turnIds, result, hitMaxTurns: false, reason: "provider_capacity" };
225
+ }
226
+ if (turn.providerParked) {
227
+ // {§provider-recovery} — the provider stayed unavailable past the recovery budget:
228
+ // the loop parks like a [202] wait, spawns outlive it, and the ordinary wake resumes it.
229
+ if (!await this.#lifecycle.park(loopId))
230
+ throw new Error(`loop ${loopId} could not park after provider recovery`);
231
+ cleanup("graceful", "provider_unavailable");
232
+ return { turnIds, result: { status: 202 }, hitMaxTurns: false, reason: "provider_unavailable" };
233
+ }
234
+ // {§engine-rails} — per-turn strike accounting (cycle detection,
235
+ // steer coupling, hard operation outcomes). StrikeRail owns the
236
+ // bookkeeping; runLoop owns abandonment.
237
+ const verdict = this.#strikes.assess(loopId, {
238
+ fingerprint: turn.fingerprint,
239
+ outcomes: turn.outcomes,
240
+ steerStruck: turn.steerStruck,
241
+ minCycles, maxCyclePeriod, maxStrikes
242
+ });
243
+ if (verdict.thresholdCrossed) {
244
+ // {§engine-rails} — the source on the crossing turn classifies
245
+ // the engine verdict: cycle-driven is 508; every other strike is 500.
246
+ const status = verdict.cycleDetected ? 508 : 500;
247
+ const failure = Results.failure("engine:rails", "strike-threshold", status, verdict.cycleDetected
248
+ ? `The loop reached its strike threshold after ${modelTurnCount} model turns because its operation pattern repeated.`
249
+ : `The loop reached its strike threshold after ${modelTurnCount} model turns because consecutive turns failed.`, {}, {
250
+ turns: modelTurnCount,
251
+ stage: "loop",
252
+ retryable: false
253
+ });
254
+ const result = await this.#lifecycle.finish(loopId, failure);
255
+ if (result === null)
256
+ throw new Error(`loop ${loopId} became terminal before strike settlement`);
257
+ cleanup("forceful", "strike_threshold");
258
+ return { turnIds, result, hitMaxTurns: false, reason: "strike_threshold" };
259
+ }
260
+ }
261
+ }
262
+ }
263
+ //# sourceMappingURL=LoopDriver.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"LoopDriver.js","sourceRoot":"","sources":["../../src/core/LoopDriver.ts"],"names":[],"mappings":"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"}
@@ -1,6 +1,6 @@
1
1
  import type { Db } from "./Db.ts";
2
2
  import { type SchemeResult } from "./results.ts";
3
- export interface CancelledLoop {
3
+ interface CancelledLoop {
4
4
  loopId: number;
5
5
  workerId: number;
6
6
  result: SchemeResult;
@@ -24,4 +24,5 @@ export default class LoopLifecycle {
24
24
  modelTurnCount(loopId: number): Promise<number>;
25
25
  cancelTree(workerId: number, reason: string, includeRoot: boolean): Promise<CancelledTree>;
26
26
  }
27
+ export {};
27
28
  //# sourceMappingURL=LoopLifecycle.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"LoopLifecycle.d.ts","sourceRoot":"","sources":["../../src/core/LoopLifecycle.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,EAAE,EAAE,MAAM,SAAS,CAAC;AAClC,OAAgB,EAAE,KAAK,YAAY,EAAE,MAAM,cAAc,CAAC;AAG1D,MAAM,WAAW,aAAa;IAC1B,MAAM,EAAE,MAAM,CAAC;IACf,QAAQ,EAAE,MAAM,CAAC;IACjB,MAAM,EAAE,YAAY,CAAC;CACxB;AAED,MAAM,WAAW,aAAa;IAC1B,SAAS,EAAE,MAAM,EAAE,CAAC;IACpB,KAAK,EAAE,aAAa,EAAE,CAAC;CAC1B;AAED,MAAM,CAAC,OAAO,OAAO,aAAa;;IAG9B,YAAY,EAAE,EAAE,EAAE,EAEjB;IAMD,MAAM,CAAC,aAAa,CAAC,MAAM,EAAE,MAAM,GAAG,MAAM,CAQ3C;IAEK,IAAI,CAAC,MAAM,EAAE,MAAM,GAAG,OAAO,CAAC,OAAO,CAAC,CAI3C;IAEK,IAAI,CAAC,MAAM,EAAE,MAAM,GAAG,OAAO,CAAC,OAAO,CAAC,CAI3C;IAEK,MAAM,CACR,MAAM,EAAE,MAAM,EACd,MAAM,EAAE,YAAY,EACpB,OAAO,GAAE;QAAE,YAAY,CAAC,EAAE,QAAQ,GAAG,IAAI,CAAA;KAAO,GACjD,OAAO,CAAC,YAAY,GAAG,IAAI,CAAC,CAa9B;IAEK,MAAM,CAAC,MAAM,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,CAAC,CAM5C;IAEK,MAAM,CAAC,MAAM,EAAE,MAAM,GAAG,OAAO,CAAC,YAAY,GAAG,IAAI,CAAC,CAQzD;IAEK,OAAO,CAAC,MAAM,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,EAAE,CAAC,CAK/C;IAEK,cAAc,CAAC,MAAM,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,CAAC,CAMpD;IAEK,UAAU,CAAC,QAAQ,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,EAAE,WAAW,EAAE,OAAO,GAAG,OAAO,CAAC,aAAa,CAAC,CAmC/F;CACJ"}
1
+ {"version":3,"file":"LoopLifecycle.d.ts","sourceRoot":"","sources":["../../src/core/LoopLifecycle.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,EAAE,EAAE,MAAM,SAAS,CAAC;AAClC,OAAgB,EAAE,KAAK,YAAY,EAAE,MAAM,cAAc,CAAC;AAG1D,UAAU,aAAa;IACnB,MAAM,EAAE,MAAM,CAAC;IACf,QAAQ,EAAE,MAAM,CAAC;IACjB,MAAM,EAAE,YAAY,CAAC;CACxB;AAED,MAAM,WAAW,aAAa;IAC1B,SAAS,EAAE,MAAM,EAAE,CAAC;IACpB,KAAK,EAAE,aAAa,EAAE,CAAC;CAC1B;AAED,MAAM,CAAC,OAAO,OAAO,aAAa;;IAG9B,YAAY,EAAE,EAAE,EAAE,EAEjB;IAMD,MAAM,CAAC,aAAa,CAAC,MAAM,EAAE,MAAM,GAAG,MAAM,CAQ3C;IAEK,IAAI,CAAC,MAAM,EAAE,MAAM,GAAG,OAAO,CAAC,OAAO,CAAC,CAI3C;IAEK,IAAI,CAAC,MAAM,EAAE,MAAM,GAAG,OAAO,CAAC,OAAO,CAAC,CAI3C;IAEK,MAAM,CACR,MAAM,EAAE,MAAM,EACd,MAAM,EAAE,YAAY,EACpB,OAAO,GAAE;QAAE,YAAY,CAAC,EAAE,QAAQ,GAAG,IAAI,CAAA;KAAO,GACjD,OAAO,CAAC,YAAY,GAAG,IAAI,CAAC,CAa9B;IAEK,MAAM,CAAC,MAAM,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,CAAC,CAM5C;IAEK,MAAM,CAAC,MAAM,EAAE,MAAM,GAAG,OAAO,CAAC,YAAY,GAAG,IAAI,CAAC,CAQzD;IAEK,OAAO,CAAC,MAAM,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,EAAE,CAAC,CAK/C;IAEK,cAAc,CAAC,MAAM,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,CAAC,CAMpD;IAEK,UAAU,CAAC,QAAQ,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,EAAE,WAAW,EAAE,OAAO,GAAG,OAAO,CAAC,aAAa,CAAC,CAmC/F;CACJ"}
@@ -0,0 +1,7 @@
1
+ import type { PlurnkSchemeContext } from "./scheme-types.ts";
2
+ import type { FsDivergence } from "./git-membership.ts";
3
+ export default class MembershipMaterialization {
4
+ #private;
5
+ static materializeMember(pathname: string, root: string, ctx: PlurnkSchemeContext, identities: Map<string, Promise<string>>): Promise<FsDivergence | null>;
6
+ }
7
+ //# sourceMappingURL=MembershipMaterialization.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"MembershipMaterialization.d.ts","sourceRoot":"","sources":["../../src/core/MembershipMaterialization.ts"],"names":[],"mappings":"AAKA,OAAO,KAAK,EAAE,mBAAmB,EAAE,MAAM,mBAAmB,CAAC;AAI7D,OAAO,KAAK,EAAE,YAAY,EAA4C,MAAM,qBAAqB,CAAC;AAqClG,MAAM,CAAC,OAAO,OAAO,yBAAyB;;IAU1C,OAAa,iBAAiB,CAC1B,QAAQ,EAAE,MAAM,EAChB,IAAI,EAAE,MAAM,EACZ,GAAG,EAAE,mBAAmB,EACxB,UAAU,EAAE,GAAG,CAAC,MAAM,EAAE,OAAO,CAAC,MAAM,CAAC,CAAC,GACzC,OAAO,CAAC,YAAY,GAAG,IAAI,CAAC,CAqI9B;CAoKJ"}
@@ -0,0 +1,283 @@
1
+ // Materializing one tracked member from disk into its body channel, text or binary. Split out of GitMembership.
2
+ import { readFile, stat } from "node:fs/promises";
3
+ import { join } from "node:path";
4
+ import { MimetypeInputLimitError } from "@plurnk/plurnk-mimetypes";
5
+ import { MimetypeBinary } from "../content/index.js";
6
+ import Owner from "./Owner.js";
7
+ import EntryCrud from "../schemes/_entry-crud.js";
8
+ import FileMaterialization from "./file-materialization.js";
9
+ const ABSENT_SIG = "absent";
10
+ const sourceProjectionFrom = (encoded) => {
11
+ const attributes = JSON.parse(encoded);
12
+ if (attributes === null || typeof attributes !== "object" || Array.isArray(attributes)) {
13
+ throw new TypeError("GitMembership: entry attributes must be a JSON object");
14
+ }
15
+ const candidate = attributes.sourceProjection;
16
+ if (candidate === undefined)
17
+ return null;
18
+ if (candidate === null || typeof candidate !== "object" || Array.isArray(candidate)) {
19
+ throw new TypeError("GitMembership: sourceProjection must be a JSON object");
20
+ }
21
+ const projection = candidate;
22
+ if (typeof projection.mimetype !== "string"
23
+ || projection.mimetype.length === 0
24
+ || typeof projection.identity !== "string"
25
+ || projection.identity.length === 0
26
+ || !["projected", "unavailable", "input-limit"].includes(projection.disposition ?? "")) {
27
+ throw new TypeError("GitMembership: sourceProjection metadata is malformed");
28
+ }
29
+ if (projection.facts !== undefined && (projection.facts === null || typeof projection.facts !== "object" || Array.isArray(projection.facts))) {
30
+ throw new TypeError("GitMembership: sourceProjection facts must be a JSON object");
31
+ }
32
+ const hasLimit = Number.isSafeInteger(projection.maximumBytes)
33
+ && (projection.maximumBytes ?? 0) > 0
34
+ && Number.isSafeInteger(projection.observedBytes)
35
+ && (projection.observedBytes ?? 0) > (projection.maximumBytes ?? 0);
36
+ if ((projection.disposition === "input-limit") !== hasLimit) {
37
+ throw new TypeError("GitMembership: sourceProjection input-limit evidence is malformed");
38
+ }
39
+ return projection;
40
+ };
41
+ export default class MembershipMaterialization {
42
+ // Materialize a member's model-readable snapshot into a body channel via writeEntry (the
43
+ // entry-write paradigm) — so it appears in the manifest catalog and is READ-able
44
+ // (D4/D5). Change-gated: text changes with mtime:size; binary projections also
45
+ // change when their opaque reader identity changes. A binary source persists
46
+ // only derived Unicode when its installed handler provides it, otherwise an
47
+ // empty typed marker ({§membership-source-projection}).
48
+ // A tracked path missing on disk retains membership but loses its stale
49
+ // readable channels; its explicit absent signature makes a later
50
+ // reappearance another observable divergence.
51
+ static async materializeMember(pathname, root, ctx, identities) {
52
+ const canonical = join(root, pathname); // pathname is namespace-absolute (`/src/foo.ts`); join roots it at the workspace
53
+ const commonsId = await Owner.commonsId(ctx.db, ctx.workspaceId);
54
+ const known = await ctx.db.crud_get_member_sig.get({
55
+ workspace_id: ctx.workspaceId, owner_id: commonsId, scheme: "file", authority: "", pathname,
56
+ });
57
+ // SPEC {§membership-change-gated-sync} — the cheap detect is a stat (mtime:size),
58
+ // never a content read: a member whose signature matches its last sync is a
59
+ // no-op (not re-read, re-tokenized, or rewritten). Coverage stays exhaustive
60
+ // (every member is stat'd); work is proportional to change.
61
+ let sig;
62
+ let sourceBytes;
63
+ try {
64
+ const st = await stat(canonical);
65
+ // A directory-shaped member — an embedded-repo boundary the untracked scan lists as
66
+ // `dir/` (native + iso alike) — is a membership marker: disk truth is a directory,
67
+ // nothing to materialize. Mirrors missing-on-disk: membership stands, no channel.
68
+ if (st.isDirectory())
69
+ return null;
70
+ sig = `${st.mtimeMs}:${st.size}`;
71
+ sourceBytes = st.size;
72
+ }
73
+ catch (err) {
74
+ if (err.code === "ENOENT") {
75
+ if (known === undefined || known.synced_sig === ABSENT_SIG)
76
+ return null;
77
+ const prior = await ctx.db.ops_read_channel.get({
78
+ workspace_id: ctx.workspaceId,
79
+ owner_id: commonsId,
80
+ scheme: "file",
81
+ authority: "",
82
+ pathname,
83
+ channel: "body",
84
+ });
85
+ await ctx.db.crud_delete_channels.run({ entry_id: known.id });
86
+ await ctx.db.crud_mark_member_absent.run({ entry_id: known.id });
87
+ return prior === undefined ? null : {
88
+ pathname,
89
+ entryId: known.id,
90
+ channel: "body",
91
+ before: prior.content,
92
+ after: "",
93
+ };
94
+ }
95
+ throw err;
96
+ }
97
+ if (known !== undefined && known.synced_sig === sig) {
98
+ const sourceMaterialization = FileMaterialization.fromAttributes(known.attributes);
99
+ if (sourceMaterialization !== null) {
100
+ if (FileMaterialization.matchesCurrent(sourceMaterialization, sourceBytes))
101
+ return null;
102
+ }
103
+ else {
104
+ const sourceProjection = sourceProjectionFrom(known.attributes);
105
+ if (sourceProjection !== null) {
106
+ const currentIdentity = await MembershipMaterialization.#projectionIdentity(sourceProjection.mimetype, ctx.mimetypes, identities);
107
+ if (currentIdentity === sourceProjection.identity)
108
+ return null;
109
+ }
110
+ }
111
+ }
112
+ const mimetype = await MembershipMaterialization.#detectMimetype(canonical, ctx.mimetypes);
113
+ const sourceMaterialization = FileMaterialization.classify(sourceBytes);
114
+ if (sourceMaterialization.disposition === "input-limit") {
115
+ return MembershipMaterialization.#materializeLimited(pathname, mimetype, sig, known?.synced_sig !== sig, known?.synced_sig === ABSENT_SIG, sourceMaterialization, ctx);
116
+ }
117
+ if (await MimetypeBinary.isBinaryMimetype(mimetype, ctx.mimetypes)) {
118
+ return MembershipMaterialization.#materializeBinary(pathname, { path: canonical }, mimetype, sig, known?.synced_sig !== sig, known?.synced_sig === ABSENT_SIG, ctx, identities);
119
+ }
120
+ let buf;
121
+ try {
122
+ buf = await readFile(canonical);
123
+ }
124
+ catch (err) {
125
+ if (err.code === "ENOENT")
126
+ return null;
127
+ throw err;
128
+ }
129
+ // {§membership-binary-sniff} — the extension map can lie (.wasm fell through to
130
+ // the markdown DEFAULT and a 3.3MB blob entered the corpus as prose, three copies,
131
+ // ~10M tokens). NUL bytes in the head are binary truth regardless of the label:
132
+ // re-stamp octet-stream and take the same bounded projection-or-marker arm.
133
+ if (buf.subarray(0, 8192).includes(0)) {
134
+ return MembershipMaterialization.#materializeBinary(pathname, { content: buf, hint: "application/octet-stream" }, "application/octet-stream", sig, known?.synced_sig !== sig, known?.synced_sig === ABSENT_SIG, ctx, identities);
135
+ }
136
+ const content = buf.toString("utf8");
137
+ // {§env-delta-filesystem-narration} — capture the prior snapshot before
138
+ // materialization replaces it, then journal the resulting net span.
139
+ const diskChanged = known?.synced_sig !== sig;
140
+ const prior = diskChanged
141
+ ? await ctx.db.ops_read_channel.get({
142
+ workspace_id: ctx.workspaceId, owner_id: commonsId, scheme: "file", authority: "", pathname, channel: "body",
143
+ })
144
+ : undefined;
145
+ const result = await EntryCrud.writeEntry({ authority: "", pathname }, {
146
+ channels: { body: { content, mimetype } },
147
+ attributes: FileMaterialization.attributes(sourceMaterialization),
148
+ }, ctx, "file", commonsId);
149
+ if (result.entryId !== null)
150
+ await ctx.db.crud_set_synced_sig.run({ entry_id: result.entryId, synced_sig: sig });
151
+ const changed = prior !== undefined && prior.content !== content;
152
+ if ((changed || known?.synced_sig === ABSENT_SIG) && result.entryId !== null) {
153
+ return { pathname, entryId: result.entryId, channel: "body", before: prior?.content ?? "", after: content };
154
+ }
155
+ return null;
156
+ }
157
+ static async #materializeBinary(pathname, input, mimetype, sig, diskChanged, previouslyAbsent, ctx, identities) {
158
+ const mimetypes = ctx.mimetypes;
159
+ if (mimetypes === undefined)
160
+ throw new Error("GitMembership: configured mimetype registry is required");
161
+ let content = "";
162
+ let outputMimetype = mimetype;
163
+ let metadata;
164
+ try {
165
+ const projected = await mimetypes.projectReadable(input);
166
+ if (projected === null) {
167
+ metadata = {
168
+ mimetype,
169
+ identity: await MembershipMaterialization.#projectionIdentity(mimetype, mimetypes, identities),
170
+ disposition: "unavailable",
171
+ };
172
+ }
173
+ else {
174
+ content = projected.content;
175
+ outputMimetype = "text/markdown";
176
+ metadata = {
177
+ mimetype: projected.sourceMimetype,
178
+ identity: projected.projectionIdentity,
179
+ disposition: "projected",
180
+ ...(projected.facts !== null && typeof projected.facts === "object" && !Array.isArray(projected.facts)
181
+ ? { facts: projected.facts }
182
+ : {}),
183
+ };
184
+ }
185
+ }
186
+ catch (cause) {
187
+ if (!(cause instanceof MimetypeInputLimitError))
188
+ throw cause;
189
+ metadata = {
190
+ mimetype,
191
+ identity: await MembershipMaterialization.#projectionIdentity(mimetype, mimetypes, identities),
192
+ disposition: "input-limit",
193
+ maximumBytes: cause.maximumBytes,
194
+ observedBytes: cause.observedBytes,
195
+ };
196
+ }
197
+ const prior = diskChanged && metadata.disposition === "projected"
198
+ ? await ctx.db.ops_read_channel.get({
199
+ workspace_id: ctx.workspaceId,
200
+ owner_id: await Owner.commonsId(ctx.db, ctx.workspaceId),
201
+ scheme: "file",
202
+ authority: "",
203
+ pathname,
204
+ channel: "body",
205
+ })
206
+ : undefined;
207
+ const result = await EntryCrud.writeEntry({ authority: "", pathname }, {
208
+ channels: { body: { content, mimetype: outputMimetype } },
209
+ attributes: { sourceProjection: metadata },
210
+ }, ctx, "file", await Owner.commonsId(ctx.db, ctx.workspaceId));
211
+ if (result.entryId !== null) {
212
+ await ctx.db.crud_set_synced_sig.run({ entry_id: result.entryId, synced_sig: sig });
213
+ }
214
+ const changed = prior !== undefined && prior.content !== content;
215
+ if ((changed || previouslyAbsent) && result.entryId !== null) {
216
+ return {
217
+ pathname,
218
+ entryId: result.entryId,
219
+ channel: "body",
220
+ before: prior?.content ?? "",
221
+ after: content,
222
+ };
223
+ }
224
+ return null;
225
+ }
226
+ static #projectionIdentity(mimetype, mimetypes, identities) {
227
+ if (mimetypes === undefined)
228
+ throw new Error("GitMembership: configured mimetype registry is required");
229
+ let identity = identities.get(mimetype);
230
+ if (identity === undefined) {
231
+ identity = mimetypes.projectionIdentity(mimetype);
232
+ identities.set(mimetype, identity);
233
+ }
234
+ return identity;
235
+ }
236
+ // Detect a tracked file's mimetype (mirrors File.detectFileMimetype) through
237
+ // the configured registry, normalizing auto-derived text/plain to the text
238
+ // primitive.
239
+ static async #detectMimetype(canonical, mimetypes) {
240
+ if (mimetypes === undefined)
241
+ throw new Error("GitMembership: configured mimetype registry is required");
242
+ const detected = await mimetypes.detect({ path: canonical });
243
+ return MimetypeBinary.normalizeAutoTextMimetype(detected);
244
+ }
245
+ static async #materializeLimited(pathname, mimetype, sig, diskChanged, previouslyAbsent, metadata, ctx) {
246
+ const commonsId = await Owner.commonsId(ctx.db, ctx.workspaceId);
247
+ const prior = diskChanged
248
+ ? await ctx.db.ops_read_channel.get({
249
+ workspace_id: ctx.workspaceId,
250
+ owner_id: commonsId,
251
+ scheme: "file",
252
+ authority: "",
253
+ pathname,
254
+ channel: "body",
255
+ })
256
+ : undefined;
257
+ const result = await EntryCrud.writeEntry({ authority: "", pathname }, {
258
+ channels: {
259
+ body: {
260
+ content: "",
261
+ mimetype,
262
+ producerResult: FileMaterialization.failure(pathname, metadata),
263
+ },
264
+ },
265
+ attributes: FileMaterialization.attributes(metadata),
266
+ }, ctx, "file", commonsId);
267
+ if (result.entryId !== null) {
268
+ await ctx.db.crud_set_synced_sig.run({ entry_id: result.entryId, synced_sig: sig });
269
+ }
270
+ const changed = prior !== undefined && prior.content !== "";
271
+ if ((changed || previouslyAbsent) && result.entryId !== null) {
272
+ return {
273
+ pathname,
274
+ entryId: result.entryId,
275
+ channel: "body",
276
+ before: prior?.content ?? "",
277
+ after: "",
278
+ };
279
+ }
280
+ return null;
281
+ }
282
+ }
283
+ //# sourceMappingURL=MembershipMaterialization.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"MembershipMaterialization.js","sourceRoot":"","sources":["../../src/core/MembershipMaterialization.ts"],"names":[],"mappings":"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"}