@plurnk/plurnk-service 1.17.0 → 1.18.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 (206) hide show
  1. package/.env.defaults +19 -1
  2. package/README.md +1 -1
  3. package/SPEC.md +1025 -946
  4. package/dist/build-info.json +1 -1
  5. package/dist/content/read-projector.js +2 -2
  6. package/dist/content/read-projector.js.map +1 -1
  7. package/dist/content/read-resolve.d.ts +1 -0
  8. package/dist/content/read-resolve.d.ts.map +1 -1
  9. package/dist/content/read-resolve.js +13 -10
  10. package/dist/content/read-resolve.js.map +1 -1
  11. package/dist/core/AdmittedTurnExecutor.d.ts +1 -2
  12. package/dist/core/AdmittedTurnExecutor.d.ts.map +1 -1
  13. package/dist/core/AdmittedTurnExecutor.js +12 -12
  14. package/dist/core/AdmittedTurnExecutor.js.map +1 -1
  15. package/dist/core/CapabilityResolver.d.ts.map +1 -1
  16. package/dist/core/CapabilityResolver.js +40 -33
  17. package/dist/core/CapabilityResolver.js.map +1 -1
  18. package/dist/core/ChannelWrite.d.ts +1 -0
  19. package/dist/core/ChannelWrite.d.ts.map +1 -1
  20. package/dist/core/ChannelWrite.js +1 -1
  21. package/dist/core/ChannelWrite.js.map +1 -1
  22. package/dist/core/DataStatementRunner.d.ts.map +1 -1
  23. package/dist/core/DataStatementRunner.js +194 -144
  24. package/dist/core/DataStatementRunner.js.map +1 -1
  25. package/dist/core/Dispatcher.d.ts +6 -1
  26. package/dist/core/Dispatcher.d.ts.map +1 -1
  27. package/dist/core/Dispatcher.js +25 -26
  28. package/dist/core/Dispatcher.js.map +1 -1
  29. package/dist/core/Engine.js +1 -1
  30. package/dist/core/Engine.js.map +1 -1
  31. package/dist/core/ExecutionOutputs.sql +8 -0
  32. package/dist/core/ExecutorRegistry.d.ts +4 -0
  33. package/dist/core/ExecutorRegistry.d.ts.map +1 -1
  34. package/dist/core/ExecutorRegistry.js +1 -0
  35. package/dist/core/ExecutorRegistry.js.map +1 -1
  36. package/dist/core/LogBody.d.ts.map +1 -1
  37. package/dist/core/LogBody.js +2 -1
  38. package/dist/core/LogBody.js.map +1 -1
  39. package/dist/core/LogEntryProjection.d.ts.map +1 -1
  40. package/dist/core/LogEntryProjection.js +4 -10
  41. package/dist/core/LogEntryProjection.js.map +1 -1
  42. package/dist/core/LogWriter.d.ts.map +1 -1
  43. package/dist/core/LogWriter.js +9 -7
  44. package/dist/core/LogWriter.js.map +1 -1
  45. package/dist/core/LoopDriver.d.ts.map +1 -1
  46. package/dist/core/LoopDriver.js +1 -3
  47. package/dist/core/LoopDriver.js.map +1 -1
  48. package/dist/core/ModelCall.d.ts.map +1 -1
  49. package/dist/core/ModelCall.js +2 -6
  50. package/dist/core/ModelCall.js.map +1 -1
  51. package/dist/core/ModelCall.sql +7 -36
  52. package/dist/core/ProposalLifecycle.d.ts.map +1 -1
  53. package/dist/core/ProposalLifecycle.js +8 -6
  54. package/dist/core/ProposalLifecycle.js.map +1 -1
  55. package/dist/core/RuntimeWorker.d.ts.map +1 -1
  56. package/dist/core/RuntimeWorker.js +6 -1
  57. package/dist/core/RuntimeWorker.js.map +1 -1
  58. package/dist/core/RuntimeWorker.sql +7 -1
  59. package/dist/core/SchemeRegistry.js +1 -1
  60. package/dist/core/SchemeRegistry.js.map +1 -1
  61. package/dist/core/StrikeRail.d.ts +2 -2
  62. package/dist/core/StrikeRail.d.ts.map +1 -1
  63. package/dist/core/StrikeRail.js +7 -5
  64. package/dist/core/StrikeRail.js.map +1 -1
  65. package/dist/core/ToolResources.d.ts.map +1 -1
  66. package/dist/core/ToolResources.js +5 -3
  67. package/dist/core/ToolResources.js.map +1 -1
  68. package/dist/core/TurnDispositionHandler.d.ts +4 -6
  69. package/dist/core/TurnDispositionHandler.d.ts.map +1 -1
  70. package/dist/core/TurnDispositionHandler.js +88 -80
  71. package/dist/core/TurnDispositionHandler.js.map +1 -1
  72. package/dist/core/TurnMaterialization.d.ts.map +1 -1
  73. package/dist/core/TurnMaterialization.js +7 -9
  74. package/dist/core/TurnMaterialization.js.map +1 -1
  75. package/dist/core/TurnOps.d.ts.map +1 -1
  76. package/dist/core/TurnOps.js +1 -1
  77. package/dist/core/TurnOps.js.map +1 -1
  78. package/dist/core/TurnRunner.d.ts +1 -5
  79. package/dist/core/TurnRunner.d.ts.map +1 -1
  80. package/dist/core/TurnRunner.js +1096 -1062
  81. package/dist/core/TurnRunner.js.map +1 -1
  82. package/dist/core/WorkerControlHandler.d.ts.map +1 -1
  83. package/dist/core/WorkerControlHandler.js +23 -0
  84. package/dist/core/WorkerControlHandler.js.map +1 -1
  85. package/dist/core/WorkerName.d.ts +3 -6
  86. package/dist/core/WorkerName.d.ts.map +1 -1
  87. package/dist/core/WorkerName.js +9 -25
  88. package/dist/core/WorkerName.js.map +1 -1
  89. package/dist/core/WorkspaceGate.js +4 -4
  90. package/dist/core/WorkspaceGate.js.map +1 -1
  91. package/dist/core/env-catalog.d.ts +28 -0
  92. package/dist/core/env-catalog.d.ts.map +1 -0
  93. package/dist/core/env-catalog.js +99 -0
  94. package/dist/core/env-catalog.js.map +1 -0
  95. package/dist/core/file-materialization.js +1 -1
  96. package/dist/core/file-materialization.js.map +1 -1
  97. package/dist/core/git-state.js +1 -1
  98. package/dist/core/git-state.js.map +1 -1
  99. package/dist/core/operation-target-groups.d.ts.map +1 -1
  100. package/dist/core/operation-target-groups.js +2 -1
  101. package/dist/core/operation-target-groups.js.map +1 -1
  102. package/dist/core/packet-wire.d.ts.map +1 -1
  103. package/dist/core/packet-wire.js +320 -295
  104. package/dist/core/packet-wire.js.map +1 -1
  105. package/dist/digest/Digest.d.ts.map +1 -1
  106. package/dist/digest/Digest.js +3 -1
  107. package/dist/digest/Digest.js.map +1 -1
  108. package/dist/digest/DigestRender.d.ts +1 -0
  109. package/dist/digest/DigestRender.d.ts.map +1 -1
  110. package/dist/digest/DigestRender.js +44 -8
  111. package/dist/digest/DigestRender.js.map +1 -1
  112. package/dist/digest/digest-rows.d.ts +6 -0
  113. package/dist/digest/digest-rows.d.ts.map +1 -1
  114. package/dist/digest/digest.sql +11 -2
  115. package/dist/schemes/Exec.d.ts.map +1 -1
  116. package/dist/schemes/Exec.js +68 -33
  117. package/dist/schemes/Exec.js.map +1 -1
  118. package/dist/schemes/ExecScheduler.js +2 -2
  119. package/dist/schemes/ExecScheduler.js.map +1 -1
  120. package/dist/schemes/File.d.ts.map +1 -1
  121. package/dist/schemes/File.js +2 -1
  122. package/dist/schemes/File.js.map +1 -1
  123. package/dist/schemes/Log.js +1 -1
  124. package/dist/schemes/Log.js.map +1 -1
  125. package/dist/schemes/QuestionTool.js +1 -1
  126. package/dist/schemes/QuestionTool.js.map +1 -1
  127. package/dist/schemes/TurnSource.d.ts.map +1 -1
  128. package/dist/schemes/TurnSource.js +7 -6
  129. package/dist/schemes/TurnSource.js.map +1 -1
  130. package/dist/schemes/_entry-crud.sql +18 -0
  131. package/dist/schemes/_entry-manifest.d.ts.map +1 -1
  132. package/dist/schemes/_entry-manifest.js +5 -14
  133. package/dist/schemes/_entry-manifest.js.map +1 -1
  134. package/dist/schemes/_entry-manifest.sql +1 -1
  135. package/dist/schemes/_search-index.d.ts +5 -1
  136. package/dist/schemes/_search-index.d.ts.map +1 -1
  137. package/dist/schemes/_search-index.js +96 -56
  138. package/dist/schemes/_search-index.js.map +1 -1
  139. package/dist/schemes/_search-index.sql +17 -0
  140. package/dist/schemes/exec-abort.js +1 -1
  141. package/dist/schemes/exec-abort.js.map +1 -1
  142. package/dist/schemes/exec-env.d.ts +3 -0
  143. package/dist/schemes/exec-env.d.ts.map +1 -1
  144. package/dist/schemes/exec-env.js +66 -15
  145. package/dist/schemes/exec-env.js.map +1 -1
  146. package/dist/schemes/exec-runtime.d.ts +1 -1
  147. package/dist/schemes/exec-runtime.d.ts.map +1 -1
  148. package/dist/schemes/exec-runtime.js +1 -1
  149. package/dist/schemes/exec-runtime.js.map +1 -1
  150. package/dist/server/ClientReads.d.ts.map +1 -1
  151. package/dist/server/ClientReads.js +2 -1
  152. package/dist/server/ClientReads.js.map +1 -1
  153. package/dist/server/Daemon.d.ts +1 -0
  154. package/dist/server/Daemon.d.ts.map +1 -1
  155. package/dist/server/Daemon.js +32 -14
  156. package/dist/server/Daemon.js.map +1 -1
  157. package/dist/server/DaemonModule.d.ts +7 -2
  158. package/dist/server/DaemonModule.d.ts.map +1 -1
  159. package/dist/server/EnvFunctionality.d.ts +43 -0
  160. package/dist/server/EnvFunctionality.d.ts.map +1 -0
  161. package/dist/server/EnvFunctionality.js +194 -0
  162. package/dist/server/EnvFunctionality.js.map +1 -0
  163. package/dist/server/Functionality.d.ts +4 -2
  164. package/dist/server/Functionality.d.ts.map +1 -1
  165. package/dist/server/Functionality.js +188 -79
  166. package/dist/server/Functionality.js.map +1 -1
  167. package/dist/server/FunctionalityManager.d.ts +2 -0
  168. package/dist/server/FunctionalityManager.d.ts.map +1 -1
  169. package/dist/server/FunctionalityManager.js +13 -3
  170. package/dist/server/FunctionalityManager.js.map +1 -1
  171. package/dist/server/MembersFunctionality.d.ts.map +1 -1
  172. package/dist/server/MembersFunctionality.js +0 -1
  173. package/dist/server/MembersFunctionality.js.map +1 -1
  174. package/dist/server/Retention.d.ts +3 -0
  175. package/dist/server/Retention.d.ts.map +1 -1
  176. package/dist/server/Retention.js +7 -4
  177. package/dist/server/Retention.js.map +1 -1
  178. package/dist/server/Retention.sql +23 -0
  179. package/dist/server/SkillsFunctionality.d.ts.map +1 -1
  180. package/dist/server/SkillsFunctionality.js +5 -2
  181. package/dist/server/SkillsFunctionality.js.map +1 -1
  182. package/dist/server/WorkspaceResidency.d.ts +2 -0
  183. package/dist/server/WorkspaceResidency.d.ts.map +1 -1
  184. package/dist/server/WorkspaceResidency.js +27 -0
  185. package/dist/server/WorkspaceResidency.js.map +1 -1
  186. package/dist/server/client-input.js +1 -1
  187. package/dist/server/client-input.js.map +1 -1
  188. package/dist/server/drain.sql +1 -1
  189. package/dist/server/envelope.d.ts +0 -1
  190. package/dist/server/envelope.d.ts.map +1 -1
  191. package/dist/server/envelope.js +0 -12
  192. package/dist/server/envelope.js.map +1 -1
  193. package/dist/server/lifecycle-recovery.sql +4 -3
  194. package/dist/server/workspace-capabilities.sql +45 -0
  195. package/dist/service.d.ts.map +1 -1
  196. package/dist/service.js +16 -1
  197. package/dist/service.js.map +1 -1
  198. package/docs/env.md +55 -0
  199. package/docs/members.md +4 -4
  200. package/docs/skills.md +1 -1
  201. package/migrations/002_workers.sql +15 -0
  202. package/migrations/004_inference.sql +53 -12
  203. package/migrations/005_entries.sql +8 -0
  204. package/migrations/006_log.sql +18 -15
  205. package/migrations/007_subscriptions.sql +2 -2
  206. package/package.json +42 -32
