@smthrs/journal 0.0.0-stage → 1.0.0-rc.4

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 (257) hide show
  1. package/CHANGELOG.md +149 -0
  2. package/LICENSE +21 -0
  3. package/README.md +206 -2
  4. package/dist/cjs/CallFact.d.ts +129 -0
  5. package/dist/cjs/CallFact.d.ts.map +1 -0
  6. package/dist/cjs/CallFact.js +106 -0
  7. package/dist/cjs/CallFact.js.map +7 -0
  8. package/dist/cjs/Consensus.d.ts +440 -0
  9. package/dist/cjs/Consensus.d.ts.map +1 -0
  10. package/dist/cjs/Consensus.js +251 -0
  11. package/dist/cjs/Consensus.js.map +7 -0
  12. package/dist/cjs/EngineEvent.d.ts +890 -0
  13. package/dist/cjs/EngineEvent.d.ts.map +1 -0
  14. package/dist/cjs/EngineEvent.js +383 -0
  15. package/dist/cjs/EngineEvent.js.map +7 -0
  16. package/dist/cjs/ExecutionFact.d.ts +216 -0
  17. package/dist/cjs/ExecutionFact.d.ts.map +1 -0
  18. package/dist/cjs/ExecutionFact.js +303 -0
  19. package/dist/cjs/ExecutionFact.js.map +7 -0
  20. package/dist/cjs/Journal.d.ts +617 -0
  21. package/dist/cjs/Journal.d.ts.map +1 -0
  22. package/dist/cjs/Journal.js +190 -0
  23. package/dist/cjs/Journal.js.map +7 -0
  24. package/dist/cjs/JournalEvent.d.ts +421 -0
  25. package/dist/cjs/JournalEvent.d.ts.map +1 -0
  26. package/dist/cjs/JournalEvent.js +281 -0
  27. package/dist/cjs/JournalEvent.js.map +7 -0
  28. package/dist/cjs/JournalGeneration.d.ts +34 -0
  29. package/dist/cjs/JournalGeneration.d.ts.map +1 -0
  30. package/dist/cjs/JournalGeneration.js +72 -0
  31. package/dist/cjs/JournalGeneration.js.map +7 -0
  32. package/dist/cjs/JournalMetrics.d.ts +72 -0
  33. package/dist/cjs/JournalMetrics.d.ts.map +1 -0
  34. package/dist/cjs/JournalMetrics.js +55 -0
  35. package/dist/cjs/JournalMetrics.js.map +7 -0
  36. package/dist/cjs/Migrations.d.ts +42 -0
  37. package/dist/cjs/Migrations.d.ts.map +1 -0
  38. package/dist/cjs/Migrations.js +58 -0
  39. package/dist/cjs/Migrations.js.map +7 -0
  40. package/dist/cjs/OwnerId.d.ts +40 -0
  41. package/dist/cjs/OwnerId.d.ts.map +1 -0
  42. package/dist/cjs/OwnerId.js +40 -0
  43. package/dist/cjs/OwnerId.js.map +7 -0
  44. package/dist/cjs/Projection.d.ts +29 -0
  45. package/dist/cjs/Projection.d.ts.map +1 -0
  46. package/dist/cjs/Projection.js +25 -0
  47. package/dist/cjs/Projection.js.map +7 -0
  48. package/dist/cjs/RedactedLogger.d.ts +121 -0
  49. package/dist/cjs/RedactedLogger.d.ts.map +1 -0
  50. package/dist/cjs/RedactedLogger.js +235 -0
  51. package/dist/cjs/RedactedLogger.js.map +7 -0
  52. package/dist/cjs/Redaction.d.ts +350 -0
  53. package/dist/cjs/Redaction.d.ts.map +1 -0
  54. package/dist/cjs/Redaction.js +928 -0
  55. package/dist/cjs/Redaction.js.map +7 -0
  56. package/dist/cjs/SqlConsensus.d.ts +44 -0
  57. package/dist/cjs/SqlConsensus.d.ts.map +1 -0
  58. package/dist/cjs/SqlConsensus.js +243 -0
  59. package/dist/cjs/SqlConsensus.js.map +7 -0
  60. package/dist/cjs/SqlJournal.d.ts +173 -0
  61. package/dist/cjs/SqlJournal.d.ts.map +1 -0
  62. package/dist/cjs/SqlJournal.js +1568 -0
  63. package/dist/cjs/SqlJournal.js.map +7 -0
  64. package/dist/cjs/StepFact.d.ts +66 -0
  65. package/dist/cjs/StepFact.d.ts.map +1 -0
  66. package/dist/cjs/StepFact.js +68 -0
  67. package/dist/cjs/StepFact.js.map +7 -0
  68. package/dist/cjs/index.d.ts +95 -0
  69. package/dist/cjs/index.d.ts.map +1 -0
  70. package/dist/cjs/index.js +63 -0
  71. package/dist/cjs/index.js.map +7 -0
  72. package/dist/cjs/internal/JournalInternalFault.d.ts +37 -0
  73. package/dist/cjs/internal/JournalInternalFault.d.ts.map +1 -0
  74. package/dist/cjs/internal/JournalInternalFault.js +43 -0
  75. package/dist/cjs/internal/JournalInternalFault.js.map +7 -0
  76. package/dist/cjs/migrations/0001_initial.d.ts +15 -0
  77. package/dist/cjs/migrations/0001_initial.d.ts.map +1 -0
  78. package/dist/cjs/migrations/0001_initial.js +54 -0
  79. package/dist/cjs/migrations/0001_initial.js.map +7 -0
  80. package/dist/cjs/migrations/0002_checkpoints.d.ts +27 -0
  81. package/dist/cjs/migrations/0002_checkpoints.d.ts.map +1 -0
  82. package/dist/cjs/migrations/0002_checkpoints.js +48 -0
  83. package/dist/cjs/migrations/0002_checkpoints.js.map +7 -0
  84. package/dist/cjs/migrations/0003_startup_index.d.ts +15 -0
  85. package/dist/cjs/migrations/0003_startup_index.d.ts.map +1 -0
  86. package/dist/cjs/migrations/0003_startup_index.js +40 -0
  87. package/dist/cjs/migrations/0003_startup_index.js.map +7 -0
  88. package/dist/cjs/migrations/0004_dedup.d.ts +15 -0
  89. package/dist/cjs/migrations/0004_dedup.d.ts.map +1 -0
  90. package/dist/cjs/migrations/0004_dedup.js +57 -0
  91. package/dist/cjs/migrations/0004_dedup.js.map +7 -0
  92. package/dist/cjs/migrations/0005_run_event_type.d.ts +15 -0
  93. package/dist/cjs/migrations/0005_run_event_type.d.ts.map +1 -0
  94. package/dist/cjs/migrations/0005_run_event_type.js +40 -0
  95. package/dist/cjs/migrations/0005_run_event_type.js.map +7 -0
  96. package/dist/cjs/migrations/0006_consensus.d.ts +22 -0
  97. package/dist/cjs/migrations/0006_consensus.d.ts.map +1 -0
  98. package/dist/cjs/migrations/0006_consensus.js +84 -0
  99. package/dist/cjs/migrations/0006_consensus.js.map +7 -0
  100. package/dist/cjs/package.json +1 -0
  101. package/dist/cjs/test/Notifying.d.ts +65 -0
  102. package/dist/cjs/test/Notifying.d.ts.map +1 -0
  103. package/dist/cjs/test/Notifying.js +62 -0
  104. package/dist/cjs/test/Notifying.js.map +7 -0
  105. package/dist/cjs/test/TestJournal.d.ts +43 -0
  106. package/dist/cjs/test/TestJournal.d.ts.map +1 -0
  107. package/dist/cjs/test/TestJournal.js +43 -0
  108. package/dist/cjs/test/TestJournal.js.map +7 -0
  109. package/dist/esm/CallFact.d.ts +129 -0
  110. package/dist/esm/CallFact.d.ts.map +1 -0
  111. package/dist/esm/CallFact.js +96 -0
  112. package/dist/esm/CallFact.js.map +1 -0
  113. package/dist/esm/Consensus.d.ts +440 -0
  114. package/dist/esm/Consensus.d.ts.map +1 -0
  115. package/dist/esm/Consensus.js +454 -0
  116. package/dist/esm/Consensus.js.map +1 -0
  117. package/dist/esm/EngineEvent.d.ts +890 -0
  118. package/dist/esm/EngineEvent.d.ts.map +1 -0
  119. package/dist/esm/EngineEvent.js +614 -0
  120. package/dist/esm/EngineEvent.js.map +1 -0
  121. package/dist/esm/ExecutionFact.d.ts +216 -0
  122. package/dist/esm/ExecutionFact.d.ts.map +1 -0
  123. package/dist/esm/ExecutionFact.js +374 -0
  124. package/dist/esm/ExecutionFact.js.map +1 -0
  125. package/dist/esm/Journal.d.ts +617 -0
  126. package/dist/esm/Journal.d.ts.map +1 -0
  127. package/dist/esm/Journal.js +323 -0
  128. package/dist/esm/Journal.js.map +1 -0
  129. package/dist/esm/JournalEvent.d.ts +421 -0
  130. package/dist/esm/JournalEvent.d.ts.map +1 -0
  131. package/dist/esm/JournalEvent.js +517 -0
  132. package/dist/esm/JournalEvent.js.map +1 -0
  133. package/dist/esm/JournalGeneration.d.ts +34 -0
  134. package/dist/esm/JournalGeneration.d.ts.map +1 -0
  135. package/dist/esm/JournalGeneration.js +65 -0
  136. package/dist/esm/JournalGeneration.js.map +1 -0
  137. package/dist/esm/JournalMetrics.d.ts +72 -0
  138. package/dist/esm/JournalMetrics.d.ts.map +1 -0
  139. package/dist/esm/JournalMetrics.js +79 -0
  140. package/dist/esm/JournalMetrics.js.map +1 -0
  141. package/dist/esm/Migrations.d.ts +42 -0
  142. package/dist/esm/Migrations.d.ts.map +1 -0
  143. package/dist/esm/Migrations.js +59 -0
  144. package/dist/esm/Migrations.js.map +1 -0
  145. package/dist/esm/OwnerId.d.ts +40 -0
  146. package/dist/esm/OwnerId.d.ts.map +1 -0
  147. package/dist/esm/OwnerId.js +33 -0
  148. package/dist/esm/OwnerId.js.map +1 -0
  149. package/dist/esm/Projection.d.ts +29 -0
  150. package/dist/esm/Projection.d.ts.map +1 -0
  151. package/dist/esm/Projection.js +13 -0
  152. package/dist/esm/Projection.js.map +1 -0
  153. package/dist/esm/RedactedLogger.d.ts +121 -0
  154. package/dist/esm/RedactedLogger.d.ts.map +1 -0
  155. package/dist/esm/RedactedLogger.js +445 -0
  156. package/dist/esm/RedactedLogger.js.map +1 -0
  157. package/dist/esm/Redaction.d.ts +350 -0
  158. package/dist/esm/Redaction.d.ts.map +1 -0
  159. package/dist/esm/Redaction.js +1584 -0
  160. package/dist/esm/Redaction.js.map +1 -0
  161. package/dist/esm/SqlConsensus.d.ts +44 -0
  162. package/dist/esm/SqlConsensus.d.ts.map +1 -0
  163. package/dist/esm/SqlConsensus.js +252 -0
  164. package/dist/esm/SqlConsensus.js.map +1 -0
  165. package/dist/esm/SqlJournal.d.ts +173 -0
  166. package/dist/esm/SqlJournal.d.ts.map +1 -0
  167. package/dist/esm/SqlJournal.js +1858 -0
  168. package/dist/esm/SqlJournal.js.map +1 -0
  169. package/dist/esm/StepFact.d.ts +66 -0
  170. package/dist/esm/StepFact.d.ts.map +1 -0
  171. package/dist/esm/StepFact.js +50 -0
  172. package/dist/esm/StepFact.js.map +1 -0
  173. package/dist/esm/index.d.ts +95 -0
  174. package/dist/esm/index.d.ts.map +1 -0
  175. package/dist/esm/index.js +95 -0
  176. package/dist/esm/index.js.map +1 -0
  177. package/dist/esm/internal/JournalInternalFault.d.ts +37 -0
  178. package/dist/esm/internal/JournalInternalFault.d.ts.map +1 -0
  179. package/dist/esm/internal/JournalInternalFault.js +28 -0
  180. package/dist/esm/internal/JournalInternalFault.js.map +1 -0
  181. package/dist/esm/migrations/0001_initial.d.ts +15 -0
  182. package/dist/esm/migrations/0001_initial.d.ts.map +1 -0
  183. package/dist/esm/migrations/0001_initial.js +32 -0
  184. package/dist/esm/migrations/0001_initial.js.map +1 -0
  185. package/dist/esm/migrations/0002_checkpoints.d.ts +27 -0
  186. package/dist/esm/migrations/0002_checkpoints.d.ts.map +1 -0
  187. package/dist/esm/migrations/0002_checkpoints.js +38 -0
  188. package/dist/esm/migrations/0002_checkpoints.js.map +1 -0
  189. package/dist/esm/migrations/0003_startup_index.d.ts +15 -0
  190. package/dist/esm/migrations/0003_startup_index.d.ts.map +1 -0
  191. package/dist/esm/migrations/0003_startup_index.js +18 -0
  192. package/dist/esm/migrations/0003_startup_index.js.map +1 -0
  193. package/dist/esm/migrations/0004_dedup.d.ts +15 -0
  194. package/dist/esm/migrations/0004_dedup.d.ts.map +1 -0
  195. package/dist/esm/migrations/0004_dedup.js +38 -0
  196. package/dist/esm/migrations/0004_dedup.js.map +1 -0
  197. package/dist/esm/migrations/0005_run_event_type.d.ts +15 -0
  198. package/dist/esm/migrations/0005_run_event_type.d.ts.map +1 -0
  199. package/dist/esm/migrations/0005_run_event_type.js +18 -0
  200. package/dist/esm/migrations/0005_run_event_type.js.map +1 -0
  201. package/dist/esm/migrations/0006_consensus.d.ts +22 -0
  202. package/dist/esm/migrations/0006_consensus.d.ts.map +1 -0
  203. package/dist/esm/migrations/0006_consensus.js +69 -0
  204. package/dist/esm/migrations/0006_consensus.js.map +1 -0
  205. package/dist/esm/test/Notifying.d.ts +65 -0
  206. package/dist/esm/test/Notifying.d.ts.map +1 -0
  207. package/dist/esm/test/Notifying.js +62 -0
  208. package/dist/esm/test/Notifying.js.map +1 -0
  209. package/dist/esm/test/TestJournal.d.ts +43 -0
  210. package/dist/esm/test/TestJournal.d.ts.map +1 -0
  211. package/dist/esm/test/TestJournal.js +27 -0
  212. package/dist/esm/test/TestJournal.js.map +1 -0
  213. package/docs/README.md +164 -0
  214. package/docs/api.md +639 -0
  215. package/docs/concepts/compaction.md +157 -0
  216. package/docs/concepts/idempotency.md +127 -0
  217. package/docs/concepts/owner-fence.md +124 -0
  218. package/docs/concepts/redaction.md +218 -0
  219. package/docs/concepts/state-event-authority.md +159 -0
  220. package/docs/concepts/two-channels.md +167 -0
  221. package/docs/guides/commit-state-and-entry.md +114 -0
  222. package/docs/guides/compact-a-run.md +134 -0
  223. package/docs/guides/fold-a-projection.md +106 -0
  224. package/docs/guides/read-a-run.md +139 -0
  225. package/docs/guides/redact-log-output.md +94 -0
  226. package/docs/guides/testing.md +124 -0
  227. package/docs/guides/write-lifecycle-events.md +110 -0
  228. package/docs/installation.md +133 -0
  229. package/docs/quickstart.md +143 -0
  230. package/docs/troubleshooting.md +214 -0
  231. package/package.json +263 -3
  232. package/src/CallFact.ts +117 -0
  233. package/src/Consensus.ts +683 -0
  234. package/src/EngineEvent.ts +823 -0
  235. package/src/ExecutionFact.ts +433 -0
  236. package/src/Journal.ts +688 -0
  237. package/src/JournalEvent.ts +654 -0
  238. package/src/JournalGeneration.ts +77 -0
  239. package/src/JournalMetrics.ts +89 -0
  240. package/src/Migrations.ts +62 -0
  241. package/src/OwnerId.ts +42 -0
  242. package/src/Projection.ts +31 -0
  243. package/src/RedactedLogger.ts +483 -0
  244. package/src/Redaction.ts +1784 -0
  245. package/src/SqlConsensus.ts +344 -0
  246. package/src/SqlJournal.ts +2732 -0
  247. package/src/StepFact.ts +69 -0
  248. package/src/index.ts +109 -0
  249. package/src/internal/JournalInternalFault.ts +40 -0
  250. package/src/migrations/0001_initial.ts +41 -0
  251. package/src/migrations/0002_checkpoints.ts +46 -0
  252. package/src/migrations/0003_startup_index.ts +19 -0
  253. package/src/migrations/0004_dedup.ts +43 -0
  254. package/src/migrations/0005_run_event_type.ts +19 -0
  255. package/src/migrations/0006_consensus.ts +83 -0
  256. package/src/test/Notifying.ts +101 -0
  257. package/src/test/TestJournal.ts +52 -0
