@typeonce/effect-machine 0.3.0 → 0.5.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (170) hide show
  1. package/README.md +410 -17
  2. package/dist/Machine.d.ts +1191 -510
  3. package/dist/Machine.d.ts.map +1 -1
  4. package/dist/Machine.js +371 -565
  5. package/dist/Machine.js.map +1 -1
  6. package/dist/internal/machine/activities.d.ts +57 -0
  7. package/dist/internal/machine/activities.d.ts.map +1 -0
  8. package/dist/internal/machine/activities.js +49 -0
  9. package/dist/internal/machine/activities.js.map +1 -0
  10. package/dist/internal/machine/atom.d.ts +69 -0
  11. package/dist/internal/machine/atom.d.ts.map +1 -0
  12. package/dist/{AtomMachine.js → internal/machine/atom.js} +20 -95
  13. package/dist/internal/machine/atom.js.map +1 -0
  14. package/dist/internal/machine/cluster.d.ts +63 -0
  15. package/dist/internal/machine/cluster.d.ts.map +1 -0
  16. package/dist/{ClusterMachine.js → internal/machine/cluster.js} +15 -119
  17. package/dist/internal/machine/cluster.js.map +1 -0
  18. package/dist/internal/machine/command.d.ts +16 -0
  19. package/dist/internal/machine/command.d.ts.map +1 -0
  20. package/dist/internal/machine/command.js +45 -0
  21. package/dist/internal/machine/command.js.map +1 -0
  22. package/dist/internal/machine/commandRuntime.d.ts +13 -0
  23. package/dist/internal/machine/commandRuntime.d.ts.map +1 -0
  24. package/dist/internal/machine/commandRuntime.js +16 -0
  25. package/dist/internal/machine/commandRuntime.js.map +1 -0
  26. package/dist/internal/{machineModel.d.ts → machine/configuration.d.ts} +12 -61
  27. package/dist/internal/machine/configuration.d.ts.map +1 -0
  28. package/dist/internal/{machineModel.js → machine/configuration.js} +250 -545
  29. package/dist/internal/machine/configuration.js.map +1 -0
  30. package/dist/internal/{machineErrors.d.ts → machine/errors.d.ts} +8 -8
  31. package/dist/internal/machine/errors.d.ts.map +1 -0
  32. package/dist/internal/{machineErrors.js → machine/errors.js} +8 -8
  33. package/dist/internal/machine/errors.js.map +1 -0
  34. package/dist/internal/machine/executionPlan.d.ts +49 -0
  35. package/dist/internal/machine/executionPlan.d.ts.map +1 -0
  36. package/dist/internal/machine/executionPlan.js +676 -0
  37. package/dist/internal/machine/executionPlan.js.map +1 -0
  38. package/dist/internal/machine/invocation.d.ts +23 -0
  39. package/dist/internal/machine/invocation.d.ts.map +1 -0
  40. package/dist/internal/machine/invocation.js +77 -0
  41. package/dist/internal/machine/invocation.js.map +1 -0
  42. package/dist/internal/machine/machine.d.ts +183 -0
  43. package/dist/internal/machine/machine.d.ts.map +1 -0
  44. package/dist/internal/machine/machine.js +552 -0
  45. package/dist/internal/machine/machine.js.map +1 -0
  46. package/dist/internal/machine/planner.d.ts +182 -0
  47. package/dist/internal/machine/planner.d.ts.map +1 -0
  48. package/dist/internal/machine/planner.js +1082 -0
  49. package/dist/internal/machine/planner.js.map +1 -0
  50. package/dist/internal/{machineProcess.d.ts → machine/process.d.ts} +11 -5
  51. package/dist/internal/machine/process.d.ts.map +1 -0
  52. package/dist/internal/machine/process.js +498 -0
  53. package/dist/internal/machine/process.js.map +1 -0
  54. package/dist/internal/machine/protocol.d.ts +34 -0
  55. package/dist/internal/machine/protocol.d.ts.map +1 -0
  56. package/dist/internal/machine/protocol.js +182 -0
  57. package/dist/internal/machine/protocol.js.map +1 -0
  58. package/dist/internal/machine/readiness.d.ts +4 -0
  59. package/dist/internal/machine/readiness.d.ts.map +1 -0
  60. package/dist/internal/machine/readiness.js +2 -0
  61. package/dist/internal/machine/readiness.js.map +1 -0
  62. package/dist/internal/machine/runtime.d.ts +255 -0
  63. package/dist/internal/machine/runtime.d.ts.map +1 -0
  64. package/dist/internal/machine/runtime.js +1489 -0
  65. package/dist/internal/machine/runtime.js.map +1 -0
  66. package/dist/internal/machine/serialization.d.ts +14 -0
  67. package/dist/internal/machine/serialization.d.ts.map +1 -0
  68. package/dist/internal/machine/serialization.js +338 -0
  69. package/dist/internal/machine/serialization.js.map +1 -0
  70. package/dist/internal/machine/stateDefinition.d.ts +15 -0
  71. package/dist/internal/machine/stateDefinition.d.ts.map +1 -0
  72. package/dist/internal/machine/stateDefinition.js +210 -0
  73. package/dist/internal/machine/stateDefinition.js.map +1 -0
  74. package/dist/internal/machine/symbols.d.ts +3 -0
  75. package/dist/internal/machine/symbols.d.ts.map +1 -0
  76. package/dist/internal/machine/symbols.js +3 -0
  77. package/dist/internal/machine/symbols.js.map +1 -0
  78. package/dist/internal/machine/topology.d.ts +98 -0
  79. package/dist/internal/machine/topology.d.ts.map +1 -0
  80. package/dist/internal/machine/topology.js +347 -0
  81. package/dist/internal/machine/topology.js.map +1 -0
  82. package/dist/internal/testing/machine/arbitrary.d.ts +36 -0
  83. package/dist/internal/testing/machine/arbitrary.d.ts.map +1 -0
  84. package/dist/internal/testing/machine/arbitrary.js +68 -0
  85. package/dist/internal/testing/machine/arbitrary.js.map +1 -0
  86. package/dist/internal/testing/machine/exploration.d.ts +30 -0
  87. package/dist/internal/testing/machine/exploration.d.ts.map +1 -0
  88. package/dist/internal/testing/machine/exploration.js +237 -0
  89. package/dist/internal/testing/machine/exploration.js.map +1 -0
  90. package/dist/internal/testing/machine/finiteModel.d.ts +322 -0
  91. package/dist/internal/testing/machine/finiteModel.d.ts.map +1 -0
  92. package/dist/internal/testing/machine/finiteModel.js +976 -0
  93. package/dist/internal/testing/machine/finiteModel.js.map +1 -0
  94. package/dist/internal/testing/machine/invariant.d.ts +31 -0
  95. package/dist/internal/testing/machine/invariant.d.ts.map +1 -0
  96. package/dist/internal/testing/machine/invariant.js +214 -0
  97. package/dist/internal/testing/machine/invariant.js.map +1 -0
  98. package/dist/internal/testing/machine/probe.d.ts +26 -0
  99. package/dist/internal/testing/machine/probe.d.ts.map +1 -0
  100. package/dist/internal/testing/machine/probe.js +45 -0
  101. package/dist/internal/testing/machine/probe.js.map +1 -0
  102. package/dist/internal/testing/machine/referenceModel.d.ts +203 -0
  103. package/dist/internal/testing/machine/referenceModel.d.ts.map +1 -0
  104. package/dist/internal/testing/machine/referenceModel.js +1012 -0
  105. package/dist/internal/testing/machine/referenceModel.js.map +1 -0
  106. package/dist/internal/testing/machine/runtime.d.ts +631 -0
  107. package/dist/internal/testing/machine/runtime.d.ts.map +1 -0
  108. package/dist/internal/testing/machine/runtime.js +726 -0
  109. package/dist/internal/testing/machine/runtime.js.map +1 -0
  110. package/dist/internal/testing/machine/runtimeInvariant.d.ts +32 -0
  111. package/dist/internal/testing/machine/runtimeInvariant.d.ts.map +1 -0
  112. package/dist/internal/testing/machine/runtimeInvariant.js +334 -0
  113. package/dist/internal/testing/machine/runtimeInvariant.js.map +1 -0
  114. package/dist/internal/testing/machine/trace.d.ts +17 -0
  115. package/dist/internal/testing/machine/trace.d.ts.map +1 -0
  116. package/dist/internal/testing/machine/trace.js +94 -0
  117. package/dist/internal/testing/machine/trace.js.map +1 -0
  118. package/dist/internal/testing/machine/verification.d.ts +36 -0
  119. package/dist/internal/testing/machine/verification.d.ts.map +1 -0
  120. package/dist/internal/testing/machine/verification.js +1375 -0
  121. package/dist/internal/testing/machine/verification.js.map +1 -0
  122. package/dist/testing/MachineTest.d.ts +1588 -0
  123. package/dist/testing/MachineTest.d.ts.map +1 -0
  124. package/dist/testing/MachineTest.js +406 -0
  125. package/dist/testing/MachineTest.js.map +1 -0
  126. package/dist/testing/index.d.ts +7 -0
  127. package/dist/testing/index.d.ts.map +1 -0
  128. package/dist/testing/index.js +7 -0
  129. package/dist/testing/index.js.map +1 -0
  130. package/dist/{ClusterMachine.d.ts → unstable/cluster/ClusterMachine.d.ts} +56 -45
  131. package/dist/unstable/cluster/ClusterMachine.d.ts.map +1 -0
  132. package/dist/unstable/cluster/ClusterMachine.js +144 -0
  133. package/dist/unstable/cluster/ClusterMachine.js.map +1 -0
  134. package/dist/{cluster.js → unstable/cluster/index.d.ts} +1 -1
  135. package/dist/unstable/cluster/index.d.ts.map +1 -0
  136. package/dist/{cluster.d.ts → unstable/cluster/index.js} +1 -1
  137. package/dist/unstable/cluster/index.js.map +1 -0
  138. package/dist/{AtomMachine.d.ts → unstable/reactivity/AtomMachine.d.ts} +116 -50
  139. package/dist/unstable/reactivity/AtomMachine.d.ts.map +1 -0
  140. package/dist/unstable/reactivity/AtomMachine.js +164 -0
  141. package/dist/unstable/reactivity/AtomMachine.js.map +1 -0
  142. package/dist/{reactivity.js → unstable/reactivity/index.d.ts} +1 -1
  143. package/dist/unstable/reactivity/index.d.ts.map +1 -0
  144. package/dist/{reactivity.d.ts → unstable/reactivity/index.js} +1 -1
  145. package/dist/unstable/reactivity/index.js.map +1 -0
  146. package/docs/agent-guide.md +316 -31
  147. package/package.json +28 -10
  148. package/dist/AtomMachine.d.ts.map +0 -1
  149. package/dist/AtomMachine.js.map +0 -1
  150. package/dist/ClusterMachine.d.ts.map +0 -1
  151. package/dist/ClusterMachine.js.map +0 -1
  152. package/dist/cluster.d.ts.map +0 -1
  153. package/dist/cluster.js.map +0 -1
  154. package/dist/internal/machineErrors.d.ts.map +0 -1
  155. package/dist/internal/machineErrors.js.map +0 -1
  156. package/dist/internal/machineModel.d.ts.map +0 -1
  157. package/dist/internal/machineModel.js.map +0 -1
  158. package/dist/internal/machinePlanner.d.ts +0 -74
  159. package/dist/internal/machinePlanner.d.ts.map +0 -1
  160. package/dist/internal/machinePlanner.js +0 -797
  161. package/dist/internal/machinePlanner.js.map +0 -1
  162. package/dist/internal/machineProcess.d.ts.map +0 -1
  163. package/dist/internal/machineProcess.js +0 -181
  164. package/dist/internal/machineProcess.js.map +0 -1
  165. package/dist/internal/machineRuntime.d.ts +0 -125
  166. package/dist/internal/machineRuntime.d.ts.map +0 -1
  167. package/dist/internal/machineRuntime.js +0 -365
  168. package/dist/internal/machineRuntime.js.map +0 -1
  169. package/dist/reactivity.d.ts.map +0 -1
  170. package/dist/reactivity.js.map +0 -1