@@ -10,6 +10,7 @@ import BodyPreview from "../content/body-preview.js";
10
10
  import { assertEditReceipt, assertResourceEffects, LineAnchors, } from "../content/index.js";
11
11
  // {§packet-attachment-parts} — the attachment kinds and their readout weights live in one table.
12
12
  import { imageWeight, pdfWeight } from "./attachments.js";
13
+ import { isExecutionOp } from "@plurnk/plurnk-contracts";
13
14
  export { imageWeight, pdfWeight };
14
15
  export default class PacketWire {
15
16
  // {§packet-markdown} Render the sections in `slot` to one ChatMessage.content
@@ -145,6 +146,9 @@ export default class PacketWire {
145
146
  if (lines.length !== ordinals.length) {
146
147
  throw new TypeError("A sparse log-body projection requires one source ordinal per rendered line.");
147
148
  }
149
+ if (sourceLineNumbers !== null && ordinals.some((ordinal) => ordinal < 1 || ordinal > sourceLineNumbers.length)) {
150
+ throw new TypeError("A sparse log-body projection's ordinals must address its source line numbers.");
151
+ }
148
152
  const displayed = ordinals.map((ordinal) => sourceLineNumbers === null ? startLine + ordinal - 1 : sourceLineNumbers[ordinal - 1]);
149
153
  const width = lineAnchors === null
150
154
  ? numericLineNumberWidth > 0
@@ -481,316 +485,337 @@ export default class PacketWire {
481
485
  }));