@@ -0,0 +1,823 @@
1
+ /**
2
+ * Versioned engine history contracts over the open journal. These schemas do
3
+ * not change journal admission or make history the engine's recovery store.
4
+ *
5
+ * @since 1.0.0
6
+ */
7
+
8
+ import * as Cause from "effect/Cause"
9
+ import * as Effect from "effect/Effect"
10
+ import * as Schema from "effect/Schema"
11
+ import * as Event from "./JournalEvent.ts"
12
+
13
+ /**
14
+ * Required lineage coordinates for a root or derived run.
15
+ *
16
+ * @category schemas
17
+ * @since 1.0.0
18
+ */
19
+ export const Lineage = Schema.Union([
20
+ Schema.Struct({
21
+ kind: Schema.Literal("root"),
22
+ runId: Event.RunId,
23
+ lineageId: Event.LineageId,
24
+ rootRunId: Event.RunId,
25
+ round: Schema.Literal(0),
26
+ parentRunId: Schema.Null
27
+ }).check(Schema.makeFilter((value) => value.runId === value.rootRunId)),
28
+ Schema.Struct({
29
+ kind: Schema.Literals(["child", "fork", "continuation"]),
30
+ runId: Event.RunId,
31
+ lineageId: Event.LineageId,
32
+ rootRunId: Event.RunId,
33
+ round: Event.NonNegativeQuantity,
34
+ parentRunId: Event.RunId
35
+ }).check(Schema.makeFilter((value) =>
36
+ value.runId !== value.parentRunId && value.runId !== value.rootRunId &&
37
+ (value.kind !== "continuation" || value.round > 0)
38
+ ))
39
+ ])
40
+
41
+ /**
42
+ * Required lineage coordinates for a root or derived run.
43
+ *
44
+ * @category models
45
+ * @since 1.0.0
46
+ */
47
+ export type Lineage = typeof Lineage.Type
48
+
49
+ /**
50
+ * Encoded values only: class instances must first pass their own codec.
51
+ *
52
+ * @category schemas
53
+ * @since 1.0.0
54
+ */
55
+ export const Success = Schema.TaggedStruct("Success", { value: Schema.Json })
56
+
57
+ /**
58
+ * Failure channels stay distinct, including interruption and encoding failure.
59
+ *
60
+ * @category schemas
61
+ * @since 1.0.0
62
+ */
63
+ export const Failure = Schema.TaggedStruct("Failure", {
64
+ reason: Schema.Literals(["error", "defect", "interrupted", "encoding"]),
65
+ detail: Schema.Json
66
+ })
67
+
68
+ /**
69
+ * Encoded success or a classified failure.
70
+ *
71
+ * @category schemas
72
+ * @since 1.0.0
73
+ */
74
+ export const ResultEnvelope = Schema.Union([Success, Failure])
75
+ /**
76
+ * Encoded success or a classified failure.
77
+ *
78
+ * @category models
79
+ * @since 1.0.0
80
+ */
81
+ export type ResultEnvelope = typeof ResultEnvelope.Type
82
+
83
+ const timing = { startedAtMs: Event.TimestampMs }
84
+ const live = {
85
+ ...timing,
86
+ heartbeatAtMs: Schema.optionalKey(Event.TimestampMs),
87
+ checkpoint: Schema.optionalKey(Schema.Json),
88
+ finishedAtMs: Schema.optionalKey(Schema.Never),
89
+ result: Schema.optionalKey(Schema.Never)
90
+ }
91
+
92
+ /**
93
+ * Completion and its outcome are inseparable; live states cannot carry either.
94
+ *
95
+ * @category schemas
96
+ * @since 1.0.0
97
+ */
98
+ export const AttemptLifecycle = Schema.Union([
99
+ Schema.Struct({ state: Schema.Literal("running"), ...live }),
100
+ Schema.Struct({ state: Schema.Literal("suspended"), ...live }),
101
+ Schema.Struct({
102
+ state: Schema.Literal("succeeded"),
103
+ ...timing,
104
+ finishedAtMs: Event.TimestampMs,
105
+ result: Success
106
+ }),
107
+ Schema.Struct({
108
+ state: Schema.Literal("failed"),
109
+ ...timing,
110
+ finishedAtMs: Event.TimestampMs,
111
+ result: Failure
112
+ })
113
+ ])
114
+
115
+ /**
116
+ * Wall clocks can move backwards; completion need not be after start.
117
+ *
118
+ * @category models
119
+ * @since 1.0.0
120
+ */
121
+ export type AttemptLifecycle = typeof AttemptLifecycle.Type
122
+
123
+ /**
124
+ * Complete identity and state of one versioned attempt event.
125
+ *
126
+ * @category schemas
127
+ * @since 1.0.0
128
+ */
129
+ export const AttemptPayload = Schema.Struct({
130
+ version: Schema.Literal(2),
131
+ lineage: Lineage,
132
+ executionId: Event.RunId,
133
+ stepKeyDigest: Event.DispatchId,
134
+ attempt: Event.NonNegativeQuantity,
135
+ lifecycle: AttemptLifecycle
136
+ }).check(Schema.makeFilter((value) => value.executionId === value.lineage.runId))
137
+
138
+ /**
139
+ * Complete identity and state of one versioned attempt event.
140
+ *
141
+ * @category models
142
+ * @since 1.0.0
143
+ */
144
+ export type AttemptPayload = typeof AttemptPayload.Type
145
+
146
+ /**
147
+ * Durable wait identities; ownership and cancellation remain independent facts.
148
+ *
149
+ * @category schemas
150
+ * @since 1.0.0
151
+ */
152
+ export const Wait = Schema.Union([
153
+ Schema.TaggedStruct("Deferred", { waitId: Event.WaitId }),
154
+ Schema.TaggedStruct("Clock", { waitId: Event.WaitId, dueAtMs: Event.TimestampMs })
155
+ ])
156
+
157
+ /**
158
+ * A complete execution observation, without operational ownership leases.
159
+ *
160
+ * @category schemas
161
+ * @since 1.0.0
162
+ */
163
+ export const ExecutionLifecycle = Schema.Union([
164
+ Schema.Struct({ state: Schema.Literal("running"), waits: Schema.Array(Wait) }),
165
+ Schema.Struct({ state: Schema.Literal("suspended"), waits: Schema.NonEmptyArray(Wait) }),
166
+ Schema.Struct({ state: Schema.Literal("completed"), result: ResultEnvelope })
167
+ ])
168
+
169
+ /**
170
+ * Versioned execution, deferred and clock observations. Every variant records
171
+ * its semantic identity and encoded value independently of diagnostics.
172
+ *
173
+ * @category schemas
174
+ * @since 1.0.0
175
+ */
176
+ export const StatePayload = Schema.Struct({
177
+ version: Schema.Literal(2),
178
+ lineage: Lineage,
179
+ executionId: Event.RunId,
180
+ event: Schema.Union([
181
+ Schema.TaggedStruct("Execution", { lifecycle: ExecutionLifecycle }),
182
+ Schema.TaggedStruct("DeferredCompleted", { waitId: Event.WaitId, result: ResultEnvelope }),
183
+ Schema.TaggedStruct("ClockScheduled", {
184
+ clockId: Event.CommandId,
185
+ waitId: Event.WaitId,
186
+ dueAtMs: Event.TimestampMs
187
+ })
188
+ ])
189
+ }).check(Schema.makeFilter((value) => value.executionId === value.lineage.runId))
190
+
191
+ /**
192
+ * Versioned execution, deferred and clock observations.
193
+ *
194
+ * @category models
195
+ * @since 1.0.0
196
+ */
197
+ export type StatePayload = typeof StatePayload.Type
198
+
199
+ /**
200
+ * Event family for complete execution, deferred and clock observations.
201
+ *
202
+ * @category constants
203
+ * @since 1.0.0
204
+ */
205
+ export const stateEventType = "flows.engine.v2.state-event"
206
+
207
+ /**
208
+ * New identity prevents old readers mistaking complete state for historical markers.
209
+ *
210
+ * @category constants
211
+ * @since 1.0.0
212
+ */
213
+ export const attemptEventType = "flows.engine.v2.attempt-lifecycle"
214
+
215
+ /**
216
+ * Malformed, foreign, unsupported or inconsistent event evidence.
217
+ *
218
+ * @category errors
219
+ * @since 1.0.0
220
+ */
221
+ export class EventError extends Schema.TaggedError<EventError>()("@smthrs/journal/EngineEventError", {
222
+ code: Schema.Literals(["malformed", "unsupported", "foreign", "transition"]),
223
+ message: Schema.String,
224
+ cause: Schema.Unknown
225
+ }) {}
226
+
227
+ /**
228
+ * Every consumer chooses its source allowlist and unknown-namespace policy.
229
+ *
230
+ * @category models
231
+ * @since 1.0.0
232
+ */
233
+ export interface Consumer {
234
+ readonly runId: Event.RunId
235
+ readonly lineageId: Event.LineageId
236
+ readonly rootRunId: Event.RunId
237
+ readonly round: number
238
+ readonly parentRunId: Event.RunId | null
239
+ readonly sources: ReadonlyArray<Event.SourceId>
240
+ readonly unknown: "ignore" | "surface"
241
+ }
242
+
243
+ /**
244
+ * A known event or the explicitly selected extension outcome.
245
+ *
246
+ * @category models
247
+ * @since 1.0.0
248
+ */
249
+ export type Decoded =
250
+ | { readonly _tag: "Attempt"; readonly entry: Event.Entry; readonly payload: AttemptPayload }
251
+ | { readonly _tag: "State"; readonly entry: Event.Entry; readonly payload: StatePayload }
252
+ | { readonly _tag: "Ignored" }
253
+ | { readonly _tag: "Unknown"; readonly entry: Event.Entry }
254
+
255
+ const strict = { onExcessProperty: "error" } as const
256
+ const decodeRow = (input: unknown) =>
257
+ Effect.gen(function*() {
258
+ const raw = yield* Schema.decodeUnknownEffect(Schema.toEncoded(Event.Entry))(input)
259
+ return yield* Schema.decodeUnknownEffect(Event.Entry)(raw)
260
+ })
261
+ const decodePayload = Schema.decodeUnknownSync(AttemptPayload, strict)
262
+ const decodeJson = Schema.decodeUnknownSync(Schema.Json)
263
+
264
+ /**
265
+ * Decode untrusted committed input. Unknown events in the known engine namespace
266
+ * are unsupported errors, never ignored. Original schema/accessor errors stay
267
+ * in cause; foreign identity includes the conflicting evidence in cause.
268
+ *
269
+ * @category decoders
270
+ * @since 1.0.0
271
+ */
272
+ export const decodeEntry = (input: unknown, consumer: Consumer): Effect.Effect<Decoded, EventError> =>
273
+ Effect.gen(function*(): Effect.fn.Return<Decoded, unknown> {
274
+ const entry = yield* decodeRow(input)
275
+ if (entry.runId !== consumer.runId || !consumer.sources.includes(entry.sourceId)) {
276
+ throw new EventError({
277
+ code: "foreign",
278
+ message: "event run or source is outside the consumer scope",
279
+ cause: entry
280
+ })
281
+ }
282
+ if (entry.eventType !== attemptEventType && entry.eventType !== stateEventType) {
283
+ if (entry.eventType.startsWith("flows.engine.")) {
284
+ throw new EventError({
285
+ code: "unsupported",
286
+ message: "unsupported engine event family or version",
287
+ cause: entry
288
+ })
289
+ }
290
+ return consumer.unknown === "ignore" ? { _tag: "Ignored" } : { _tag: "Unknown", entry }
291
+ }
292
+ const decoded = entry.eventType === attemptEventType
293
+ ? { _tag: "Attempt" as const, payload: yield* Schema.decodeUnknownEffect(AttemptPayload, strict)(entry.payload) }
294
+ : { _tag: "State" as const, payload: yield* Schema.decodeUnknownEffect(StatePayload, strict)(entry.payload) }
295
+ const { payload } = decoded
296
+ if (
297
+ payload.lineage.runId !== entry.runId || payload.lineage.lineageId !== consumer.lineageId ||
298
+ payload.lineage.rootRunId !== consumer.rootRunId || payload.lineage.round !== consumer.round ||
299
+ payload.lineage.parentRunId !== consumer.parentRunId
300
+ ) {
301
+ throw new EventError({
302
+ code: "foreign",
303
+ message: "event lineage disagrees with its journal or consumer",
304
+ cause: payload.lineage
305
+ })
306
+ }
307
+ // The optional journal side channel is disclosure only. Semantic lineage
308
+ // lives in payload and cannot be replaced by diagnostic metadata.
309
+ yield* Schema.decodeUnknownEffect(Schema.Json)(entry.meta)
310
+ return { ...decoded, entry }
311
+ }).pipe(Effect.catchCause((failure) => {
312
+ const cause = Cause.squash(failure)
313
+ return Effect.fail(
314
+ cause instanceof EventError
315
+ ? cause
316
+ : new EventError({ code: "malformed", message: "invalid engine event", cause })
317
+ )
318
+ }))
319
+
320
+ /**
321
+ * Construct a versioned submission, validating before journal redaction.
322
+ *
323
+ * @category constructors
324
+ * @since 1.0.0
325
+ */
326
+ export const attempt = (
327
+ payload: AttemptPayload,
328
+ sourceId: Event.SourceId,
329
+ sourceSeq: Event.SourceSeq,
330
+ diagnostics: Schema.Json = null
331
+ ): Event.Input => {
332
+ const validated = decodePayload(payload)
333
+ return new Event.Input({
334
+ runId: validated.lineage.runId,
335
+ sourceId,
336
+ sourceSeq,
337
+ eventType: attemptEventType,
338
+ payload: validated,
339
+ meta: decodeJson(diagnostics)
340
+ })
341
+ }
342
+
343
+ /**
344
+ * Construct a versioned execution, deferred or clock submission. Existing
345
+ * unversioned writers are unchanged and cannot manufacture missing lineage.
346
+ *
347
+ * @category constructors
348
+ * @since 1.0.0
349
+ */
350
+ export const stateEvent = (
351
+ payload: StatePayload,
352
+ sourceId: Event.SourceId,
353
+ sourceSeq: Event.SourceSeq,
354
+ diagnostics: Schema.Json = null
355
+ ): Event.Input => {
356
+ const validated = Schema.decodeUnknownSync(StatePayload, strict)(payload)
357
+ return new Event.Input({
358
+ runId: validated.lineage.runId,
359
+ sourceId,
360
+ sourceSeq,
361
+ eventType: stateEventType,
362
+ payload: validated,
363
+ meta: decodeJson(diagnostics)
364
+ })
365
+ }
366
+
367
+ /**
368
+ * Historical attempt markers deliberately remain incomplete evidence. No
369
+ * result, timestamp, round or lineage root is invented for old rows.
370
+ *
371
+ * @category schemas
372
+ * @since 1.0.0
373
+ */
374
+ export const CurrentAttempt = Schema.Union([
375
+ Schema.Struct({
376
+ eventType: Schema.Literal("flows.engine.attempt-started"),
377
+ payload: Schema.Struct({
378
+ version: Schema.optionalKey(Schema.Never),
379
+ runId: Event.RunId,
380
+ stepKeyDigest: Event.DispatchId,
381
+ attempt: Event.NonNegativeQuantity,
382
+ tier: Schema.Literals(["sealed", "compensable", "irreversible"])
383
+ })
384
+ }),
385
+ Schema.Struct({
386
+ eventType: Schema.Literal("flows.engine.attempt-finished"),
387
+ payload: Schema.Struct({
388
+ version: Schema.optionalKey(Schema.Never),
389
+ runId: Event.RunId,
390
+ stepKeyDigest: Event.DispatchId,
391
+ attempt: Event.NonNegativeQuantity,
392
+ state: Schema.Literals(["succeeded", "failed"])
393
+ })
394
+ })
395
+ ])
396
+
397
+ /**
398
+ * Decode current markers using their recorded lineage, without upgrading bytes.
399
+ *
400
+ * @category decoders
401
+ * @since 1.0.0
402
+ */
403
+ export const decodeCurrentAttempt = (input: unknown, consumer: Consumer) =>
404
+ Effect.gen(function*() {
405
+ const entry = yield* decodeRow(input)
406
+ const marker = yield* Schema.decodeUnknownEffect(CurrentAttempt)(entry)
407
+ const meta = yield* Schema.decodeUnknownEffect(Schema.Struct({ lineageId: Event.LineageId }))(entry.meta)
408
+ if (
409
+ entry.runId !== consumer.runId || marker.payload.runId !== entry.runId ||
410
+ meta.lineageId !== consumer.lineageId || !consumer.sources.includes(entry.sourceId)
411
+ ) {
412
+ throw new EventError({
413
+ code: "foreign",
414
+ message: "current attempt marker is outside the consumer scope",
415
+ cause: entry
416
+ })
417
+ }
418
+ return { entry, marker, lineageId: meta.lineageId }
419
+ }).pipe(Effect.catchCause((failure) => {
420
+ const cause = Cause.squash(failure)
421
+ return Effect.fail(
422
+ cause instanceof EventError
423
+ ? cause
424
+ : new EventError({ code: "malformed", message: "invalid current attempt marker", cause })
425
+ )
426
+ }))
427
+
428
+ /**
429
+ * Where a declaration was written, as a durable record may carry it.
430
+ *
431
+ * Repo-relative by contract: a journal is read on machines that are not the
432
+ * one that wrote it, so an absolute path is at best noise and at worst an
433
+ * operator's home directory published into a run's history. A writer that
434
+ * cannot make a path relative omits the field.
435
+ *
436
+ * @category schemas
437
+ * @since 1.0.0
438
+ */
439
+ export const DeclaredAt = Schema.Struct({
440
+ path: Schema.NonEmptyString.check(Schema.makeFilter((value) => !value.startsWith("/"))),
441
+ line: Event.NonNegativeQuantity
442
+ })
443
+
444
+ /**
445
+ * A root that names the whole filesystem, which is no root at all.
446
+ *
447
+ * `process.cwd()` is `"/"` for a host a launcher started outside any
448
+ * directory, and relativizing against it would make every absolute path
449
+ * "relative": an operator's home directory, minus one leading slash, written
450
+ * into a run's permanent history. The empty string is the same statement, and
451
+ * a Windows drive root (`C:` or `C:\`) is the same statement again. @private
452
+ */
453
+ const isFilesystemRoot = (root: string): boolean => root === "" || root === "/" || /^[A-Za-z]:[\\/]?$/.test(root)
454
+
455
+ /**
456
+ * A declaration path as {@link DeclaredAt} may carry it: relative to the
457
+ * root, or nothing.
458
+ *
459
+ * It lives beside the schema that refuses an absolute path, because obeying
460
+ * that refusal is the writer's one job and every writer obeys it the same
461
+ * way. A path outside the root is omitted rather than recorded with `..`
462
+ * segments, because a reader resolving those would have to know the root,
463
+ * which is exactly the machine-specific fact this strips. A root that is the
464
+ * filesystem itself strips nothing, so it is read as no root.
465
+ *
466
+ * @category accessors
467
+ * @since 1.0.0
468
+ */
469
+ export const relativePath = (root: string | undefined, path: string): string | undefined => {
470
+ if (root === undefined || isFilesystemRoot(root) || path === "") return undefined
471
+ const base = root.endsWith("/") ? root : `${root}/`
472
+ if (!path.startsWith(base)) return undefined
473
+ const relative = path.slice(base.length)
474
+ return relative === "" ? undefined : relative
475
+ }
476
+
477
+ /**
478
+ * One node of the graph a run was driven from.
479
+ *
480
+ * `kind` is open text because the two executors name kinds differently and
481
+ * both are true: the plan scheduler's node is a `step`, an `agent` or a
482
+ * `merge`, while the interpreter's is the authoring variant it was observed
483
+ * at. A closed union here would force one of them to lie.
484
+ *
485
+ * @category schemas
486
+ * @since 1.0.0
487
+ */
488
+ export const NodeSummary = Schema.Struct({
489
+ id: Schema.NonEmptyString,
490
+ kind: Schema.String,
491
+ dependsOn: Schema.Array(Schema.NonEmptyString),
492
+ tier: Schema.Literals(["sealed", "compensable", "irreversible"]),
493
+ key: Schema.optionalKey(Schema.String),
494
+ generation: Schema.optionalKey(Event.NonNegativeQuantity),
495
+ action: Schema.optionalKey(Schema.String),
496
+ effects: Schema.optionalKey(Schema.Json),
497
+ declaredAt: Schema.optionalKey(DeclaredAt)
498
+ })
499
+
500
+ /**
501
+ * One edge of that graph, with the reason the builder drew it.
502
+ *
503
+ * @category schemas
504
+ * @since 1.0.0
505
+ */
506
+ export const EdgeSummary = Schema.Struct({
507
+ from: Schema.NonEmptyString,
508
+ to: Schema.NonEmptyString,
509
+ reason: Schema.Literals(["value", "continuation", "failure"])
510
+ })
511
+
512
+ /**
513
+ * The immutable name of a tree a host read declaration sites out of.
514
+ *
515
+ * Exactly the forty lowercase hex digits the only producer emits: a jj
516
+ * working-copy commit id, or a git commit for a tree that still matches one
517
+ * (`SourceRevision.objectId`). It is narrowed here rather than left as text
518
+ * because a reader puts it straight into a contents route's `?ref=`, and
519
+ * `DeclaredAt` beside it refuses an absolute path for the same class of
520
+ * reason: a field that only ever holds one shape should refuse the others at
521
+ * the boundary rather than at whatever spawns a process downstream.
522
+ *
523
+ * @category schemas
524
+ * @since 1.0.0
525
+ */
526
+ export const SourceRevision = Schema.NonEmptyString.check(Schema.makeFilter((value) => /^[0-9a-f]{40}$/.test(value)))
527
+
528
+ /**
529
+ * The graph, or one page of it, carried beside a plan record.
530
+ *
531
+ * `edges` is optional because only one writer can answer it honestly. A plan
532
+ * names its edges through each node's `dependsOn` and knows no reason for
533
+ * them; an interpreter knows the reason it drew each one. A writer without
534
+ * reasons omits the field rather than labelling every edge `value`.
535
+ *
536
+ * @category schemas
537
+ * @since 1.0.0
538
+ */
539
+ export const NodeGraph = Schema.Struct({
540
+ nodes: Schema.Array(NodeSummary),
541
+ edges: Schema.optionalKey(Schema.Array(EdgeSummary)),
542
+ /**
543
+ * The revision of the tree the nodes on this page were read out of.
544
+ *
545
+ * A `declaredAt` is a path and a line, and neither says which bytes were
546
+ * at that line: a working tree moves, so the same path after an edit or a
547
+ * branch switch is a different file. Only the writer can answer this —
548
+ * like the root a path is made relative to — so it travels with the page
549
+ * the sites travel on, and a reader can ask for the file AT this revision
550
+ * instead of whatever is on disk when they look.
551
+ *
552
+ * Optional because only a writer served out of a version-controlled tree
553
+ * can name one. A writer that cannot says nothing, and a reader that has
554
+ * nothing shows no code rather than code it cannot bind (D-068).
555
+ */
556
+ sourceRevision: Schema.optionalKey(SourceRevision)
557
+ })
558
+
559
+ /**
560
+ * A plan was recorded and a run is about to be driven under it.
561
+ *
562
+ * `nodes` is the node COUNT the record has always carried. The node list
563
+ * arrives beside it as `graph`, optional and paged, because a journal entry
564
+ * has a byte bound: what does not fit follows as {@link SubgraphAppended}
565
+ * pages rather than being clipped.
566
+ *
567
+ * Everything an executor cannot honestly answer is optional rather than
568
+ * invented. The interpreter drives a graph with no plan id, no plan digest
569
+ * and no store to record an outcome with, and saying so is the point of this
570
+ * schema.
571
+ *
572
+ * @category schemas
573
+ * @since 1.0.0
574
+ */
575
+ export const PlanRecordedPayload = Schema.Struct({
576
+ planId: Schema.optionalKey(Schema.NonEmptyString),
577
+ flow: Schema.NonEmptyString,
578
+ digest: Schema.optionalKey(Schema.String),
579
+ baseDigest: Schema.optionalKey(Schema.String),
580
+ generation: Event.NonNegativeQuantity,
581
+ nodes: Event.NonNegativeQuantity,
582
+ outcome: Schema.optionalKey(Schema.String),
583
+ page: Schema.optionalKey(Event.NonNegativeQuantity),
584
+ pages: Schema.optionalKey(Event.NonNegativeQuantity),
585
+ graph: Schema.optionalKey(NodeGraph)
586
+ })
587
+
588
+ /**
589
+ * An elaboration appended a pre-keyed subgraph to the same plan, or the next
590
+ * page of a graph too large for one record.
591
+ *
592
+ * @category schemas
593
+ * @since 1.0.0
594
+ */
595
+ export const SubgraphAppendedPayload = Schema.Struct({
596
+ planId: Schema.optionalKey(Schema.NonEmptyString),
597
+ flow: Schema.optionalKey(Schema.NonEmptyString),
598
+ digest: Schema.optionalKey(Schema.String),
599
+ baseDigest: Schema.optionalKey(Schema.String),
600
+ generation: Event.NonNegativeQuantity,
601
+ nodeIds: Schema.Array(Schema.NonEmptyString),
602
+ page: Schema.optionalKey(Event.NonNegativeQuantity),
603
+ pages: Schema.optionalKey(Event.NonNegativeQuantity),
604
+ graph: Schema.optionalKey(NodeGraph)
605
+ })
606
+
607
+ /**
608
+ * A plan node was admitted and its work is about to start.
609
+ *
610
+ * @category schemas
611
+ * @since 1.0.0
612
+ */
613
+ export const NodeScheduledPayload = Schema.Struct({
614
+ planId: Schema.optionalKey(Schema.NonEmptyString),
615
+ nodeId: Schema.NonEmptyString,
616
+ kind: Schema.String,
617
+ planKey: Schema.optionalKey(Schema.String),
618
+ dispatchKey: Schema.optionalKey(Schema.String),
619
+ attempt: Event.PositiveQuantity,
620
+ priority: Schema.optionalKey(Schema.Int),
621
+ waited: Schema.optionalKey(Event.NonNegativeQuantity),
622
+ action: Schema.optionalKey(Schema.String)
623
+ })
624
+
625
+ /**
626
+ * A bounded look at what a node settled with.
627
+ *
628
+ * `preview` is JSON text, redacted before it was encoded and cut to a fixed
629
+ * ceiling afterwards, so a long value costs a durable row a known number of
630
+ * bytes rather than however many it happens to hold. `truncated` says the cut
631
+ * happened, which is also the warning that the text is a PREFIX of JSON and
632
+ * no longer parses. `bytes` is the size of the encoding the preview was cut
633
+ * from, so a reader can say how much was left out without being shown it; a
634
+ * value too large for a writer to redact at all is named by the size of its
635
+ * own encoding, with an empty preview and the flag set.
636
+ *
637
+ * Redaction comes first and truncation second on purpose: cutting the text
638
+ * first can split a credential across the boundary, and a textual redactor
639
+ * scanning the remains would no longer recognise it.
640
+ *
641
+ * @category schemas
642
+ * @since 1.0.0
643
+ */
644
+ export const NodeResultSummary = Schema.Struct({
645
+ preview: Schema.String,
646
+ bytes: Event.NonNegativeQuantity,
647
+ truncated: Schema.Boolean
648
+ })
649
+
650
+ /**
651
+ * A plan node reached an outcome.
652
+ *
653
+ * The outcomes are Skyframe's evaluation states: `built` ran,
654
+ * `clean` was served from records, `failed` raised, `skipped` was never
655
+ * reached, and `deferred` is a scheduling debt the plan scheduler alone
656
+ * records.
657
+ *
658
+ * `attempts` is the executor's own count. For the plan scheduler it is the
659
+ * node's; for the interpreter it is the highest durable attempt any of this
660
+ * node's dispatches ran as, because the interpreter settles each node once
661
+ * and a retry happens underneath it inside one dispatch.
662
+ *
663
+ * `stepKeyDigests` names the dispatches the node drove, and it is the join
664
+ * `flows.engine.attempt-started` could not make on its own: an attempt record
665
+ * carries a step key digest and no node id, so an attempt belongs to the node
666
+ * whose settlement claims its digest. A retried dispatch keeps ONE digest —
667
+ * the attempt is folded into no key — so the list is distinct dispatches, not
668
+ * attempts. A writer that derives no digests omits the field; a node that
669
+ * dispatched nothing records an empty list, which is a different statement.
670
+ *
671
+ * `result` is what the node settled with: the success value for `built` and
672
+ * `clean`, the typed failure for `failed`, bounded and redacted by the writer.
673
+ * Absent when the writer kept none.
674
+ *
675
+ * @category schemas
676
+ * @since 1.0.0
677
+ */
678
+ export const NodeSettledPayload = Schema.Struct({
679
+ planId: Schema.optionalKey(Schema.NonEmptyString),
680
+ nodeId: Schema.NonEmptyString,
681
+ planKey: Schema.optionalKey(Schema.String),
682
+ dispatchKey: Schema.optionalKey(Schema.String),
683
+ stepKeyDigests: Schema.optionalKey(Schema.Array(Schema.NonEmptyString)),
684
+ outcome: Schema.Literals(["built", "clean", "failed", "skipped", "deferred"]),
685
+ attempts: Event.NonNegativeQuantity,
686
+ rebases: Schema.optionalKey(Event.NonNegativeQuantity),
687
+ action: Schema.optionalKey(Schema.String),
688
+ result: Schema.optionalKey(NodeResultSummary)
689
+ })
690
+
691
+ /**
692
+ * A scheduled node's dispatch identity was invalidated and re-keyed.
693
+ *
694
+ * @category schemas
695
+ * @since 1.0.0
696
+ */
697
+ export const NodeInvalidatedPayload = Schema.Struct({
698
+ planId: Schema.NonEmptyString,
699
+ nodeId: Schema.NonEmptyString,
700
+ planKey: Schema.String,
701
+ from: Schema.String,
702
+ to: Schema.String,
703
+ reason: Schema.Literal("measured-inputs-changed")
704
+ })
705
+
706
+ /**
707
+ * The reconciliation seam returned a verdict for a deviation.
708
+ *
709
+ * @category schemas
710
+ * @since 1.0.0
711
+ */
712
+ export const NodeReconciledPayload = Schema.Struct({
713
+ planId: Schema.NonEmptyString,
714
+ nodeId: Schema.NonEmptyString,
715
+ trigger: Schema.String,
716
+ verdict: Schema.Json
717
+ })
718
+
719
+ /**
720
+ * Where a declaration was written, as a durable record carries it.
721
+ *
722
+ * @category models
723
+ * @since 1.0.0
724
+ */
725
+ export type DeclaredAt = typeof DeclaredAt.Type
726
+
727
+ /**
728
+ * One node of the graph a run was driven from.
729
+ *
730
+ * @category models
731
+ * @since 1.0.0
732
+ */
733
+ export type NodeSummary = typeof NodeSummary.Type
734
+
735
+ /**
736
+ * One edge of the graph a run was driven from.
737
+ *
738
+ * @category models
739
+ * @since 1.0.0
740
+ */
741
+ export type EdgeSummary = typeof EdgeSummary.Type
742
+
743
+ /**
744
+ * The graph, or one page of it, carried beside a plan record.
745
+ *
746
+ * @category models
747
+ * @since 1.0.0
748
+ */
749
+ export type NodeGraph = typeof NodeGraph.Type
750
+
751
+ /**
752
+ * A plan was recorded and a run is about to be driven under it.
753
+ *
754
+ * @category models
755
+ * @since 1.0.0
756
+ */
757
+ export type PlanRecordedPayload = typeof PlanRecordedPayload.Type
758
+
759
+ /**
760
+ * An elaboration appended a subgraph, or the next page of a large graph.
761
+ *
762
+ * @category models
763
+ * @since 1.0.0
764
+ */
765
+ export type SubgraphAppendedPayload = typeof SubgraphAppendedPayload.Type
766
+
767
+ /**
768
+ * A plan node was admitted and its work is about to start.
769
+ *
770
+ * @category models
771
+ * @since 1.0.0
772
+ */
773
+ export type NodeScheduledPayload = typeof NodeScheduledPayload.Type
774
+
775
+ /**
776
+ * A bounded look at what a node settled with.
777
+ *
778
+ * @category models
779
+ * @since 1.0.0
780
+ */
781
+ export type NodeResultSummary = typeof NodeResultSummary.Type
782
+
783
+ /**
784
+ * A plan node reached an outcome.
785
+ *
786
+ * @category models
787
+ * @since 1.0.0
788
+ */
789
+ export type NodeSettledPayload = typeof NodeSettledPayload.Type
790
+
791
+ /**
792
+ * A scheduled node's dispatch identity was invalidated and re-keyed.
793
+ *
794
+ * @category models
795
+ * @since 1.0.0
796
+ */
797
+ export type NodeInvalidatedPayload = typeof NodeInvalidatedPayload.Type
798
+
799
+ /**
800
+ * The reconciliation seam's verdict for one deviation.
801
+ *
802
+ * @category models
803
+ * @since 1.0.0
804
+ */
805
+ export type NodeReconciledPayload = typeof NodeReconciledPayload.Type
806
+
807
+ /**
808
+ * The event type each node and plan payload is recorded under.
809
+ *
810
+ * Readers and writers share these identities, so a value here is stored
811
+ * history and changing one requires migrating it.
812
+ *
813
+ * @category constants
814
+ * @since 1.0.0
815
+ */
816
+ export const nodeEventTypes = {
817
+ planRecorded: "flows.engine.plan-recorded",
818
+ subgraphAppended: "flows.engine.subgraph-appended",
819
+ nodeScheduled: "flows.engine.node-scheduled",
820
+ nodeSettled: "flows.engine.node-settled",
821
+ nodeInvalidated: "flows.engine.node-invalidated",
822
+ nodeReconciled: "flows.engine.node-reconciled"
823
+ } as const