@@ -0,0 +1,1588 @@
1
+ /**
2
+ * Property-based scenario generation and planner trace utilities.
3
+ *
4
+ * @since 0.4.0
5
+ */
6
+ import type * as Effect from "effect/Effect";
7
+ import type * as Graph from "effect/Graph";
8
+ import type * as Schema from "effect/Schema";
9
+ import type { FastCheck } from "effect/testing";
10
+ import type { EnsureExecutable } from "../internal/machine/readiness.js";
11
+ import type { SchemaArbitraryReport } from "../internal/testing/machine/arbitrary.js";
12
+ import type { FiniteModel } from "../internal/testing/machine/finiteModel.js";
13
+ import type * as ReferenceModel from "../internal/testing/machine/referenceModel.js";
14
+ import * as internal from "../internal/testing/machine/verification.js";
15
+ import type { VerificationError } from "../internal/testing/machine/verification.js";
16
+ import type * as Machine from "../Machine.js";
17
+ export { advanceCommand, type CausalRuntimeAssertionContext, type CausalRuntimeCommandActual, CausalRuntimeCommandFailure, type CausalRuntimeCommandRecord, type CausalRuntimeCommandResult, type CausalRuntimeInspectionContext, type CausalRuntimeModelOptions, type CausalRuntimeModelStep, type CausalRuntimeTranscript, type CausalVerificationAwaitContext, type CausalVerificationOptions, type CausalVerificationTranscript, checkpointCommand, type EnqueuedRuntimeAssertionContext, type EnqueuedRuntimeCommandActual, type EnqueuedRuntimeCommandRecord, type EnqueuedRuntimeInspectionContext, type EnqueuedRuntimeModelOptions, type EnqueuedRuntimeModelStep, type EnqueuedRuntimeTranscript, formatCausalTranscript, formatEnqueuedTranscript, formatRuntimeTranscript, runCausalCommands, runEnqueuedCommands, runRuntimeCommands, type RuntimeAssertionContext, type RuntimeAwait, type RuntimeCommand, type RuntimeCommandActual, RuntimeCommandFailure, type RuntimeCommandRecord, type RuntimeCommandResult, type RuntimeCommands, runtimeCommands, type RuntimeCommandsDiagnostics, type RuntimeCommandsOptions, type RuntimeInspectionContext, type RuntimeModelOptions, type RuntimeModelStep, RuntimeObservationError, RuntimeSynchronization, type RuntimeTranscript, sendCommand, stopCommand, verifyCausalCommands } from "../internal/testing/machine/verification.js";
18
+ export type { SchemaArbitraryOpaqueFilterWarning, SchemaArbitraryReport, SchemaArbitraryWarning } from "../internal/testing/machine/verification.js";
19
+ export { compileModel, type FiniteAtomicState, type FiniteAutomaticTransition, type FiniteCompoundState, type FiniteEventTransition, type FiniteFinalState, type FiniteHistoryMutation, type FiniteHistoryScenario, type FiniteHistoryState, type FiniteHistoryTransfer, type FiniteModel, type FiniteModelDiagnostics, type FiniteModelOptions, type FiniteModels, finiteModels, type FiniteParallelState, type FiniteState, type FiniteTransition, type FiniteTransitionTrigger } from "../internal/testing/machine/verification.js";
20
+ export { ModelVerificationError, type ModelVerificationField, type ModelVerificationLocation, type ModelVerificationMismatch, type ReferenceCompletion, type ReferenceHistoryRecord, type ReferenceInitialStep, type ReferenceMicrostep, type ReferenceState, type ReferenceStateValue, type ReferenceStep, type ReferenceTrace, type ReferenceTransition } from "../internal/testing/machine/verification.js";
21
+ /**
22
+ * Purely interprets a finite hierarchical model without compiling a
23
+ * machine.
24
+ *
25
+ * @category verification
26
+ * @since 0.4.0
27
+ */
28
+ export declare const interpretModel: (model: FiniteModel, events: ReadonlyArray<string>) => ReferenceModel.ReferenceTrace;
29
+ type AnyMachine = Machine.Machine.Any;
30
+ type InputValue<M extends AnyMachine> = Machine.Machine.Input<M>["Type"];
31
+ type StatePath<M extends AnyMachine> = Machine.Machine.StateIdentifier<Machine.Machine.States<M>>;
32
+ type StateNodePath<M extends AnyMachine> = Machine.Machine.StateNodeIdentifier<Machine.Machine.States<M>>;
33
+ type IsAny<A> = 0 extends (1 & A) ? true : false;
34
+ type ReadyMachine<M extends AnyMachine> = M & EnsureExecutable<Machine.Machine.States<M>, Machine.Machine.UnhandledStates<M>, Machine.Machine.OutputStates<M>>;
35
+ /**
36
+ * A generated public-input scenario for a machine.
37
+ *
38
+ * Machines without an input schema omit `input`; machines with one retain its
39
+ * exact decoded type. Events use only the public input protocol.
40
+ *
41
+ * @category models
42
+ * @since 0.4.0
43
+ */
44
+ export type Scenario<M extends AnyMachine> = Machine.Machine.Input<M> extends typeof Schema.Void ? {
45
+ readonly events: ReadonlyArray<Machine.Machine.InputEvent<M>>;
46
+ } : {
47
+ readonly input: InputValue<M>;
48
+ readonly events: ReadonlyArray<Machine.Machine.InputEvent<M>>;
49
+ };
50
+ /**
51
+ * Options for schema-derived scenario generation.
52
+ *
53
+ * `inputArbitrary` and `eventsArbitrary` replace their complete generated
54
+ * value. An events override therefore owns its own length distribution.
55
+ *
56
+ * @category models
57
+ * @since 0.4.0
58
+ */
59
+ export type ScenarioOptions<M extends AnyMachine> = {
60
+ readonly minEvents?: number;
61
+ readonly maxEvents?: number;
62
+ readonly eventsArbitrary?: FastCheck.Arbitrary<ReadonlyArray<Machine.Machine.InputEvent<M>>>;
63
+ } & (Machine.Machine.Input<M> extends typeof Schema.Void ? {
64
+ readonly inputArbitrary?: never;
65
+ } : {
66
+ readonly inputArbitrary?: FastCheck.Arbitrary<InputValue<M>>;
67
+ });
68
+ /**
69
+ * Diagnostics for one schema-derived arbitrary.
70
+ *
71
+ * @category models
72
+ * @since 0.4.0
73
+ */
74
+ export interface SchemaArbitraryDiagnostic {
75
+ readonly boundary: "input" | "event";
76
+ readonly index: number | undefined;
77
+ readonly report: SchemaArbitraryReport;
78
+ }
79
+ /**
80
+ * Diagnostics describing how a scenario arbitrary was assembled.
81
+ *
82
+ * @category models
83
+ * @since 0.4.0
84
+ */
85
+ export interface ScenarioDiagnostics {
86
+ readonly input: "none" | "schema" | "override";
87
+ readonly events: "empty" | "schema" | "override";
88
+ readonly schemas: ReadonlyArray<SchemaArbitraryDiagnostic>;
89
+ }
90
+ /**
91
+ * A scenario arbitrary together with schema-derivation diagnostics.
92
+ *
93
+ * @category models
94
+ * @since 0.4.0
95
+ */
96
+ export interface Scenarios<M extends AnyMachine> {
97
+ readonly arbitrary: FastCheck.Arbitrary<Scenario<M>>;
98
+ readonly diagnostics: ScenarioDiagnostics;
99
+ }
100
+ /**
101
+ * Derives valid machine inputs and public events from their schemas.
102
+ *
103
+ * Unsupported schema derivations fail immediately through `Schema.toArbitrary`.
104
+ * Non-fatal derivation warnings are returned instead of being hidden.
105
+ *
106
+ * **Example**
107
+ *
108
+ * ```ts
109
+ * import { Schema } from "effect"
110
+ * import { Machine } from "@typeonce/effect-machine"
111
+ * import { MachineTest } from "@typeonce/effect-machine/testing"
112
+ *
113
+ * class Idle extends Schema.TaggedClass<Idle>("Idle")("Idle", {}) {}
114
+ * class Reset extends Schema.TaggedClass<Reset>("Reset")("Reset", {}) {}
115
+ * const States = Machine.defineStates({ Idle })
116
+ * const machine = Machine.make({
117
+ * states: States.states,
118
+ * events: [Reset],
119
+ * initial: () => States.initial.Idle.from()
120
+ * }).handle({ Idle: { on: { Reset: () => States.initial.Idle.from() } } })
121
+ *
122
+ * const generated = MachineTest.scenarios(machine, { maxEvents: 5 })
123
+ * ```
124
+ *
125
+ * @category constructors
126
+ * @since 0.4.0
127
+ */
128
+ export declare const scenarios: <M extends AnyMachine>(machine: M, options?: ScenarioOptions<M>) => Scenarios<M>;
129
+ /**
130
+ * Completion information retained by an initial or event plan.
131
+ *
132
+ * @category models
133
+ * @since 0.4.0
134
+ */
135
+ export type PlanCompletion<M extends AnyMachine> = {
136
+ readonly done: true;
137
+ readonly output: Machine.Machine.Output<M>;
138
+ } | {
139
+ readonly done: false;
140
+ readonly output: undefined;
141
+ };
142
+ /**
143
+ * One public planned microstep, including retained post-conflict transitions.
144
+ *
145
+ * @category models
146
+ * @since 0.4.0
147
+ */
148
+ export interface Microstep<M extends AnyMachine, Requirements = Machine.Machine.Services<M>> {
149
+ readonly next: Machine.Machine.Snapshot<Machine.Machine.States<M>>;
150
+ readonly event: Machine.Machine.Event<M> | Machine.InitialEvent;
151
+ readonly transitions: ReadonlyArray<Machine.Machine.RetainedTransition<StatePath<M>, Machine.Machine.TagOf<Machine.Machine.Events<M>[number]>, StateNodePath<M>>>;
152
+ readonly commands: ReadonlyArray<Machine.Command>;
153
+ readonly raisedEvents: ReadonlyArray<Machine.Machine.Event<M>>;
154
+ readonly emittedEvents: ReadonlyArray<Machine.Machine.Emit<M>>;
155
+ readonly exitPaths: ReadonlyArray<string>;
156
+ readonly entryPaths: ReadonlyArray<string>;
157
+ readonly changed: boolean;
158
+ }
159
+ /**
160
+ * The complete data returned while planning machine startup.
161
+ *
162
+ * @category models
163
+ * @since 0.4.0
164
+ */
165
+ export type InitialPlan<M extends AnyMachine> = {
166
+ readonly startingState: Machine.Machine.Snapshot<Machine.Machine.States<M>>;
167
+ readonly initialEntryPaths: ReadonlyArray<StatePath<M>>;
168
+ readonly state: Machine.Machine.Snapshot<Machine.Machine.States<M>>;
169
+ readonly commands: ReadonlyArray<Machine.Command>;
170
+ readonly emittedEvents: ReadonlyArray<Machine.Machine.Emit<M>>;
171
+ readonly microsteps: ReadonlyArray<Microstep<M, Machine.Machine.InitialServices<M> | Machine.Machine.Services<M>>>;
172
+ } & PlanCompletion<M>;
173
+ /**
174
+ * The complete data returned while planning one public event.
175
+ *
176
+ * @category models
177
+ * @since 0.4.0
178
+ */
179
+ export type EventPlan<M extends AnyMachine> = {
180
+ readonly next: Machine.Machine.Snapshot<Machine.Machine.States<M>>;
181
+ readonly commands: ReadonlyArray<Machine.Command>;
182
+ readonly emittedEvents: ReadonlyArray<Machine.Machine.Emit<M>>;
183
+ readonly microsteps: ReadonlyArray<Microstep<M>>;
184
+ } & PlanCompletion<M>;
185
+ /**
186
+ * Startup portion of an executable planner trace.
187
+ *
188
+ * @category models
189
+ * @since 0.4.0
190
+ */
191
+ export interface InitialTrace<M extends AnyMachine> {
192
+ readonly plan: InitialPlan<M>;
193
+ readonly startingState: Machine.Machine.Snapshot<Machine.Machine.States<M>>;
194
+ readonly startingConfiguration: ReadonlyArray<StatePath<M>>;
195
+ readonly initialEntryPaths: ReadonlyArray<StatePath<M>>;
196
+ readonly configuration: ReadonlyArray<StatePath<M>>;
197
+ }
198
+ /**
199
+ * One event portion of an executable planner trace.
200
+ *
201
+ * @category models
202
+ * @since 0.4.0
203
+ */
204
+ export interface TraceStep<M extends AnyMachine> {
205
+ readonly index: number;
206
+ readonly before: Machine.Machine.Snapshot<Machine.Machine.States<M>>;
207
+ readonly beforeConfiguration: ReadonlyArray<StatePath<M>>;
208
+ readonly event: Machine.Machine.InputEvent<M>;
209
+ readonly plan: EventPlan<M>;
210
+ readonly after: Machine.Machine.Snapshot<Machine.Machine.States<M>>;
211
+ readonly afterConfiguration: ReadonlyArray<StatePath<M>>;
212
+ }
213
+ /**
214
+ * A scenario and every plan produced by executing it without running actions.
215
+ *
216
+ * @category models
217
+ * @since 0.4.0
218
+ */
219
+ export interface Trace<M extends AnyMachine> {
220
+ readonly scenario: Scenario<M>;
221
+ readonly initial: InitialTrace<M>;
222
+ readonly steps: ReadonlyArray<TraceStep<M>>;
223
+ readonly final: Machine.Machine.Snapshot<Machine.Machine.States<M>>;
224
+ readonly finalConfiguration: ReadonlyArray<StatePath<M>>;
225
+ }
226
+ /**
227
+ * One runtime microstep retained by the execution strategy used by a probe.
228
+ *
229
+ * Transition-definition metadata is intentionally not reconstructed here:
230
+ * optimized runtimes retain execution evidence, while `run` and `plan` remain
231
+ * the APIs for complete diagnostic transition metadata.
232
+ *
233
+ * @category runtime testing
234
+ * @since 0.4.0
235
+ */
236
+ export type ProbeMicrostep<M extends AnyMachine> = Omit<Microstep<M>, "transitions">;
237
+ /**
238
+ * Runtime plan evidence associated with one acknowledged public event.
239
+ *
240
+ * @category runtime testing
241
+ * @since 0.4.0
242
+ */
243
+ export type ProbePlan<M extends AnyMachine> = {
244
+ readonly next: Machine.Machine.Snapshot<Machine.Machine.States<M>>;
245
+ readonly commands: ReadonlyArray<Machine.Command>;
246
+ readonly emittedEvents: ReadonlyArray<Machine.Machine.Emit<M>>;
247
+ readonly microsteps: ReadonlyArray<ProbeMicrostep<M>>;
248
+ } & PlanCompletion<M>;
249
+ /**
250
+ * Causal evidence produced after one event has completed its managed runtime
251
+ * macrostep.
252
+ *
253
+ * `handled` distinguishes an ignored event from a retained transition that
254
+ * deliberately leaves the logical state unchanged. `configurationChanged`
255
+ * reports whether any microstep changed or reentered the active statechart
256
+ * configuration; compare `before` and `after` for state-value assertions.
257
+ *
258
+ * @category runtime testing
259
+ * @since 0.4.0
260
+ */
261
+ export interface ProbeStep<M extends AnyMachine> {
262
+ readonly event: Machine.Machine.InputEvent<M>;
263
+ readonly before: Machine.Machine.Snapshot<Machine.Machine.States<M>>;
264
+ readonly plan: ProbePlan<M>;
265
+ readonly after: Machine.Machine.Snapshot<Machine.Machine.States<M>>;
266
+ readonly handled: boolean;
267
+ readonly configurationChanged: boolean;
268
+ }
269
+ /**
270
+ * Testing-only causal access to a managed statechart reference.
271
+ *
272
+ * A probe does not change ordinary machine scheduling. `sendAndAwait` uses an
273
+ * acknowledged mailbox delivery so an ignored event can be proven processed
274
+ * without waiting for a snapshot that will never be published.
275
+ *
276
+ * @category runtime testing
277
+ * @since 0.4.0
278
+ */
279
+ export interface Probe<M extends AnyMachine, Error = never, Output = never> {
280
+ readonly machine: M;
281
+ readonly ref: Machine.MachineRef<Machine.Machine.Snapshot<Machine.Machine.States<M>>, Machine.Machine.InputEvent<M>, Error, Output>;
282
+ readonly sendAndAwait: (event: Machine.Machine.InputEvent<M>) => Effect.Effect<ProbeStep<M>, Error | Machine.StoppedError>;
283
+ /** Constructors for asynchronous observation after a causal command. */
284
+ readonly await: {
285
+ readonly none: internal.RuntimeAwait<Machine.Machine.Snapshot<Machine.Machine.States<M>>, Error, Output>;
286
+ readonly until: (predicate: (snapshot: Machine.RuntimeSnapshot<Machine.Machine.Snapshot<Machine.Machine.States<M>>, Error, Output>) => boolean) => internal.RuntimeAwait<Machine.Machine.Snapshot<Machine.Machine.States<M>>, Error, Output>;
287
+ };
288
+ }
289
+ /**
290
+ * Raised when `probe` receives a reference that is not backed by the managed
291
+ * statechart runtime.
292
+ *
293
+ * @category errors
294
+ * @since 0.4.0
295
+ */
296
+ export { ProbeUnavailableError } from "../internal/testing/machine/verification.js";
297
+ /**
298
+ * Attaches testing-only causal event delivery to a running statechart.
299
+ *
300
+ * The returned probe exposes `sendAndAwait`; ordinary production sends remain
301
+ * available exclusively through `MachineRef.send` and retain their
302
+ * asynchronous enqueue-only semantics.
303
+ *
304
+ * **Example**
305
+ *
306
+ * ```ts
307
+ * import { Effect, Schema } from "effect"
308
+ * import { Machine } from "@typeonce/effect-machine"
309
+ * import { MachineTest } from "@typeonce/effect-machine/testing"
310
+ *
311
+ * class Idle extends Schema.TaggedClass<Idle>("Idle")("Idle", {}) {}
312
+ * const States = Machine.defineStates({ Idle })
313
+ * const machine = Machine.make({
314
+ * states: States.states,
315
+ * events: [],
316
+ * initial: () => States.initial.Idle.from()
317
+ * }).handle({ Idle: {} })
318
+ *
319
+ * const program = Effect.gen(function*() {
320
+ * const ref = yield* Machine.start(machine)
321
+ * return yield* MachineTest.probe(machine, ref)
322
+ * })
323
+ * ```
324
+ *
325
+ * @category runtime testing
326
+ * @since 0.4.0
327
+ */
328
+ export declare const probe: <M extends AnyMachine, Error, Output>(machine: ReadyMachine<M>, ref: Machine.MachineRef<Machine.Machine.Snapshot<Machine.Machine.States<M>>, Machine.Machine.InputEvent<M>, Error, Output>) => Effect.Effect<Probe<M, Error, Output>, internal.ProbeUnavailableError>;
329
+ /**
330
+ * The runtime error channel exposed by a managed reference for a machine.
331
+ *
332
+ * @category utility types
333
+ * @since 0.4.0
334
+ */
335
+ export type RuntimeInvariantErrorChannel<M extends AnyMachine> = Machine.Machine.Error<M> | Machine.ActionError<Machine.Machine.Services<M>> | Machine.InfiniteTransitionError | Machine.MachineSchemaDecodeError | Machine.StoppedError;
336
+ /**
337
+ * A causal command record projected independently of a reference model.
338
+ *
339
+ * @category models
340
+ * @since 0.4.0
341
+ */
342
+ export interface CausalRuntimeEvidenceRecord<M extends AnyMachine, Error, Output> {
343
+ readonly index: number;
344
+ readonly command: internal.RuntimeCommand<Machine.Machine.InputEvent<M>>;
345
+ readonly actual: internal.CausalRuntimeCommandActual<M, Error, Output, unknown>;
346
+ }
347
+ /**
348
+ * The model-independent evidence shared by causal command transcripts.
349
+ *
350
+ * @category models
351
+ * @since 0.4.0
352
+ */
353
+ export interface CausalRuntimeEvidence<M extends AnyMachine, Error, Output> {
354
+ readonly commands: ReadonlyArray<internal.RuntimeCommand<Machine.Machine.InputEvent<M>>>;
355
+ readonly initial: Machine.RuntimeSnapshot<Machine.Machine.Snapshot<Machine.Machine.States<M>>, Error, Output>;
356
+ readonly records: ReadonlyArray<CausalRuntimeEvidenceRecord<M, Error, Output>>;
357
+ readonly final: Machine.RuntimeSnapshot<Machine.Machine.Snapshot<Machine.Machine.States<M>>, Error, Output>;
358
+ }
359
+ /**
360
+ * The runtime snapshots selected by one snapshot invariant.
361
+ *
362
+ * @category invariants
363
+ * @since 0.4.0
364
+ */
365
+ export type RuntimeSnapshotObservationMode = "settled" | "awaited" | "all" | "final";
366
+ /**
367
+ * The semantic location of one retained runtime snapshot.
368
+ *
369
+ * @category invariants
370
+ * @since 0.4.0
371
+ */
372
+ export type RuntimeSnapshotObservation = "initial" | "command" | "awaited" | "final";
373
+ /**
374
+ * A model-independent command record supplied to runtime laws.
375
+ *
376
+ * @category models
377
+ * @since 0.4.0
378
+ */
379
+ export interface RuntimeInvariantRecord<M extends AnyMachine> {
380
+ readonly index: number;
381
+ readonly command: internal.RuntimeCommand<Machine.Machine.InputEvent<M>>;
382
+ readonly result: internal.CausalRuntimeCommandResult<M>;
383
+ readonly snapshot: Machine.RuntimeSnapshot<Machine.Machine.Snapshot<Machine.Machine.States<M>>, RuntimeInvariantErrorChannel<M>, Machine.Machine.Output<M>>;
384
+ readonly awaited: ReadonlyArray<Machine.RuntimeSnapshot<Machine.Machine.Snapshot<Machine.Machine.States<M>>, RuntimeInvariantErrorChannel<M>, Machine.Machine.Output<M>>>;
385
+ }
386
+ /**
387
+ * A model-independent causal transcript supplied to runtime laws.
388
+ *
389
+ * @category models
390
+ * @since 0.4.0
391
+ */
392
+ export interface RuntimeInvariantTranscript<M extends AnyMachine> {
393
+ readonly commands: ReadonlyArray<internal.RuntimeCommand<Machine.Machine.InputEvent<M>>>;
394
+ readonly initial: Machine.RuntimeSnapshot<Machine.Machine.Snapshot<Machine.Machine.States<M>>, RuntimeInvariantErrorChannel<M>, Machine.Machine.Output<M>>;
395
+ readonly records: ReadonlyArray<RuntimeInvariantRecord<M>>;
396
+ readonly final: Machine.RuntimeSnapshot<Machine.Machine.Snapshot<Machine.Machine.States<M>>, RuntimeInvariantErrorChannel<M>, Machine.Machine.Output<M>>;
397
+ }
398
+ /**
399
+ * Evidence passed to a runtime snapshot invariant.
400
+ *
401
+ * @category models
402
+ * @since 0.4.0
403
+ */
404
+ export interface RuntimeSnapshotInvariantContext<M extends AnyMachine> {
405
+ readonly machine: M;
406
+ readonly transcript: RuntimeInvariantTranscript<M>;
407
+ readonly snapshot: RuntimeInvariantTranscript<M>["initial"];
408
+ readonly observationIndex: number;
409
+ readonly phase: RuntimeSnapshotObservation;
410
+ readonly commandIndex: number | undefined;
411
+ readonly awaitedIndex: number | undefined;
412
+ readonly command: internal.RuntimeCommand<Machine.Machine.InputEvent<M>> | undefined;
413
+ readonly result: internal.CausalRuntimeCommandResult<M> | undefined;
414
+ }
415
+ /**
416
+ * Evidence passed to an invariant for one completed causal command.
417
+ *
418
+ * @category models
419
+ * @since 0.4.0
420
+ */
421
+ export interface RuntimeCommandInvariantContext<M extends AnyMachine> {
422
+ readonly machine: M;
423
+ readonly transcript: RuntimeInvariantTranscript<M>;
424
+ readonly record: RuntimeInvariantRecord<M>;
425
+ readonly previous: RuntimeInvariantRecord<M> | undefined;
426
+ readonly index: number;
427
+ readonly command: internal.RuntimeCommand<Machine.Machine.InputEvent<M>>;
428
+ readonly result: internal.CausalRuntimeCommandResult<M>;
429
+ readonly snapshot: RuntimeInvariantRecord<M>["snapshot"];
430
+ readonly awaited: RuntimeInvariantRecord<M>["awaited"];
431
+ }
432
+ /**
433
+ * Evidence passed to a whole-runtime-transcript invariant.
434
+ *
435
+ * @category models
436
+ * @since 0.4.0
437
+ */
438
+ export interface RuntimeTranscriptInvariantContext<M extends AnyMachine> {
439
+ readonly machine: M;
440
+ readonly transcript: RuntimeInvariantTranscript<M>;
441
+ }
442
+ /**
443
+ * Options for a runtime snapshot invariant.
444
+ *
445
+ * @category models
446
+ * @since 0.4.0
447
+ */
448
+ export interface RuntimeSnapshotInvariantOptions<M extends AnyMachine> extends InvariantOptions<RuntimeSnapshotInvariantContext<M>> {
449
+ readonly observe?: RuntimeSnapshotObservationMode;
450
+ }
451
+ /**
452
+ * A semantic property checked against selected live runtime snapshots.
453
+ *
454
+ * @category invariants
455
+ * @since 0.4.0
456
+ */
457
+ export interface RuntimeSnapshotInvariant<M extends AnyMachine> extends InvariantOptions<RuntimeSnapshotInvariantContext<M>> {
458
+ readonly _tag: "RuntimeSnapshotInvariant";
459
+ readonly name: string;
460
+ readonly observe: RuntimeSnapshotObservationMode;
461
+ readonly check: (context: RuntimeSnapshotInvariantContext<M>) => InvariantOutcome;
462
+ }
463
+ /**
464
+ * A semantic property checked after every completed causal command.
465
+ *
466
+ * @category invariants
467
+ * @since 0.4.0
468
+ */
469
+ export interface RuntimeCommandInvariant<M extends AnyMachine> extends InvariantOptions<RuntimeCommandInvariantContext<M>> {
470
+ readonly _tag: "RuntimeCommandInvariant";
471
+ readonly name: string;
472
+ readonly check: (context: RuntimeCommandInvariantContext<M>) => InvariantOutcome;
473
+ }
474
+ /**
475
+ * A semantic property checked once against a complete causal transcript.
476
+ *
477
+ * @category invariants
478
+ * @since 0.4.0
479
+ */
480
+ export interface RuntimeTranscriptInvariant<M extends AnyMachine> extends InvariantOptions<RuntimeTranscriptInvariantContext<M>> {
481
+ readonly _tag: "RuntimeTranscriptInvariant";
482
+ readonly name: string;
483
+ readonly check: (context: RuntimeTranscriptInvariantContext<M>) => InvariantOutcome;
484
+ }
485
+ /**
486
+ * A user-defined semantic property over retained live runtime evidence.
487
+ *
488
+ * @category invariants
489
+ * @since 0.4.0
490
+ */
491
+ export type RuntimeInvariant<M extends AnyMachine> = RuntimeSnapshotInvariant<M> | RuntimeCommandInvariant<M> | RuntimeTranscriptInvariant<M>;
492
+ /**
493
+ * Machine-bound runtime invariant constructors with exact event inference.
494
+ *
495
+ * @category models
496
+ * @since 0.4.0
497
+ */
498
+ export interface RuntimeInvariantBuilder<M extends AnyMachine> {
499
+ readonly snapshot: (name: string, check: (context: RuntimeSnapshotInvariantContext<M>) => InvariantOutcome, options?: RuntimeSnapshotInvariantOptions<M>) => RuntimeSnapshotInvariant<M>;
500
+ readonly command: (name: string, check: (context: RuntimeCommandInvariantContext<M>) => InvariantOutcome, options?: InvariantOptions<RuntimeCommandInvariantContext<M>>) => RuntimeCommandInvariant<M>;
501
+ readonly transcript: (name: string, check: (context: RuntimeTranscriptInvariantContext<M>) => InvariantOutcome, options?: InvariantOptions<RuntimeTranscriptInvariantContext<M>>) => RuntimeTranscriptInvariant<M>;
502
+ }
503
+ /**
504
+ * Creates reusable semantic laws for causal runtime evidence.
505
+ *
506
+ * @category constructors
507
+ * @since 0.4.0
508
+ */
509
+ export declare const runtimeInvariants: <M extends AnyMachine>(machine: M) => RuntimeInvariantBuilder<M>;
510
+ /**
511
+ * Scope of a runtime invariant.
512
+ *
513
+ * @category invariants
514
+ * @since 0.4.0
515
+ */
516
+ export type RuntimeInvariantScope = "snapshot" | "command" | "transcript";
517
+ /**
518
+ * Aggregate result for one runtime invariant.
519
+ *
520
+ * @category models
521
+ * @since 0.4.0
522
+ */
523
+ export interface RuntimeInvariantCheckResult {
524
+ readonly invariant: string;
525
+ readonly scope: RuntimeInvariantScope;
526
+ readonly status: InvariantStatus;
527
+ readonly observations: number;
528
+ readonly failures: number;
529
+ }
530
+ /**
531
+ * Aggregate result for all checked runtime invariants.
532
+ *
533
+ * @category models
534
+ * @since 0.4.0
535
+ */
536
+ export interface RuntimeInvariantReport {
537
+ readonly checks: ReadonlyArray<RuntimeInvariantCheckResult>;
538
+ }
539
+ /**
540
+ * One runtime invariant violation and its exact retained location.
541
+ *
542
+ * @category models
543
+ * @since 0.4.0
544
+ */
545
+ export interface RuntimeInvariantViolation<M extends AnyMachine = AnyMachine> {
546
+ readonly invariant: string;
547
+ readonly scope: RuntimeInvariantScope;
548
+ readonly kind: "predicate" | "observations";
549
+ readonly observationIndex?: number;
550
+ readonly commandIndex: number | undefined;
551
+ readonly awaitedIndex?: number;
552
+ readonly phase?: RuntimeSnapshotObservation;
553
+ readonly command?: internal.RuntimeCommand<Machine.Machine.InputEvent<M>>;
554
+ readonly message: string;
555
+ }
556
+ /**
557
+ * All violations found in one causal runtime transcript.
558
+ *
559
+ * @category errors
560
+ * @since 0.4.0
561
+ */
562
+ export { RuntimeInvariantError } from "../internal/testing/machine/verification.js";
563
+ /**
564
+ * Checks runtime invariants and returns their complete non-vacuity report.
565
+ *
566
+ * @category verification
567
+ * @since 0.4.0
568
+ */
569
+ export declare const checkRuntimeInvariants: <M extends AnyMachine, Error, Output>(machine: M, transcript: CausalRuntimeEvidence<M, Error, Output>, invariants: ReadonlyArray<RuntimeInvariant<M>>) => Effect.Effect<RuntimeInvariantReport, internal.RuntimeInvariantError<M>>;
570
+ /**
571
+ * Asserts runtime invariants against an existing causal transcript.
572
+ *
573
+ * @category verification
574
+ * @since 0.4.0
575
+ */
576
+ export declare const assertRuntimeInvariants: <M extends AnyMachine, Error, Output>(machine: M, transcript: CausalRuntimeEvidence<M, Error, Output>, invariants: ReadonlyArray<RuntimeInvariant<M>>) => Effect.Effect<void, internal.RuntimeInvariantError<M>>;
577
+ /**
578
+ * One disagreement between pure planning and a causally processed send.
579
+ *
580
+ * @category models
581
+ * @since 0.4.0
582
+ */
583
+ export interface PlannerRuntimeAgreementViolation<M extends AnyMachine = AnyMachine> {
584
+ readonly commandIndex: number;
585
+ readonly command: internal.RuntimeCommand<Machine.Machine.InputEvent<M>>;
586
+ readonly field: "planning" | "handled" | "configurationChanged" | "planNext" | "after" | "completion" | "commands" | "emittedEvents" | "microsteps";
587
+ readonly message: string;
588
+ }
589
+ /**
590
+ * Raised when live causal evidence disagrees with a fresh pure plan.
591
+ *
592
+ * @category errors
593
+ * @since 0.4.0
594
+ */
595
+ export { PlannerRuntimeAgreementError } from "../internal/testing/machine/verification.js";
596
+ /**
597
+ * Checks that every processed public send agrees with a fresh pure plan.
598
+ *
599
+ * @category verification
600
+ * @since 0.4.0
601
+ */
602
+ export declare const assertPlannerRuntimeAgreement: <M extends AnyMachine, Error, Output>(machine: ReadyMachine<M>, transcript: CausalRuntimeEvidence<M, Error, Output>) => Effect.Effect<void, internal.PlannerRuntimeAgreementError<M>, RunServices<M>>;
603
+ /**
604
+ * The result of evaluating one semantic invariant.
605
+ *
606
+ * `true` passes, `false` produces a default failure message, and a string
607
+ * fails with that string as its counterexample explanation.
608
+ *
609
+ * @category invariants
610
+ * @since 0.4.0
611
+ */
612
+ export type InvariantOutcome = boolean | string;
613
+ /**
614
+ * The portions of a trace that a state invariant may observe.
615
+ *
616
+ * - `settled` observes startup and the state after every public event.
617
+ * - `microsteps` observes every internal microstep.
618
+ * - `all` observes both settled states and microsteps.
619
+ * - `final` observes only the final state.
620
+ *
621
+ * @category invariants
622
+ * @since 0.4.0
623
+ */
624
+ export type StateObservationMode = "settled" | "microsteps" | "all" | "final";
625
+ /**
626
+ * The semantic location of one state observation.
627
+ *
628
+ * @category invariants
629
+ * @since 0.4.0
630
+ */
631
+ export type StateObservation = "initial" | "event" | "microstep" | "final";
632
+ /**
633
+ * Evidence passed to a state invariant.
634
+ *
635
+ * @category invariants
636
+ * @since 0.4.0
637
+ */
638
+ export interface StateInvariantContext<M extends AnyMachine> {
639
+ readonly machine: M;
640
+ readonly trace: Trace<M>;
641
+ readonly snapshot: Machine.Machine.Snapshot<Machine.Machine.States<M>>;
642
+ readonly configuration: ReadonlyArray<StatePath<M>>;
643
+ readonly observationIndex: number;
644
+ readonly phase: StateObservation;
645
+ readonly eventIndex: number | undefined;
646
+ readonly microstepIndex: number | undefined;
647
+ readonly event: Machine.Machine.Event<M> | Machine.InitialEvent | undefined;
648
+ }
649
+ /**
650
+ * Evidence passed to an invariant for one public event step.
651
+ *
652
+ * @category invariants
653
+ * @since 0.4.0
654
+ */
655
+ export interface StepInvariantContext<M extends AnyMachine> {
656
+ readonly machine: M;
657
+ readonly trace: Trace<M>;
658
+ readonly step: TraceStep<M>;
659
+ readonly index: number;
660
+ readonly before: Machine.Machine.Snapshot<Machine.Machine.States<M>>;
661
+ readonly beforeConfiguration: ReadonlyArray<StatePath<M>>;
662
+ readonly event: Machine.Machine.InputEvent<M>;
663
+ readonly plan: EventPlan<M>;
664
+ readonly after: Machine.Machine.Snapshot<Machine.Machine.States<M>>;
665
+ readonly afterConfiguration: ReadonlyArray<StatePath<M>>;
666
+ }
667
+ /**
668
+ * Evidence passed to a whole-trace invariant.
669
+ *
670
+ * @category invariants
671
+ * @since 0.4.0
672
+ */
673
+ export interface TraceInvariantContext<M extends AnyMachine> {
674
+ readonly machine: M;
675
+ readonly trace: Trace<M>;
676
+ }
677
+ /**
678
+ * Controls conditional invariant evaluation and optional non-vacuity checks.
679
+ *
680
+ * A condition that never matches is reported as `untested`. Set
681
+ * `require.minObservations` when that must fail the check instead.
682
+ *
683
+ * @category invariants
684
+ * @since 0.4.0
685
+ */
686
+ export interface InvariantOptions<Context> {
687
+ readonly when?: (context: Context) => boolean;
688
+ readonly require?: {
689
+ readonly minObservations: number;
690
+ };
691
+ }
692
+ /**
693
+ * Options for a state invariant.
694
+ *
695
+ * @category invariants
696
+ * @since 0.4.0
697
+ */
698
+ export interface StateInvariantOptions<M extends AnyMachine> extends InvariantOptions<StateInvariantContext<M>> {
699
+ readonly observe?: StateObservationMode;
700
+ }
701
+ /**
702
+ * A semantic property checked against selected state observations.
703
+ *
704
+ * @category invariants
705
+ * @since 0.4.0
706
+ */
707
+ export interface StateInvariant<M extends AnyMachine> extends InvariantOptions<StateInvariantContext<M>> {
708
+ readonly _tag: "StateInvariant";
709
+ readonly name: string;
710
+ readonly observe: StateObservationMode;
711
+ readonly check: (context: StateInvariantContext<M>) => InvariantOutcome;
712
+ }
713
+ /**
714
+ * A semantic property checked after every public event.
715
+ *
716
+ * @category invariants
717
+ * @since 0.4.0
718
+ */
719
+ export interface StepInvariant<M extends AnyMachine> extends InvariantOptions<StepInvariantContext<M>> {
720
+ readonly _tag: "StepInvariant";
721
+ readonly name: string;
722
+ readonly check: (context: StepInvariantContext<M>) => InvariantOutcome;
723
+ }
724
+ /**
725
+ * A semantic property checked once against a complete trace.
726
+ *
727
+ * @category invariants
728
+ * @since 0.4.0
729
+ */
730
+ export interface TraceInvariant<M extends AnyMachine> extends InvariantOptions<TraceInvariantContext<M>> {
731
+ readonly _tag: "TraceInvariant";
732
+ readonly name: string;
733
+ readonly check: (context: TraceInvariantContext<M>) => InvariantOutcome;
734
+ }
735
+ /**
736
+ * A user-defined semantic property over a planner trace.
737
+ *
738
+ * @category invariants
739
+ * @since 0.4.0
740
+ */
741
+ export type Invariant<M extends AnyMachine> = StateInvariant<M> | StepInvariant<M> | TraceInvariant<M>;
742
+ /**
743
+ * Machine-bound invariant constructors with complete contextual inference.
744
+ *
745
+ * @category invariants
746
+ * @since 0.4.0
747
+ */
748
+ export interface InvariantBuilder<M extends AnyMachine> {
749
+ readonly state: (name: string, check: (context: StateInvariantContext<M>) => InvariantOutcome, options?: StateInvariantOptions<M>) => StateInvariant<M>;
750
+ readonly step: (name: string, check: (context: StepInvariantContext<M>) => InvariantOutcome, options?: InvariantOptions<StepInvariantContext<M>>) => StepInvariant<M>;
751
+ readonly trace: (name: string, check: (context: TraceInvariantContext<M>) => InvariantOutcome, options?: InvariantOptions<TraceInvariantContext<M>>) => TraceInvariant<M>;
752
+ }
753
+ /**
754
+ * Direct invariant constructors. Prefer `invariants(machine)` when contextual
755
+ * machine types should be inferred without an explicit type argument.
756
+ *
757
+ * @category constructors
758
+ * @since 0.4.0
759
+ */
760
+ export declare const Invariant: {
761
+ readonly state: <M extends AnyMachine>(name: string, check: (context: StateInvariantContext<M>) => InvariantOutcome, options?: StateInvariantOptions<M>) => StateInvariant<M>;
762
+ readonly step: <M extends AnyMachine>(name: string, check: (context: StepInvariantContext<M>) => InvariantOutcome, options?: InvariantOptions<StepInvariantContext<M>>) => StepInvariant<M>;
763
+ readonly trace: <M extends AnyMachine>(name: string, check: (context: TraceInvariantContext<M>) => InvariantOutcome, options?: InvariantOptions<TraceInvariantContext<M>>) => TraceInvariant<M>;
764
+ };
765
+ /**
766
+ * Creates invariant constructors bound to a machine's exact state and event
767
+ * types. The machine is used only for inference; invariant evaluation remains
768
+ * pure and reusable across traces from that machine.
769
+ *
770
+ * **Example**
771
+ *
772
+ * ```ts
773
+ * import { Schema } from "effect"
774
+ * import { Machine } from "@typeonce/effect-machine"
775
+ * import { MachineTest } from "@typeonce/effect-machine/testing"
776
+ *
777
+ * class Count extends Schema.TaggedClass<Count>("Count")("Count", {
778
+ * value: Schema.Number
779
+ * }) {}
780
+ * const States = Machine.defineStates({ Count })
781
+ * const machine = Machine.make({
782
+ * states: States.states,
783
+ * events: [],
784
+ * initial: () => States.initial.Count(new Count({ value: 0 }))
785
+ * }).handle({ Count: {} })
786
+ *
787
+ * const nonNegative = MachineTest.invariants(machine).state(
788
+ * "count is non-negative",
789
+ * ({ snapshot }) => snapshot.value.value >= 0
790
+ * )
791
+ * ```
792
+ *
793
+ * @category constructors
794
+ * @since 0.4.0
795
+ */
796
+ export declare const invariants: <M extends AnyMachine>(machine: M) => InvariantBuilder<M>;
797
+ /**
798
+ * The scope of a semantic invariant.
799
+ *
800
+ * @category invariants
801
+ * @since 0.4.0
802
+ */
803
+ export type InvariantScope = "state" | "step" | "trace";
804
+ /**
805
+ * Result status for one invariant.
806
+ *
807
+ * `untested` is non-failing unless the invariant declares a minimum number of
808
+ * observations, in which case it becomes `insufficient`.
809
+ *
810
+ * @category invariants
811
+ * @since 0.4.0
812
+ */
813
+ export type InvariantStatus = "passed" | "failed" | "untested" | "insufficient";
814
+ /**
815
+ * Aggregate result for one invariant.
816
+ *
817
+ * @category invariants
818
+ * @since 0.4.0
819
+ */
820
+ export interface InvariantCheckResult {
821
+ readonly invariant: string;
822
+ readonly scope: InvariantScope;
823
+ readonly status: InvariantStatus;
824
+ readonly observations: number;
825
+ readonly failures: number;
826
+ }
827
+ /**
828
+ * Aggregate result for all checked invariants.
829
+ *
830
+ * @category invariants
831
+ * @since 0.4.0
832
+ */
833
+ export interface InvariantReport {
834
+ readonly checks: ReadonlyArray<InvariantCheckResult>;
835
+ }
836
+ /**
837
+ * One semantic invariant violation with its precise trace location.
838
+ *
839
+ * @category invariants
840
+ * @since 0.4.0
841
+ */
842
+ export interface InvariantViolation<M extends AnyMachine = AnyMachine> {
843
+ readonly invariant: string;
844
+ readonly scope: InvariantScope;
845
+ readonly kind: "predicate" | "observations";
846
+ readonly observationIndex?: number;
847
+ readonly eventIndex: number | undefined;
848
+ readonly microstepIndex?: number;
849
+ readonly phase?: StateObservation;
850
+ readonly configuration?: ReadonlyArray<StatePath<M>>;
851
+ readonly event?: Machine.Machine.Event<M> | Machine.InitialEvent;
852
+ readonly message: string;
853
+ }
854
+ /**
855
+ * All semantic violations found in one trace, together with the complete
856
+ * counterexample and aggregate report.
857
+ *
858
+ * @category errors
859
+ * @since 0.4.0
860
+ */
861
+ export { InvariantError } from "../internal/testing/machine/verification.js";
862
+ /**
863
+ * Checks user-defined semantic invariants against an existing planner trace.
864
+ *
865
+ * Every invariant and matching observation is evaluated so one failure
866
+ * contains all relevant evidence. Combine this with `scenarios` and `run` in
867
+ * an Effect property test to retain FastCheck shrinking.
868
+ *
869
+ * @category verification
870
+ * @since 0.4.0
871
+ */
872
+ export declare const checkInvariants: <M extends AnyMachine>(machine: M, trace: Trace<M>, invariants: ReadonlyArray<Invariant<M>>) => Effect.Effect<InvariantReport, internal.InvariantError<M>>;
873
+ /**
874
+ * Asserts user-defined semantic invariants and discards the success report.
875
+ *
876
+ * This is the property-test-oriented form of `checkInvariants`: its `void`
877
+ * success works directly with `it.effect.prop`, while failures retain the
878
+ * same complete report and trace evidence.
879
+ *
880
+ * @category verification
881
+ * @since 0.4.0
882
+ */
883
+ export declare const assertInvariants: <M extends AnyMachine>(machine: M, trace: Trace<M>, invariants: ReadonlyArray<Invariant<M>>) => Effect.Effect<void, internal.InvariantError<M>>;
884
+ /**
885
+ * User-defined identity for a logical exploration state.
886
+ *
887
+ * Equal keys deliberately collapse snapshots into one explored state. The key
888
+ * therefore defines both finiteness and the semantic precision of an
889
+ * exploration.
890
+ *
891
+ * @category exploration
892
+ * @since 0.4.0
893
+ */
894
+ export type ExplorationKey = PropertyKey;
895
+ /**
896
+ * Hard bounds for one exploration.
897
+ *
898
+ * Defaults are 20 public events, 1,000 states, and 10,000 planned
899
+ * transitions. A limit never makes an incomplete result appear exhaustive.
900
+ *
901
+ * @category exploration
902
+ * @since 0.4.0
903
+ */
904
+ export interface ExplorationLimits {
905
+ readonly maxDepth?: number;
906
+ readonly maxStates?: number;
907
+ readonly maxTransitions?: number;
908
+ }
909
+ /**
910
+ * Resolved bounds retained by an exploration result.
911
+ *
912
+ * @category exploration
913
+ * @since 0.4.0
914
+ */
915
+ export interface ResolvedExplorationLimits {
916
+ readonly maxDepth: number;
917
+ readonly maxStates: number;
918
+ readonly maxTransitions: number;
919
+ }
920
+ /**
921
+ * Evidence available while assigning a state key.
922
+ *
923
+ * @category exploration
924
+ * @since 0.4.0
925
+ */
926
+ export interface ExplorationStateContext<M extends AnyMachine> {
927
+ readonly machine: M;
928
+ readonly snapshot: Machine.Machine.Snapshot<Machine.Machine.States<M>>;
929
+ readonly configuration: ReadonlyArray<StatePath<M>>;
930
+ readonly depth: number;
931
+ readonly trace: Trace<M>;
932
+ }
933
+ /**
934
+ * One logical state discovered by breadth-first exploration.
935
+ *
936
+ * `trace` is the first, and therefore shortest, trace that reached `key`.
937
+ *
938
+ * @category exploration
939
+ * @since 0.4.0
940
+ */
941
+ export interface ExplorationNode<M extends AnyMachine, Key extends ExplorationKey = ExplorationKey> extends ExplorationStateContext<M> {
942
+ readonly key: Key;
943
+ }
944
+ /**
945
+ * One concretely planned public event in the exploration graph.
946
+ *
947
+ * @category exploration
948
+ * @since 0.4.0
949
+ */
950
+ export interface ExplorationEdge<M extends AnyMachine> {
951
+ readonly event: Machine.Machine.InputEvent<M>;
952
+ readonly step: TraceStep<M>;
953
+ readonly discovered: boolean;
954
+ }
955
+ /**
956
+ * One boundary that could not be explored because a hard limit was reached.
957
+ *
958
+ * @category exploration
959
+ * @since 0.4.0
960
+ */
961
+ export type ExplorationFrontier<M extends AnyMachine, Key extends ExplorationKey = ExplorationKey> = {
962
+ readonly _tag: "DepthLimit";
963
+ readonly source: Key;
964
+ readonly trace: Trace<M>;
965
+ readonly event: Machine.Machine.InputEvent<M>;
966
+ } | {
967
+ readonly _tag: "StateLimit";
968
+ readonly source: Key;
969
+ readonly trace: Trace<M>;
970
+ readonly event: Machine.Machine.InputEvent<M>;
971
+ readonly target: Key;
972
+ readonly targetTrace: Trace<M>;
973
+ } | {
974
+ readonly _tag: "TransitionLimit";
975
+ readonly source: Key;
976
+ readonly trace: Trace<M>;
977
+ readonly event: Machine.Machine.InputEvent<M>;
978
+ };
979
+ /**
980
+ * Honest completeness status for the supplied event representatives and state
981
+ * key abstraction.
982
+ *
983
+ * @category exploration
984
+ * @since 0.4.0
985
+ */
986
+ export type ExplorationCompleteness<M extends AnyMachine, Key extends ExplorationKey = ExplorationKey> = {
987
+ readonly _tag: "Complete";
988
+ } | {
989
+ readonly _tag: "Truncated";
990
+ readonly reasons: ReadonlyArray<"depth" | "states" | "transitions">;
991
+ readonly frontier: ReadonlyArray<ExplorationFrontier<M, Key>>;
992
+ };
993
+ /**
994
+ * Deterministic breadth-first exploration counts.
995
+ *
996
+ * @category exploration
997
+ * @since 0.4.0
998
+ */
999
+ export interface ExplorationStats {
1000
+ readonly states: number;
1001
+ readonly plannedTransitions: number;
1002
+ readonly retainedEdges: number;
1003
+ readonly maxDepth: number;
1004
+ }
1005
+ /**
1006
+ * A bounded logical state graph and its shortest-path evidence.
1007
+ *
1008
+ * @category exploration
1009
+ * @since 0.4.0
1010
+ */
1011
+ export interface Exploration<M extends AnyMachine, Key extends ExplorationKey = ExplorationKey> {
1012
+ readonly graph: Graph.DirectedGraph<ExplorationNode<M, Key>, ExplorationEdge<M>>;
1013
+ readonly nodes: ReadonlyArray<ExplorationNode<M, Key>>;
1014
+ readonly nodesByKey: ReadonlyMap<Key, Graph.NodeIndex>;
1015
+ readonly start: Graph.NodeIndex;
1016
+ readonly limits: ResolvedExplorationLimits;
1017
+ readonly stats: ExplorationStats;
1018
+ readonly completeness: ExplorationCompleteness<M, Key>;
1019
+ }
1020
+ interface ExploreOptionsBase<M extends AnyMachine, Key extends ExplorationKey> {
1021
+ readonly events: (context: ExplorationStateContext<M>) => ReadonlyArray<Machine.Machine.InputEvent<M>>;
1022
+ readonly stateKey: (context: ExplorationStateContext<M>) => Key;
1023
+ readonly limits?: ExplorationLimits;
1024
+ readonly invariants?: ReadonlyArray<Invariant<M>>;
1025
+ }
1026
+ /**
1027
+ * Configuration for bounded planner exploration.
1028
+ *
1029
+ * Event representatives may depend on the current state. Exploration is
1030
+ * exhaustive only relative to those representatives and the equivalence
1031
+ * relation defined by `stateKey`.
1032
+ *
1033
+ * @category exploration
1034
+ * @since 0.4.0
1035
+ */
1036
+ export type ExploreOptions<M extends AnyMachine, Key extends ExplorationKey = ExplorationKey> = ExploreOptionsBase<M, Key> & (Machine.Machine.Input<M> extends typeof Schema.Void ? {
1037
+ readonly input?: never;
1038
+ } : {
1039
+ readonly input: InputValue<M>;
1040
+ });
1041
+ /**
1042
+ * Explores the bounded logical state graph in breadth-first order.
1043
+ *
1044
+ * Invariants are checked against startup and every concretely planned edge,
1045
+ * so a failure retains a shortest discovered counterexample. Staged actions
1046
+ * and runtime activities are not executed.
1047
+ *
1048
+ * **Example**
1049
+ *
1050
+ * ```ts
1051
+ * import { Schema } from "effect"
1052
+ * import { Machine } from "@typeonce/effect-machine"
1053
+ * import { MachineTest } from "@typeonce/effect-machine/testing"
1054
+ *
1055
+ * class Count extends Schema.TaggedClass<Count>("Count")("Count", {
1056
+ * value: Schema.Number
1057
+ * }) {}
1058
+ * class Increment extends Schema.TaggedClass<Increment>("Increment")("Increment", {}) {}
1059
+ * const States = Machine.defineStates({ Count })
1060
+ * const machine = Machine.make({
1061
+ * states: States.states,
1062
+ * events: [Increment],
1063
+ * initial: () => States.initial.Count(new Count({ value: 0 }))
1064
+ * }).handle({
1065
+ * Count: { on: { Increment: ({ state }) =>
1066
+ * States.initial.Count(new Count({ value: state.value + 1 })) } }
1067
+ * })
1068
+ *
1069
+ * const explored = MachineTest.explore(machine, {
1070
+ * events: ({ snapshot }) => snapshot.value.value < 2 ? [new Increment({})] : [],
1071
+ * stateKey: ({ snapshot }) => snapshot.value.value
1072
+ * })
1073
+ * ```
1074
+ *
1075
+ * @category exploration
1076
+ * @since 0.4.0
1077
+ */
1078
+ export declare const explore: <M extends AnyMachine, Key extends ExplorationKey>(machine: ReadyMachine<M>, options: ExploreOptions<M, Key>) => Effect.Effect<Exploration<M, Key>, RunFailure<RunError<M>, M> | internal.InvariantError<M>, RunServices<M>>;
1079
+ /**
1080
+ * A predicate over one explored logical state.
1081
+ *
1082
+ * @category exploration
1083
+ * @since 0.4.0
1084
+ */
1085
+ export type ExplorationPredicate<M extends AnyMachine, Key extends ExplorationKey = ExplorationKey> = (node: ExplorationNode<M, Key>) => boolean;
1086
+ /**
1087
+ * Why a reachability assertion failed.
1088
+ *
1089
+ * @category exploration
1090
+ * @since 0.4.0
1091
+ */
1092
+ export type ReachabilityFailure = "NotFound" | "UnexpectedMatch" | "Inconclusive";
1093
+ /**
1094
+ * A failed or inconclusive reachability assertion.
1095
+ *
1096
+ * @category errors
1097
+ * @since 0.4.0
1098
+ */
1099
+ export { ReachabilityError } from "../internal/testing/machine/verification.js";
1100
+ /**
1101
+ * Finds the first, and therefore shortest, explored state matching a
1102
+ * predicate.
1103
+ *
1104
+ * @category exploration
1105
+ * @since 0.4.0
1106
+ */
1107
+ export declare const findShortest: <M extends AnyMachine, Key extends ExplorationKey>(exploration: Exploration<M, Key>, predicate: ExplorationPredicate<M, Key>) => ExplorationNode<M, Key> | undefined;
1108
+ /**
1109
+ * Requires a matching state and returns its shortest witness.
1110
+ *
1111
+ * A truncated exploration without a witness fails as inconclusive rather than
1112
+ * claiming the state is unreachable.
1113
+ *
1114
+ * @category exploration
1115
+ * @since 0.4.0
1116
+ */
1117
+ export declare const assertReachable: <M extends AnyMachine, Key extends ExplorationKey>(exploration: Exploration<M, Key>, name: string, predicate: ExplorationPredicate<M, Key>) => Effect.Effect<ExplorationNode<M, Key>, internal.ReachabilityError<M, Key>>;
1118
+ /**
1119
+ * Requires that no explored state matches a predicate.
1120
+ *
1121
+ * This assertion succeeds only for a complete exploration. A truncated
1122
+ * result without a witness fails as inconclusive.
1123
+ *
1124
+ * @category exploration
1125
+ * @since 0.4.0
1126
+ */
1127
+ export declare const assertUnreachable: <M extends AnyMachine, Key extends ExplorationKey>(exploration: Exploration<M, Key>, name: string, predicate: ExplorationPredicate<M, Key>) => Effect.Effect<void, internal.ReachabilityError<M, Key>>;
1128
+ /**
1129
+ * Checks a real planner trace against the independent finite statechart model
1130
+ * interpreter.
1131
+ *
1132
+ * The oracle does not import the machine compiler, planner, snapshot helpers,
1133
+ * or target builders. It compares semantic projections of the public trace
1134
+ * and accumulates every disagreement in one structured error.
1135
+ *
1136
+ * @category verification
1137
+ * @since 0.4.0
1138
+ */
1139
+ export declare const verifyModel: <M extends AnyMachine>(model: FiniteModel, actualTrace: Trace<M>) => Effect.Effect<void, ReferenceModel.ModelVerificationError>;
1140
+ /**
1141
+ * A typed planning failure together with every successfully completed trace
1142
+ * segment preceding it.
1143
+ *
1144
+ * @category models
1145
+ * @since 0.4.0
1146
+ */
1147
+ export type RunFailure<Cause, M extends AnyMachine = AnyMachine> = {
1148
+ readonly _tag: "MachineTestRunFailure";
1149
+ readonly scenario: Scenario<M>;
1150
+ readonly phase: "initial";
1151
+ readonly eventIndex: undefined;
1152
+ readonly event: undefined;
1153
+ readonly initial: undefined;
1154
+ readonly steps: readonly [];
1155
+ readonly cause: Cause;
1156
+ } | {
1157
+ readonly _tag: "MachineTestRunFailure";
1158
+ readonly scenario: Scenario<M>;
1159
+ readonly phase: "event";
1160
+ readonly eventIndex: number;
1161
+ readonly event: Machine.Machine.InputEvent<M>;
1162
+ readonly initial: InitialTrace<M>;
1163
+ readonly steps: ReadonlyArray<TraceStep<M>>;
1164
+ readonly cause: Cause;
1165
+ };
1166
+ /**
1167
+ * Errors that can be produced while planning a complete scenario.
1168
+ *
1169
+ * @category errors
1170
+ * @since 0.4.0
1171
+ */
1172
+ export type RunError<M extends AnyMachine> = Machine.Machine.InitialError<M> | Machine.Machine.Error<M> | Machine.InfiniteTransitionError | Machine.MachineSchemaDecodeError | Machine.StartupError;
1173
+ /**
1174
+ * Services required while planning a complete scenario.
1175
+ *
1176
+ * Scenario execution delegates exclusively to the service-free `planInitial`
1177
+ * and `plan` APIs. Invoke services and managed runtime capabilities belong to
1178
+ * later execution, not synchronous planning.
1179
+ *
1180
+ * @category models
1181
+ * @since 0.4.0
1182
+ */
1183
+ export type RunServices<M extends AnyMachine> = IsAny<Machine.PlanningServices<Machine.Machine.InitialServices<M> | Machine.Machine.Services<M>>> extends true ? Machine.PlanningServices<Machine.Machine.InitialServices<M> | Machine.Machine.Services<M>> : never;
1184
+ /**
1185
+ * Executes a generated scenario exclusively through `planInitial` and `plan`.
1186
+ *
1187
+ * Staged actions are retained in each plan but are never executed. Every event
1188
+ * is planned, including events that occur after a terminal configuration.
1189
+ * Typed planning errors retain the scenario and successfully completed prefix
1190
+ * in a `RunFailure`.
1191
+ *
1192
+ * **Example**
1193
+ *
1194
+ * ```ts
1195
+ * import { Schema } from "effect"
1196
+ * import { Machine } from "@typeonce/effect-machine"
1197
+ * import { MachineTest } from "@typeonce/effect-machine/testing"
1198
+ *
1199
+ * class Idle extends Schema.TaggedClass<Idle>("Idle")("Idle", {}) {}
1200
+ * const States = Machine.defineStates({ Idle })
1201
+ * const machine = Machine.make({
1202
+ * states: States.states,
1203
+ * events: [],
1204
+ * initial: () => States.initial.Idle.from()
1205
+ * }).handle({ Idle: {} })
1206
+ *
1207
+ * const trace = MachineTest.run(machine, { events: [] })
1208
+ * ```
1209
+ *
1210
+ * @category constructors
1211
+ * @since 0.4.0
1212
+ */
1213
+ export declare const run: <M extends AnyMachine>(machine: ReadyMachine<M>, scenario: Scenario<M>) => Effect.Effect<Trace<M>, RunFailure<RunError<M>, M>, RunServices<M>>;
1214
+ /**
1215
+ * A deterministic hit/miss summary for a finite set declared by a machine.
1216
+ *
1217
+ * @category models
1218
+ * @since 0.4.0
1219
+ */
1220
+ export interface CoverageSummary<Item> {
1221
+ readonly total: number;
1222
+ readonly hit: number;
1223
+ readonly missing: number;
1224
+ readonly hits: ReadonlyArray<Item>;
1225
+ readonly misses: ReadonlyArray<Item>;
1226
+ }
1227
+ /**
1228
+ * One active (non-history) state node in a state coverage summary.
1229
+ *
1230
+ * @category models
1231
+ * @since 0.4.0
1232
+ */
1233
+ export interface StateCoverageItem<Path extends string = string> {
1234
+ readonly path: Path;
1235
+ readonly type: Exclude<Machine.Machine.StateNode["type"], "history">;
1236
+ }
1237
+ /**
1238
+ * State activation and lifecycle coverage.
1239
+ *
1240
+ * @category models
1241
+ * @since 0.4.0
1242
+ */
1243
+ export interface StateCoverage<Path extends string = string> {
1244
+ readonly activation: CoverageSummary<StateCoverageItem<Path>>;
1245
+ readonly entry: CoverageSummary<StateCoverageItem<Path>>;
1246
+ readonly exit: CoverageSummary<StateCoverageItem<Path>>;
1247
+ }
1248
+ /**
1249
+ * One stable transition-definition identity in definition order.
1250
+ *
1251
+ * @category models
1252
+ * @since 0.4.0
1253
+ */
1254
+ export interface TransitionCoverageItem<SourcePath extends string = string, EventTag extends PropertyKey = PropertyKey, TargetPath extends string = SourcePath> {
1255
+ readonly id: string;
1256
+ readonly index: number;
1257
+ readonly source: SourcePath;
1258
+ readonly trigger: Machine.Machine.TransitionTrigger<EventTag>;
1259
+ readonly reenter: boolean;
1260
+ readonly targets: Machine.Machine.TransitionTargets<TargetPath>;
1261
+ }
1262
+ /**
1263
+ * One public event tag declared by the machine.
1264
+ *
1265
+ * @category models
1266
+ * @since 0.4.0
1267
+ */
1268
+ export interface EventCoverageItem<Tag extends PropertyKey = PropertyKey> {
1269
+ readonly tag: Tag;
1270
+ readonly count: number;
1271
+ }
1272
+ /**
1273
+ * Public event coverage, including events that no transition retained.
1274
+ *
1275
+ * @category models
1276
+ * @since 0.4.0
1277
+ */
1278
+ export type EventCoverage<Tag extends PropertyKey = PropertyKey> = {
1279
+ readonly available: true;
1280
+ readonly total: number;
1281
+ readonly hit: number;
1282
+ readonly missing: number;
1283
+ readonly hits: ReadonlyArray<EventCoverageItem<Tag>>;
1284
+ readonly misses: ReadonlyArray<EventCoverageItem<Tag>>;
1285
+ readonly observed: ReadonlyArray<EventCoverageItem<Tag>>;
1286
+ readonly diagnostics: readonly [];
1287
+ } | {
1288
+ readonly available: false;
1289
+ readonly total: undefined;
1290
+ readonly hit: undefined;
1291
+ readonly missing: undefined;
1292
+ readonly hits: undefined;
1293
+ readonly misses: undefined;
1294
+ readonly observed: ReadonlyArray<EventCoverageItem<Tag>>;
1295
+ readonly diagnostics: ReadonlyArray<{
1296
+ readonly schemaIndex: number;
1297
+ readonly message: string;
1298
+ }>;
1299
+ };
1300
+ /**
1301
+ * Trace-derived scenario counts. There is no finite declared scenario space.
1302
+ *
1303
+ * @category models
1304
+ * @since 0.4.0
1305
+ */
1306
+ export interface ScenarioCoverage {
1307
+ readonly traces: number;
1308
+ readonly events: number;
1309
+ readonly empty: number;
1310
+ }
1311
+ /**
1312
+ * Trace-derived logical configuration counts. There is no claimed exhaustive total.
1313
+ *
1314
+ * @category models
1315
+ * @since 0.4.0
1316
+ */
1317
+ export interface LogicalConfigurationCoverage {
1318
+ readonly observations: number;
1319
+ readonly hit: number;
1320
+ readonly identities: ReadonlyArray<string>;
1321
+ }
1322
+ /**
1323
+ * Directly observed startup and microstep evidence.
1324
+ *
1325
+ * @category models
1326
+ * @since 0.4.0
1327
+ */
1328
+ export interface MicrostepCoverageEvidence {
1329
+ readonly total: number;
1330
+ readonly changed: number;
1331
+ readonly targetless: number;
1332
+ readonly raised: number;
1333
+ readonly emitted: number;
1334
+ readonly eventTriggered: number;
1335
+ readonly alwaysTriggered: number;
1336
+ readonly doneTriggered: number;
1337
+ readonly choiceTriggered: number;
1338
+ }
1339
+ /**
1340
+ * Directly observed completion evidence.
1341
+ *
1342
+ * @category models
1343
+ * @since 0.4.0
1344
+ */
1345
+ export interface CompletionCoverageEvidence<Path extends string = string> {
1346
+ readonly donePlans: number;
1347
+ readonly recordObservations: number;
1348
+ readonly paths: ReadonlyArray<Path>;
1349
+ }
1350
+ /**
1351
+ * Directly observed history records and history-target transitions.
1352
+ *
1353
+ * @category models
1354
+ * @since 0.4.0
1355
+ */
1356
+ export interface HistoryCoverageEvidence<Path extends string = string> {
1357
+ readonly recordObservations: number;
1358
+ readonly recorded: ReadonlyArray<{
1359
+ readonly path: Path;
1360
+ readonly modes: ReadonlyArray<"shallow" | "deep">;
1361
+ }>;
1362
+ readonly targets: number;
1363
+ readonly resolvedTargets: number;
1364
+ }
1365
+ /**
1366
+ * Coverage computed only from observable machine definitions and planner traces.
1367
+ *
1368
+ * @category models
1369
+ * @since 0.4.0
1370
+ */
1371
+ export interface Coverage<M extends AnyMachine> {
1372
+ readonly states: StateCoverage<StatePath<M>>;
1373
+ readonly transitions: CoverageSummary<TransitionCoverageItem<StateNodePath<M>, Machine.Machine.TagOf<Machine.Machine.Events<M>[number]>, StateNodePath<M>>>;
1374
+ readonly events: EventCoverage<Machine.Machine.TagOf<Machine.Machine.InputEvents<M>[number]>>;
1375
+ readonly scenarios: ScenarioCoverage;
1376
+ readonly logicalConfigurations: LogicalConfigurationCoverage;
1377
+ readonly startup: {
1378
+ readonly traces: number;
1379
+ readonly withMicrosteps: number;
1380
+ };
1381
+ readonly microsteps: MicrostepCoverageEvidence;
1382
+ readonly completion: CompletionCoverageEvidence<StatePath<M>>;
1383
+ readonly history: HistoryCoverageEvidence<StateNodePath<M>>;
1384
+ }
1385
+ /**
1386
+ * Computes deterministic, definition-aware coverage from completed planner
1387
+ * traces. Finite declared sets report hits and misses; scenarios and logical
1388
+ * configurations report observations only because their complete spaces are
1389
+ * generally infinite.
1390
+ *
1391
+ * **Example**
1392
+ *
1393
+ * ```ts
1394
+ * import { Effect, Schema } from "effect"
1395
+ * import { Machine } from "@typeonce/effect-machine"
1396
+ * import { MachineTest } from "@typeonce/effect-machine/testing"
1397
+ *
1398
+ * class Idle extends Schema.TaggedClass<Idle>("Idle")("Idle", {}) {}
1399
+ * const States = Machine.defineStates({ Idle })
1400
+ * const machine = Machine.make({
1401
+ * states: States.states,
1402
+ * events: [],
1403
+ * initial: () => States.initial.Idle.from()
1404
+ * }).handle({ Idle: {} })
1405
+ *
1406
+ * const report = Effect.map(
1407
+ * MachineTest.run(machine, { events: [] }),
1408
+ * (trace) => MachineTest.coverage(machine, trace)
1409
+ * )
1410
+ * ```
1411
+ *
1412
+ * @category verification
1413
+ * @since 0.4.0
1414
+ */
1415
+ export declare const coverage: <M extends AnyMachine>(machine: M, traceOrTraces: Trace<M> | ReadonlyArray<Trace<M>>) => Coverage<M>;
1416
+ /**
1417
+ * The observation roles summarized for one logical graph node.
1418
+ *
1419
+ * @category models
1420
+ * @since 0.4.0
1421
+ */
1422
+ export interface ObservedGraphNodeObservations {
1423
+ readonly total: number;
1424
+ readonly startup: number;
1425
+ readonly event: number;
1426
+ readonly microstep: number;
1427
+ }
1428
+ /**
1429
+ * One full encoded logical snapshot stored in the observed Effect graph.
1430
+ *
1431
+ * @category models
1432
+ * @since 0.4.0
1433
+ */
1434
+ export interface ObservedGraphNode<M extends AnyMachine> {
1435
+ readonly id: string;
1436
+ readonly snapshot: Machine.Machine.Snapshot<Machine.Machine.States<M>>;
1437
+ readonly encoded: Machine.Machine.EncodedSnapshot;
1438
+ readonly configuration: ReadonlyArray<StatePath<M>>;
1439
+ readonly observations: ObservedGraphNodeObservations;
1440
+ }
1441
+ /**
1442
+ * Retained evidence for one microstep inside an observed graph edge.
1443
+ *
1444
+ * @category models
1445
+ * @since 0.4.0
1446
+ */
1447
+ export interface ObservedGraphMicrostep<M extends AnyMachine> {
1448
+ readonly next: string;
1449
+ readonly event: Machine.Machine.Event<M> | Machine.InitialEvent;
1450
+ readonly transitions: Microstep<M, any>["transitions"];
1451
+ readonly raisedEvents: ReadonlyArray<Machine.Machine.Event<M>>;
1452
+ readonly emittedEvents: ReadonlyArray<Machine.Machine.Emit<M>>;
1453
+ readonly exitPaths: ReadonlyArray<StatePath<M>>;
1454
+ readonly entryPaths: ReadonlyArray<StatePath<M>>;
1455
+ readonly changed: boolean;
1456
+ }
1457
+ /**
1458
+ * A startup or public-event macrostep retained by the observed graph.
1459
+ *
1460
+ * @category models
1461
+ * @since 0.4.0
1462
+ */
1463
+ export type ObservedGraphEdge<M extends AnyMachine> = {
1464
+ readonly _tag: "Startup";
1465
+ readonly traceIndex: number;
1466
+ readonly microsteps: ReadonlyArray<ObservedGraphMicrostep<M>>;
1467
+ readonly completion: PlanCompletion<M>;
1468
+ } | {
1469
+ readonly _tag: "Event";
1470
+ readonly traceIndex: number;
1471
+ readonly eventIndex: number;
1472
+ readonly event: Machine.Machine.InputEvent<M>;
1473
+ readonly microsteps: ReadonlyArray<ObservedGraphMicrostep<M>>;
1474
+ readonly completion: PlanCompletion<M>;
1475
+ };
1476
+ /**
1477
+ * An Effect directed graph plus stable indexes useful to graph algorithms.
1478
+ *
1479
+ * @category models
1480
+ * @since 0.4.0
1481
+ */
1482
+ export interface ObservedGraph<M extends AnyMachine> {
1483
+ readonly graph: Graph.DirectedGraph<ObservedGraphNode<M>, ObservedGraphEdge<M>>;
1484
+ readonly nodesById: ReadonlyMap<string, Graph.NodeIndex>;
1485
+ /** Settled post-startup nodes from which public event paths begin. */
1486
+ readonly starts: ReadonlyArray<Graph.NodeIndex>;
1487
+ /** Pre-settled startup sources connected to `starts` by `Startup` edges. */
1488
+ readonly startupSources: ReadonlyArray<Graph.NodeIndex>;
1489
+ }
1490
+ /**
1491
+ * Converts concrete planner traces into an observed logical-state graph.
1492
+ * Nodes are deduplicated by the public snapshot encoding and every edge is a
1493
+ * concrete startup or public-event macrostep. This intentionally does not
1494
+ * claim to be a static or exhaustive graph of the machine.
1495
+ *
1496
+ * @category verification
1497
+ * @since 0.4.0
1498
+ */
1499
+ export declare const observedGraph: <M extends AnyMachine>(machine: M, traceOrTraces: Trace<M> | ReadonlyArray<Trace<M>>) => Effect.Effect<ObservedGraph<M>, Machine.MachineSchemaEncodeError, Machine.Machine.SnapshotEncodingServices<Machine.Machine.States<M>>>;
1500
+ /**
1501
+ * Independently checked families of planner laws.
1502
+ *
1503
+ * @category models
1504
+ * @since 0.4.0
1505
+ */
1506
+ export type VerificationLawGroup = "configuration" | "microsteps" | "completion" | "history" | "targetBounds";
1507
+ /**
1508
+ * Stable identifiers for individual planner laws.
1509
+ *
1510
+ * @category models
1511
+ * @since 0.4.0
1512
+ */
1513
+ export type VerificationLaw = "configuration.shape" | "configuration.path" | "configuration.schema" | "configuration.hierarchy" | "configuration.compound" | "configuration.parallel" | "configuration.duplicate" | "configuration.trace" | "microsteps.unique" | "microsteps.order" | "microsteps.activeBefore" | "microsteps.activeAfter" | "microsteps.changed" | "microsteps.continuity" | "microsteps.reentry" | "completion.record" | "completion.output" | "completion.done" | "history.record" | "history.mode" | "history.path" | "history.value" | "history.shallow" | "history.deep" | "targetBounds.definition" | "targetBounds.target";
1514
+ /**
1515
+ * One independently observed violation in a planner trace.
1516
+ *
1517
+ * @category models
1518
+ * @since 0.4.0
1519
+ */
1520
+ export interface VerificationViolation {
1521
+ readonly law: VerificationLaw;
1522
+ /** `undefined` identifies startup; otherwise this is the scenario event index. */
1523
+ readonly eventIndex: number | undefined;
1524
+ readonly microstepIndex?: number;
1525
+ readonly path?: string;
1526
+ readonly message: string;
1527
+ }
1528
+ /**
1529
+ * All violations found while checking one trace.
1530
+ *
1531
+ * @category errors
1532
+ * @since 0.4.0
1533
+ */
1534
+ export { VerificationError } from "../internal/testing/machine/verification.js";
1535
+ /**
1536
+ * Selects law families for the single canonical verifier. All run by default.
1537
+ *
1538
+ * @category models
1539
+ * @since 0.4.0
1540
+ */
1541
+ export interface VerifyOptions {
1542
+ readonly laws?: ReadonlyArray<VerificationLawGroup>;
1543
+ }
1544
+ /**
1545
+ * Verifies an executed trace using only public machine inspection and raw
1546
+ * snapshot data. The verifier deliberately does not reuse planner
1547
+ * normalization, encoding, finality, or other internal helpers.
1548
+ *
1549
+ * Every selected law is evaluated and returned in one structured error so a
1550
+ * shrunk property-test counterexample retains all relevant evidence.
1551
+ *
1552
+ * **Example**
1553
+ *
1554
+ * ```ts
1555
+ * import { Effect, Schema } from "effect"
1556
+ * import { Machine } from "@typeonce/effect-machine"
1557
+ * import { MachineTest } from "@typeonce/effect-machine/testing"
1558
+ *
1559
+ * class Idle extends Schema.TaggedClass<Idle>("Idle")("Idle", {}) {}
1560
+ * const States = Machine.defineStates({ Idle })
1561
+ * const machine = Machine.make({
1562
+ * states: States.states,
1563
+ * events: [],
1564
+ * initial: () => States.initial.Idle.from()
1565
+ * }).handle({ Idle: {} })
1566
+ *
1567
+ * const checked = Effect.gen(function*() {
1568
+ * const trace = yield* MachineTest.run(machine, { events: [] })
1569
+ * yield* MachineTest.verify(machine, trace)
1570
+ * })
1571
+ * ```
1572
+ *
1573
+ * @category verification
1574
+ * @since 0.4.0
1575
+ */
1576
+ export declare const verify: <M extends AnyMachine>(machine: M, trace: Trace<M>, options?: VerifyOptions) => Effect.Effect<void, VerificationError>;
1577
+ /**
1578
+ * Formats a trace as deterministic, line-oriented counterexample evidence.
1579
+ *
1580
+ * Object keys and map/set entries are canonicalized. Deferred effects are
1581
+ * represented by counts so formatting never evaluates or inspects actions.
1582
+ * Failures include their original cause and every available successful prefix.
1583
+ *
1584
+ * @category formatting
1585
+ * @since 0.4.0
1586
+ */
1587
+ export declare const formatTrace: <M extends AnyMachine, Cause>(trace: Trace<M> | RunFailure<Cause, M>) => string;
1588
+ //# sourceMappingURL=MachineTest.d.ts.map