482
486
  const promptProjectionWeights = PacketWire.#promptProjectionWeights(entries, visibleBodies, visibility, weighContent, options.promptProjectionWeight);
483
487
  return entries.map((e, index) => {
484
- const meta = {};
485
- const coordinate = typeof e.coordinate === "string" ? e.coordinate : null;
486
- const op = typeof e.op === "string" && e.op.length > 0 ? e.op : null;
487
- const renderedLeaf = LogEntryProjection.leaf(e);
488
- const path = PacketWire.#entryPath(coordinate, renderedLeaf);
489
- // Absence = "model" — the worker's own authorship is the default,
490
- // exactly as `source` absence means the owning worker (#338).
491
- if (typeof e.origin === "string" && e.origin !== "model")
492
- meta.origin = e.origin;
493
- // {§env-delta-attribution}: render the causal worker address or
494
- // subsystem token when present; absence means the owning worker.
495
- if (typeof e.source === "string" && e.source.length > 0)
496
- meta.source = e.source;
497
- if (e.source === "file" && e.attrs !== null && typeof e.attrs === "object" && "git" in e.attrs) {
498
- const git = e.attrs.git;
499
- if (typeof git !== "string" || git.length !== 2) {
500
- throw new TypeError("A source=file log row carries malformed Git XY metadata.");
501
- }
502
- meta.git = git;
503
- }
504
- // SEND, TASK, destructive KILL, and non-200 statuses stay explicit.
505
- // Successful log-KILL rows never reach this projection
506
- // ({§log-kill-meta-operation}).
507
- if (typeof e.status === "number" && (op === "SEND" || op === "KILL" || typeof op === "string" && TurnDisposition.isOp(op) || e.status !== 200))
508
- meta.status = e.status;
509
- const tx = (typeof e.tx === "string" ? PacketWire.#safeParse(e.tx) : e.tx);
510
- if (typeof tx?.aside === "string")
511
- meta.aside = tx.aside;
512
- const target = PacketWire.#renderActionTarget(e.target);
513
- // {§exec-stream}: a terminal stream observation's address is the stream it observed,
514
- // rendered under `stream` like the invocation's own link — never a `target`, which
515
- // the model would otherwise author into an EXEC slot (#425 F4).
516
- const terminalStream = op === "READ"
517
- && e.attrs !== null
518
- && typeof e.attrs === "object"
519
- && e.attrs.terminal === true;
520
- if (op === "COPY" || op === "MOVE") {
521
- const source = PacketWire.#renderSelection(tx?.source?.target, tx?.source?.lineMarker);
522
- const destination = PacketWire.#renderSelection(tx?.destination?.target, tx?.destination?.lineMarker);
523
- if (source !== null)
524
- meta.source = source;
525
- if (destination !== null)
526
- meta.destination = destination;
527
- if (typeof e.status === "number"
528
- && e.status < 400
529
- && (source === null || destination === null)) {
530
- throw new Error(`A successful ${op} log row must retain both operand selections.`);
531
- }
532
- }
533
- else if (target !== null) {
534
- meta[terminalStream ? "stream" : "target"] = target;
535
- }
536
- // {§worker-auto-name} The created identity is an outcome, not an authored target.
537
- if ((op === "WORK" || op === "FORK") && e.attrs !== null && typeof e.attrs === "object"
538
- && typeof e.attrs.worker === "string") {
539
- meta.worker = e.attrs.worker;
540
- }
541
- // EXEC's output is a separate stream entry ({§exec-stream}); its address rides in a
542
- // `stream` link, distinct from the runtime-owned invocation target.
543
- // {§exec-target-routing} {§fs-namespace} — the receipt names the working directory only
544
- // when it is not the project root, and then in the model's own project-relative form;
545
- // the root is the default and a host-absolute path never reaches the packet.
546
- if (op === "EXEC" && e.attrs !== null && typeof e.attrs === "object" && typeof e.attrs.cwd === "string") {
547
- const cwd = PacketWire.#projectRelativeCwd(e.attrs.cwd, options.projectRoot ?? null);
548
- if (cwd !== null)
549
- meta.cwd = cwd;
550
- }
551
- if (op === "EXEC" && e.attrs !== null && typeof e.attrs === "object" && typeof e.attrs.stream === "string") {
552
- meta.stream = e.attrs.stream;
553
- }
488
+ const identity = PacketWire.#rowIdentity(e, options);
554
489
  // Parse rx once — reused for the matcher/items enrichment and the body.
555
490
  const rx = (typeof e.rx === "string" ? PacketWire.#safeParse(e.rx) : e.rx);
556
- // {§exec-stream}: a terminal stream observation is self-sufficient
557
- // even when its selected channel is empty. Preserve exact producer
558
- // facts; do not manufacture a prose completion summary.
559
- if (terminalStream) {
560
- meta.terminal = true;
561
- if (rx !== null && typeof rx === "object" && Object.hasOwn(rx, "exitCode")) {
562
- if (typeof rx.exitCode !== "number" || !Number.isSafeInteger(rx.exitCode)) {
563
- throw new TypeError("A terminal stream result carries a malformed exitCode.");
564
- }
565
- meta.exitCode = rx.exitCode;
566
- }
491
+ const facts = PacketWire.#rowResultFacts(identity, e, rx);
492
+ const projected = PacketWire.#rowBody(identity, e, bodies[index], visibility[index], facts, promptProjectionWeights.get(index), weighContent);
493
+ return PacketWire.#rowAccounting(identity, e, bodies[index], visibility[index], projected, weighContent, options);
494
+ });
495
+ }
496
+ // The row's identity and authored facts: who wrote it, what it addressed, and the statuses
497
+ // that stay explicit. `meta` is the metadata line under construction; each later stage adds
498
+ // to it, and {§log-wire-format}'s canonical JSON sorts the keys, so the order of stages never
499
+ // reaches the wire.
500
+ static #rowIdentity(e, options) {
501
+ const meta = {};
502
+ const coordinate = typeof e.coordinate === "string" ? e.coordinate : null;
503
+ const op = typeof e.op === "string" && e.op.length > 0 ? e.op : null;
504
+ const renderedLeaf = LogEntryProjection.leaf(e);
505
+ const path = PacketWire.#entryPath(coordinate, renderedLeaf);
506
+ // Absence = "model" — the worker's own authorship is the default,
507
+ // exactly as `source` absence means the owning worker (#338).
508
+ if (typeof e.origin === "string" && e.origin !== "model")
509
+ meta.origin = e.origin;
510
+ // {§env-delta-attribution}: render the causal worker address or
511
+ // subsystem token when present; absence means the owning worker.
512
+ if (typeof e.source === "string" && e.source.length > 0)
513
+ meta.source = e.source;
514
+ if (e.source === "file" && e.attrs !== null && typeof e.attrs === "object" && "git" in e.attrs) {
515
+ const git = e.attrs.git;
516
+ if (typeof git !== "string" || git.length !== 2) {
517
+ throw new TypeError("A source=file log row carries malformed Git XY metadata.");
567
518
  }
568
- // {§problem-projection} — the exact durable Problem remains the
569
- // failure authority; the packet carries only facts not already
570
- // owned by its enclosing row. Errors remains only an index.
571
- if (typeof e.status === "number" && e.status >= 400 && rx !== null && typeof rx === "object") {
572
- const problem = rx.problem;
573
- Validator.assertProblemDetails(problem);
574
- meta.problem = Problems.project(problem, {
575
- status: e.status,
576
- row: meta,
577
- });
519
+ meta.git = git;
520
+ }
521
+ // SEND, TASK, destructive KILL, and non-200 statuses stay explicit.
522
+ // Successful log-KILL rows never reach this projection
523
+ // ({§log-kill-meta-operation}).
524
+ if (typeof e.status === "number" && (op === "SEND" || op === "KILL" || typeof op === "string" && TurnDisposition.isOp(op) || e.status !== 200))
525
+ meta.status = e.status;
526
+ const tx = (typeof e.tx === "string" ? PacketWire.#safeParse(e.tx) : e.tx);
527
+ if (typeof tx?.aside === "string")
528
+ meta.aside = tx.aside;
529
+ const target = PacketWire.#renderActionTarget(e.target);
530
+ // {§exec-stream}: a terminal stream observation's address is the stream it observed,
531
+ // rendered under `stream` like the invocation's own link — never a `target`, which
532
+ // the model would otherwise author into an execution slot (#425 F4).
533
+ const terminalStream = op === "READ"
534
+ && e.attrs !== null
535
+ && typeof e.attrs === "object"
536
+ && e.attrs.terminal === true;
537
+ if (op === "COPY" || op === "MOVE") {
538
+ const source = PacketWire.#renderSelection(tx?.source?.target, tx?.source?.lineMarker);
539
+ const destination = PacketWire.#renderSelection(tx?.destination?.target, tx?.destination?.lineMarker);
540
+ if (source !== null)
541
+ meta.source = source;
542
+ if (destination !== null)
543
+ meta.destination = destination;
544
+ if (typeof e.status === "number"
545
+ && e.status < 400
546
+ && (source === null || destination === null)) {
547
+ throw new Error(`A successful ${op} log row must retain both operand selections.`);
578
548
  }
579
- // The success-side sibling (#342): a sub-problem receipt may carry one
580
- // terse `detail` (e.g. the EDIT 304) so situational teaching is paid
581
- // only when the situation occurs, never in the hot path.
582
- if (!Object.hasOwn(meta, "problem") && rx !== null && typeof rx === "object"
583
- && typeof rx.detail === "string"
584
- && rx.detail.length > 0) {
585
- meta.detail = rx.detail;
549
+ }
550
+ else if (target !== null) {
551
+ meta[terminalStream ? "stream" : "target"] = target;
552
+ }
553
+ // {§worker-auto-name} The created identity is an outcome, not an authored target.
554
+ if ((op === "WORK" || op === "FORK") && e.attrs !== null && typeof e.attrs === "object"
555
+ && typeof e.attrs.worker === "string") {
556
+ meta.worker = e.attrs.worker;
557
+ }
558
+ // An execution's output is a separate stream entry ({§exec-stream}); its address rides in a
559
+ // `stream` link, distinct from the runtime-owned invocation target.
560
+ // {§exec-target-routing} {§fs-namespace} — the receipt names the working directory only
561
+ // when it is not the project root, and then in the model's own project-relative form;
562
+ // the root is the default and a host-absolute path never reaches the packet.
563
+ if (isExecutionOp(op) && e.attrs !== null && typeof e.attrs === "object" && typeof e.attrs.cwd === "string") {
564
+ const cwd = PacketWire.#projectRelativeCwd(e.attrs.cwd, options.projectRoot ?? null);
565
+ if (cwd !== null)
566
+ meta.cwd = cwd;
567
+ }
568
+ if (isExecutionOp(op) && e.attrs !== null && typeof e.attrs === "object" && typeof e.attrs.stream === "string") {
569
+ meta.stream = e.attrs.stream;
570
+ }
571
+ return { meta, op, tx, coordinate, path, renderedLeaf, target, terminalStream };
572
+ }
573
+ // The row's result facts from its rx: the terminal stream's exit, the Problem or detail, the
574
+ // matcher, the retrieval extents, and the structured mutation receipts. Returns what the body
575
+ // projection needs to know about the result.
576
+ static #rowResultFacts(identity, e, rx) {
577
+ const { meta, op, tx, terminalStream } = identity;
578
+ // {§exec-stream}: a terminal stream observation is self-sufficient
579
+ // even when its selected channel is empty. Preserve exact producer
580
+ // facts; do not manufacture a prose completion summary.
581
+ if (terminalStream) {
582
+ meta.terminal = true;
583
+ if (rx !== null && typeof rx === "object" && Object.hasOwn(rx, "exitCode")) {
584
+ if (typeof rx.exitCode !== "number" || !Number.isSafeInteger(rx.exitCode)) {
585
+ throw new TypeError("A terminal stream result carries a malformed exitCode.");
586
+ }
587
+ meta.exitCode = rx.exitCode;
586
588
  }
587
- // {§retrieval-packet-metadata}: one extent/coordinate owner plus
588
- // only FIND aggregates that add information beyond that extent.
589
- let findItems = null;
590
- // {§matcher-option} — a pattern rides the heading; the row shows it as `matcher`.
591
- const patterned = tx !== null && tx !== undefined && typeof tx === "object" && tx.matcher !== null && typeof tx.matcher === "object" && typeof tx.matcher.raw === "string";
592
- if (patterned) {
593
- meta.matcher = tx.matcher.raw;
594
- if (op !== "FIND" && rx !== null && typeof rx === "object" && typeof rx.matched === "number")
595
- meta.matched = rx.matched;
589
+ }
590
+ // {§problem-projection} — the exact durable Problem remains the
591
+ // failure authority; the packet carries only facts not already
592
+ // owned by its enclosing row. Errors remains only an index.
593
+ if (typeof e.status === "number" && e.status >= 400 && rx !== null && typeof rx === "object") {
594
+ const problem = rx.problem;
595
+ Validator.assertProblemDetails(problem);
596
+ meta.problem = Problems.project(problem, {
597
+ status: e.status,
598
+ row: meta,
599
+ });
600
+ }
601
+ // The success-side sibling (#342): a sub-problem receipt may carry one
602
+ // terse `detail` (e.g. the EDIT 304) so situational teaching is paid
603
+ // only when the situation occurs, never in the hot path.
604
+ if (!Object.hasOwn(meta, "problem") && rx !== null && typeof rx === "object"
605
+ && typeof rx.detail === "string"
606
+ && rx.detail.length > 0) {
607
+ meta.detail = rx.detail;
608
+ }
609
+ // {§retrieval-packet-metadata}: one extent/coordinate owner plus
610
+ // only FIND aggregates that add information beyond that extent.
611
+ let findItems = null;
612
+ const patterned = tx !== null && tx !== undefined && typeof tx === "object" && tx.matcher !== null && typeof tx.matcher === "object" && typeof tx.matcher.raw === "string";
613
+ if (patterned) {
614
+ meta.matcher = tx.matcher.raw;
615
+ if (op !== "FIND" && rx !== null && typeof rx === "object" && typeof rx.matched === "number")
616
+ meta.matched = rx.matched;
617
+ }
618
+ // {§channel-selection-visibility} — a READ names the resource's other channels with their
619
+ // tokens, so the row itself shows the choice a FIND listing would.
620
+ if (op === "READ" && rx !== null && typeof rx === "object" && rx.channels !== null && typeof rx.channels === "object") {
621
+ meta.channels = rx.channels;
622
+ }
623
+ // {§send-response-receipt} — a reply's row names the prompts it answered.
624
+ if (op === "SEND" && rx !== null && typeof rx === "object" && Array.isArray(rx.recipients)) {
625
+ meta.recipients = rx.recipients;
626
+ }
627
+ if (op === "READ" || op === "FIND") {
628
+ if (op === "FIND" && rx !== null && typeof rx === "object" && typeof rx.content === "string") {
629
+ const parsed = PacketWire.#safeParse(rx.content);
630
+ if (Array.isArray(parsed))
631
+ findItems = parsed.length;
596
632
  }
597
- // {§channel-selection-visibility} — a READ names the resource's other channels with their
598
- // tokens, so the row itself shows the choice a FIND listing would.
599
- if (op === "READ" && rx !== null && typeof rx === "object" && rx.channels !== null && typeof rx.channels === "object") {
600
- meta.channels = rx.channels;
633
+ const range = rx !== null && typeof rx === "object" && rx.range !== undefined
634
+ ? rx.range
635
+ : undefined;
636
+ const problemOwnsRange = typeof e.status === "number"
637
+ && e.status >= 400
638
+ && meta.problem !== null
639
+ && typeof meta.problem === "object"
640
+ && Object.hasOwn(meta.problem, "range");
641
+ if (problemOwnsRange) {
642
+ Validator.assertRangeExtent(meta.problem.range);
601
643
  }
602
- // {§send-response-receipt} — a reply's row names the prompts it answered.
603
- if (op === "SEND" && rx !== null && typeof rx === "object" && Array.isArray(rx.recipients)) {
604
- meta.recipients = rx.recipients;
644
+ if (range !== undefined && !problemOwnsRange) {
645
+ meta.range = Validator.assertRangeExtent(range);
605
646
  }
606
- if (op === "READ" || op === "FIND") {
607
- if (op === "FIND" && rx !== null && typeof rx === "object" && typeof rx.content === "string") {
608
- const parsed = PacketWire.#safeParse(rx.content);
609
- if (Array.isArray(parsed))
610
- findItems = parsed.length;
611
- }
612
- const range = rx !== null && typeof rx === "object" && rx.range !== undefined
613
- ? rx.range
614
- : undefined;
615
- const problemOwnsRange = typeof e.status === "number"
616
- && e.status >= 400
617
- && meta.problem !== null
618
- && typeof meta.problem === "object"
619
- && Object.hasOwn(meta.problem, "range");
620
- if (problemOwnsRange) {
621
- Validator.assertRangeExtent(meta.problem.range);
622
- }
623
- if (range !== undefined && !problemOwnsRange) {
624
- meta.range = Validator.assertRangeExtent(range);
625
- }
626
- else if (op === "READ" && rx !== null && typeof rx === "object" && rx.region !== undefined) {
627
- meta.region = Validator.assertTextRegion(rx.region);
628
- }
629
- // These are underlying selected-content weights, distinct from
630
- // the emitted body's generic `tokens` measurement.
631
- if (op === "FIND" && rx !== null && typeof rx === "object" && typeof rx.itemsWeightTotal === "number" && rx.itemsWeightTotal > 0) {
632
- meta.itemsTokenTotal = rx.itemsWeightTotal;
633
- }
634
- if (op === "FIND"
635
- && rx !== null
636
- && typeof rx === "object"
637
- && typeof rx.returnedItemsWeightTotal === "number"
638
- && rx.returnedItemsWeightTotal > 0
639
- && rx.returnedItemsWeightTotal !== rx.itemsWeightTotal) {
640
- meta.returnedItemsTokenTotal = rx.returnedItemsWeightTotal;
641
- }
642
- if (op === "FIND"
643
- && patterned
644
- && range !== null
645
- && typeof range === "object"
646
- && range.unit === "resource"
647
- && rx !== null
648
- && typeof rx === "object"
649
- && typeof rx.matchLocationCount === "number"
650
- && rx.matchLocationCount > 0) {
651
- meta.matchLocationCount = rx.matchLocationCount;
652
- }
647
+ else if (op === "READ" && rx !== null && typeof rx === "object" && rx.region !== undefined) {
648
+ meta.region = Validator.assertTextRegion(rx.region);
653
649
  }
654
- // {§edit-result-receipt-projection} {§edit-result-copy-move-effects}
655
- // EDIT/scoped entry KILL own one receipt; COPY/MOVE own resource effects whose
656
- // optional receipts describe scoped textual materializations.
657
- let structuredMutationReceipt = false;
658
- if ((op === "EDIT" || op === "KILL") && rx !== null && typeof rx === "object" && Object.hasOwn(rx, "receipt")) {
659
- Object.assign(meta, PacketWire.#receiptMeta(rx.receipt));
660
- structuredMutationReceipt = true;
650
+ // These are underlying selected-content weights, distinct from
651
+ // the emitted body's generic `tokens` measurement.
652
+ if (op === "FIND" && rx !== null && typeof rx === "object" && typeof rx.itemsWeightTotal === "number" && rx.itemsWeightTotal > 0) {
653
+ meta.itemsTokenTotal = rx.itemsWeightTotal;
661
654
  }
662
- if ((op === "COPY" || op === "MOVE")
655
+ if (op === "FIND"
663
656
  && rx !== null
664
657
  && typeof rx === "object"
665
- && Object.hasOwn(rx, "effects")) {
666
- const effects = assertResourceEffects(rx.effects);
667
- meta.effects = effects.map((effect) => ({
668
- target: effect.target,
669
- action: effect.action,
670
- ...(effect.receipt === undefined
671
- ? {}
672
- : PacketWire.#receiptMeta(effect.receipt)),
673
- }));
674
- structuredMutationReceipt = effects.some((effect) => effect.receipt !== undefined);
658
+ && typeof rx.returnedItemsWeightTotal === "number"
659
+ && rx.returnedItemsWeightTotal > 0
660
+ && rx.returnedItemsWeightTotal !== rx.itemsWeightTotal) {
661
+ meta.returnedItemsTokenTotal = rx.returnedItemsWeightTotal;
675
662
  }
676
- // The canonical full body is shared with log READ, log FIND,
677
- // and search derivation. READ/FIND own selection bounds, TASK and
678
- // admitted programs remain complete, and prompt rows share their packet
679
- // allowance. Structured mutation receipts own their join bound;
680
- // every remaining body uses the ordinary fixed preview.
681
- const fullBody = bodies[index];
682
- const bodyVisibility = visibility[index];
683
- const projectedBody = {
684
- ...fullBody,
685
- content: bodyVisibility.fullyFolded ? bodyVisibility.readableContent : bodyVisibility.content,
686
- };
687
- const emptyFind = op === "FIND" && e.status === 200 && findItems === 0;
688
- const previewExempt = op === "READ"
689
- || op === "FIND"
690
- || op === "TASK"
691
- || (op === null && renderedLeaf === "ops")
692
- || structuredMutationReceipt;
693
- const lineAnchors = op === "READ" ? e.lineAnchors ?? null : null;
694
- const lineNumberWidth = op === "READ" ? e.lineNumberWidth ?? null : null;
695
- if (lineAnchors !== null) {
696
- LineAnchors.assertProjection(fullBody.content, lineAnchors);
697
- }
698
- const findRange = op === "FIND" && meta.range !== null && typeof meta.range === "object"
699
- ? meta.range
700
- : null;
701
- const bodyStartLine = findRange?.returned?.[0] ?? fullBody.startLine;
702
- const numericLineNumberWidth = findRange === null
703
- ? bodyStartLine === null || bodyVisibility.totalLines === 0
704
- ? 0
705
- : String(fullBody.lineOrdinals?.at(-1) ?? bodyStartLine + bodyVisibility.totalLines - 1).length
706
- : String(findRange.total).length;
707
- const sourceOrdinals = bodyVisibility.fullyFolded
708
- ? bodyVisibility.readableOrdinals
709
- : bodyVisibility.ordinals;
710
- const promptProjectionWeight = promptProjectionWeights.get(index);
711
- const projection = promptProjectionWeight !== undefined
712
- ? PacketWire.#promptProjection(projectedBody, promptProjectionWeight, weighContent, (content) => PacketWire.#renderContentBody(content, bodyStartLine, null, null, numericLineNumberWidth, bodyStartLine === null
713
- ? null
714
- : sourceOrdinals.slice(0, TextCoordinates.logicalLines(content).length)))
715
- : previewExempt
716
- ? { text: projectedBody.content, cut: false, chunk: null }
717
- : PacketWire.#preview(projectedBody.content);
718
- const projectedLineCount = TextCoordinates.logicalLines(projection.text).length;
719
- const projectedOrdinals = sourceOrdinals.slice(0, projectedLineCount);
720
- const body = emptyFind || projection.text.length === 0
721
- ? ""
722
- : PacketWire.#renderContentBody(projection.text, bodyStartLine, lineAnchors, lineNumberWidth, numericLineNumberWidth, bodyStartLine === null ? null : projectedOrdinals, fullBody.lineOrdinals ?? null);
723
- // lines beside tokens on a non-retrieval row with a navigable body — the count of
724
- // `N:`-numbered lines (fences and unnumbered prose don't count), so the model can plan
725
- // a <start,end> slice before paying for a READ. READ/FIND own typed extents instead.
726
- if (fullBody.content.length > 0 && op !== "READ" && op !== "FIND") {
727
- meta.lines = bodyVisibility.totalLines;
728
- }
729
- if (bodyVisibility.folded.length > 0 && !bodyVisibility.fullyFolded) {
730
- meta.folded = LogVisibility.format(bodyVisibility.folded);
731
- }
732
- const display = bodyVisibility.readableContent.length === 0
733
- ? "none"
734
- : bodyVisibility.fullyFolded || e.output_withheld === true
735
- ? "folded"
736
- : body.length === 0
737
- ? "none"
738
- : "open";
739
- const projectedChunk = projection.chunk !== null
740
- && bodyVisibility.folded.length > 0
741
- && !bodyVisibility.fullyFolded
742
- ? PacketWire.#sparseChunk(fullBody.content, projectedBody.content, sourceOrdinals, projection.text)
743
- : projection.chunk;
744
- if (display === "open" && projectedChunk !== null)
745
- meta.chunk = projectedChunk;
746
- const nativeCandidate = op === "READ" && typeof e.status === "number" && e.status >= 200 && e.status < 300
747
- ? PacketWire.#attachmentOf(e.rx, e.target, coordinate, target) : null;
748
- const native = nativeCandidate !== null && (options.acceptedAttachmentKinds?.has(nativeCandidate.kind) ?? true)
749
- ? nativeCandidate : null;
750
- const outputWithheld = e.output_withheld === true
751
- && ((!bodyVisibility.fullyFolded && body.length > 0) || native !== null);
752
- if (outputWithheld) {
753
- const omitted = body.length > 0
754
- ? `${projectedLineCount} output lines${native === null ? "" : " and native content"}`
755
- : "native content";
756
- meta.overflow = `${omitted} not shown; logTokensTotal exceeds logTokensMax`;
663
+ if (op === "FIND"
664
+ && patterned
665
+ && range !== null
666
+ && typeof range === "object"
667
+ && range.unit === "resource"
668
+ && rx !== null
669
+ && typeof rx === "object"
670
+ && typeof rx.matchLocationCount === "number"
671
+ && rx.matchLocationCount > 0) {
672
+ meta.matchLocationCount = rx.matchLocationCount;
757
673
  }
758
- const renderRow = () => {
759
- const metadata = PacketWire.#canonicalJson(meta);
760
- return display === "open"
761
- ? `### ${path}\n${metadata}\n${body}`
762
- : `### ${path}\n${metadata}`;
763
- };
764
- // The accounting field participates in the row it measures. Iterate
765
- // until its decimal width and therefore the rendered row's curation
766
- // weight are stable. {§packet-token-accounting}
767
- // {§packet-attachment-parts}: retained native content shares the row's curation lifetime.
768
- const attachment = e.output_withheld !== true
769
- && !(bodyVisibility.totalLines > 0 && bodyVisibility.fullyFolded)
770
- ? native
771
- : null;
772
- if (attachment !== null)
773
- meta.tokensAttachment = attachment.weight;
774
- meta.logTokens = 0;
775
- for (let pass = 0; pass < 8; pass += 1) {
776
- const logTokens = weighContent(renderRow()) + (attachment?.weight ?? 0);
777
- if (meta.logTokens === logTokens) {
778
- return {
779
- content: renderRow(),
780
- curationTarget: { path, logTokens },
781
- attachment,
782
- unadmittedOutput: (display === "open" || attachment !== null)
783
- && fullBody.provenance === "returned"
784
- && e.output_admission_turn_id == null
785
- && typeof e.id === "number"
786
- ? e.id : null,
787
- newOverflow: outputWithheld && e.newOverflow === true,
788
- };
789
- }
790
- meta.logTokens = logTokens;
674
+ }
675
+ // {§edit-result-receipt-projection} {§edit-result-copy-move-effects}
676
+ // EDIT/scoped entry KILL own one receipt; COPY/MOVE own resource effects whose
677
+ // optional receipts describe scoped textual materializations.
678
+ let structuredMutationReceipt = false;
679
+ if ((op === "EDIT" || op === "KILL") && rx !== null && typeof rx === "object" && Object.hasOwn(rx, "receipt")) {
680
+ Object.assign(meta, PacketWire.#receiptMeta(rx.receipt));
681
+ structuredMutationReceipt = true;
682
+ }
683
+ if ((op === "COPY" || op === "MOVE")
684
+ && rx !== null
685
+ && typeof rx === "object"
686
+ && Object.hasOwn(rx, "effects")) {
687
+ const effects = assertResourceEffects(rx.effects);
688
+ meta.effects = effects.map((effect) => ({
689
+ target: effect.target,
690
+ action: effect.action,
691
+ ...(effect.receipt === undefined
692
+ ? {}
693
+ : PacketWire.#receiptMeta(effect.receipt)),
694
+ }));
695
+ structuredMutationReceipt = effects.some((effect) => effect.receipt !== undefined);
696
+ }
697
+ return { findItems, structuredMutationReceipt };
698
+ }
699
+ // The body the row shows: the canonical full body is shared with log READ, log FIND, and
700
+ // search derivation. READ/FIND own selection bounds, TASK and admitted programs remain
701
+ // complete, and prompt rows share their packet allowance. Structured mutation receipts own
702
+ // their join bound; every remaining body uses the ordinary fixed preview.
703
+ static #rowBody(identity, e, fullBody, bodyVisibility, facts, promptProjectionWeight, weighContent) {
704
+ const { meta, op, renderedLeaf } = identity;
705
+ const projectedBody = {
706
+ ...fullBody,
707
+ content: bodyVisibility.fullyFolded ? bodyVisibility.readableContent : bodyVisibility.content,
708
+ };
709
+ const emptyFind = op === "FIND" && e.status === 200 && facts.findItems === 0;
710
+ const previewExempt = op === "READ"
711
+ || op === "FIND"
712
+ || op === "TASK"
713
+ || (op === null && renderedLeaf === "ops")
714
+ || facts.structuredMutationReceipt;
715
+ const lineAnchors = op === "READ" ? e.lineAnchors ?? null : null;
716
+ const lineNumberWidth = op === "READ" ? e.lineNumberWidth ?? null : null;
717
+ if (lineAnchors !== null) {
718
+ LineAnchors.assertProjection(fullBody.content, lineAnchors);
719
+ }
720
+ const findRange = op === "FIND" && meta.range !== null && typeof meta.range === "object"
721
+ ? meta.range
722
+ : null;
723
+ const bodyStartLine = findRange?.returned?.[0] ?? fullBody.startLine;
724
+ const numericLineNumberWidth = findRange === null
725
+ ? bodyStartLine === null || bodyVisibility.totalLines === 0
726
+ ? 0
727
+ : String(fullBody.lineOrdinals?.at(-1) ?? bodyStartLine + bodyVisibility.totalLines - 1).length
728
+ : String(findRange.total).length;
729
+ const sourceOrdinals = bodyVisibility.fullyFolded
730
+ ? bodyVisibility.readableOrdinals
731
+ : bodyVisibility.ordinals;
732
+ const projection = promptProjectionWeight !== undefined
733
+ ? PacketWire.#promptProjection(projectedBody, promptProjectionWeight, weighContent, (content) => PacketWire.#renderContentBody(content, bodyStartLine, null, null, numericLineNumberWidth, bodyStartLine === null
734
+ ? null
735
+ : sourceOrdinals.slice(0, TextCoordinates.logicalLines(content).length)))
736
+ : previewExempt
737
+ ? { text: projectedBody.content, cut: false, chunk: null }
738
+ : PacketWire.#preview(projectedBody.content);
739
+ const projectedLineCount = TextCoordinates.logicalLines(projection.text).length;
740
+ const projectedOrdinals = sourceOrdinals.slice(0, projectedLineCount);
741
+ const body = emptyFind || projection.text.length === 0
742
+ ? ""
743
+ : PacketWire.#renderContentBody(projection.text, bodyStartLine, lineAnchors, lineNumberWidth, numericLineNumberWidth, bodyStartLine === null ? null : projectedOrdinals, fullBody.lineOrdinals ?? null);
744
+ // lines beside tokens on a non-retrieval row with a navigable body — the count of
745
+ // `N:`-numbered lines (fences and unnumbered prose don't count), so the model can plan
746
+ // a <start,end> slice before paying for a READ. READ/FIND own typed extents instead.
747
+ if (fullBody.content.length > 0 && op !== "READ" && op !== "FIND") {
748
+ meta.lines = bodyVisibility.totalLines;
749
+ }
750
+ if (bodyVisibility.folded.length > 0 && !bodyVisibility.fullyFolded) {
751
+ meta.folded = LogVisibility.format(bodyVisibility.folded);
752
+ }
753
+ const display = bodyVisibility.readableContent.length === 0
754
+ ? "none"
755
+ : bodyVisibility.fullyFolded || e.output_withheld === true
756
+ ? "folded"
757
+ : body.length === 0
758
+ ? "none"
759
+ : "open";
760
+ const projectedChunk = projection.chunk !== null
761
+ && bodyVisibility.folded.length > 0
762
+ && !bodyVisibility.fullyFolded
763
+ ? PacketWire.#sparseChunk(fullBody.content, projectedBody.content, sourceOrdinals, projection.text)
764
+ : projection.chunk;
765
+ if (display === "open" && projectedChunk !== null)
766
+ meta.chunk = projectedChunk;
767
+ return { body, projectedLineCount, display };
768
+ }
769
+ // The row's native attachment, its withholding receipt, and the accounting field that
770
+ // participates in the row it measures: iterate until its decimal width and therefore the
771
+ // rendered row's curation weight are stable. {§packet-token-accounting}
772
+ static #rowAccounting(identity, e, fullBody, bodyVisibility, projected, weighContent, options) {
773
+ const { meta, op, coordinate, path, target } = identity;
774
+ const { body, projectedLineCount, display } = projected;
775
+ const nativeCandidate = op === "READ" && typeof e.status === "number" && e.status >= 200 && e.status < 300
776
+ ? PacketWire.#attachmentOf(e.rx, e.target, coordinate, target) : null;
777
+ const native = nativeCandidate !== null && (options.acceptedAttachmentKinds?.has(nativeCandidate.kind) ?? true)
778
+ ? nativeCandidate : null;
779
+ const outputWithheld = e.output_withheld === true
780
+ && ((!bodyVisibility.fullyFolded && body.length > 0) || native !== null);
781
+ if (outputWithheld) {
782
+ const omitted = body.length > 0
783
+ ? `${projectedLineCount} output lines${native === null ? "" : " and native content"}`
784
+ : "native content";
785
+ meta.overflow = `${omitted} not shown; the log exceeded logTokensMax when this row was withheld`;
786
+ }
787
+ const renderRow = () => {
788
+ const metadata = PacketWire.#canonicalJson(meta);
789
+ return display === "open"
790
+ ? `### ${path}\n${metadata}\n${body}`
791
+ : `### ${path}\n${metadata}`;
792
+ };
793
+ // {§packet-attachment-parts}: retained native content shares the row's curation lifetime.
794
+ const attachment = e.output_withheld !== true
795
+ && !(bodyVisibility.totalLines > 0 && bodyVisibility.fullyFolded)
796
+ ? native
797
+ : null;
798
+ if (attachment !== null)
799
+ meta.tokensAttachment = attachment.weight;
800
+ meta.logTokens = 0;
801
+ for (let pass = 0; pass < 8; pass += 1) {
802
+ const logTokens = weighContent(renderRow()) + (attachment?.weight ?? 0);
803
+ if (meta.logTokens === logTokens) {
804
+ return {
805
+ content: renderRow(),
806
+ curationTarget: { path, logTokens },
807
+ attachment,
808
+ unadmittedOutput: (display === "open" || attachment !== null)
809
+ && fullBody.provenance === "returned"
810
+ && e.output_admission_turn_id == null
811
+ && typeof e.id === "number"
812
+ ? e.id : null,
813
+ newOverflow: outputWithheld && e.newOverflow === true,
814
+ };
791
815
  }
792
- throw new Error("packet log row accounting did not converge");
793
- });
816
+ meta.logTokens = logTokens;
817
+ }
818
+ throw new Error("packet log row accounting did not converge");
794
819
  }
795
820
  static #attachmentOf(rx, target, coordinate, path) {
796
821
  const view = rx;