@astrale-os/sdk 0.6.0-beta.41 → 0.6.0-beta.43

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 (177) hide show
  1. package/README.md +22 -2
  2. package/dist/application/action/context.d.ts +49 -18
  3. package/dist/application/action/index.d.ts +1 -1
  4. package/dist/application/error/error.d.ts +16 -1
  5. package/dist/application/error/error.js +39 -5
  6. package/dist/application/error/index.d.ts +1 -1
  7. package/dist/application/error/index.js +1 -1
  8. package/dist/application/mutation/authoring/builder.d.ts +81 -33
  9. package/dist/application/mutation/authoring/builder.js +100 -30
  10. package/dist/application/mutation/authoring/guard.d.ts +37 -0
  11. package/dist/application/mutation/authoring/guard.js +150 -0
  12. package/dist/application/mutation/authoring/index.d.ts +5 -2
  13. package/dist/application/mutation/authoring/index.js +2 -1
  14. package/dist/application/mutation/authoring/names.d.ts +19 -0
  15. package/dist/application/mutation/authoring/names.js +83 -0
  16. package/dist/application/mutation/authoring/transition.d.ts +3 -2
  17. package/dist/application/mutation/define.d.ts +24 -10
  18. package/dist/application/mutation/define.js +49 -53
  19. package/dist/application/mutation/execution/execute.d.ts +2 -2
  20. package/dist/application/mutation/execution/execute.js +78 -7
  21. package/dist/application/mutation/execution/executor.d.ts +4 -1
  22. package/dist/application/mutation/execution/executor.js +6 -1
  23. package/dist/application/mutation/failure.d.ts +11 -1
  24. package/dist/application/mutation/failure.js +18 -3
  25. package/dist/application/mutation/index.d.ts +8 -4
  26. package/dist/application/mutation/index.js +5 -2
  27. package/dist/application/mutation/legacy/v6/builder.d.ts +84 -0
  28. package/dist/application/mutation/legacy/v6/define.d.ts +18 -0
  29. package/dist/application/mutation/legacy/v6/define.js +56 -0
  30. package/dist/application/mutation/legacy/v6/mutation.d.ts +28 -0
  31. package/dist/application/mutation/legacy/v6/mutation.js +1 -0
  32. package/dist/application/mutation/{authoring → legacy/v6}/precondition.d.ts +4 -0
  33. package/dist/application/mutation/mutation.d.ts +30 -19
  34. package/dist/application/query/answer/answer.d.ts +117 -0
  35. package/dist/application/query/answer/answer.js +1 -0
  36. package/dist/application/query/answer/conformance.d.ts +4 -0
  37. package/dist/application/query/answer/conformance.js +27 -0
  38. package/dist/application/query/answer/facts.d.ts +17 -0
  39. package/dist/application/query/answer/facts.js +57 -0
  40. package/dist/application/query/composite/builder.d.ts +1 -1
  41. package/dist/application/query/composite/builder.js +1 -1
  42. package/dist/application/query/composite/plan.d.ts +1 -1
  43. package/dist/application/query/composite/plan.js +1 -1
  44. package/dist/application/query/composite/query.d.ts +1 -2
  45. package/dist/application/query/define.d.ts +2 -33
  46. package/dist/application/query/define.js +3 -130
  47. package/dist/application/query/definition.d.ts +12 -0
  48. package/dist/application/query/definition.js +47 -0
  49. package/dist/application/query/execution/bounds.d.ts +22 -0
  50. package/dist/application/query/execution/bounds.js +88 -0
  51. package/dist/application/query/execution/crossings.d.ts +25 -0
  52. package/dist/application/query/execution/crossings.js +192 -0
  53. package/dist/application/query/execution/error.d.ts +68 -0
  54. package/dist/application/query/execution/error.js +50 -0
  55. package/dist/application/query/execution/execute.d.ts +2 -7
  56. package/dist/application/query/execution/execute.js +3 -51
  57. package/dist/application/query/execution/recipe.d.ts +85 -0
  58. package/dist/application/query/execution/recipe.js +324 -0
  59. package/dist/application/query/execution/refusal.d.ts +37 -0
  60. package/dist/application/query/execution/refusal.js +80 -0
  61. package/dist/application/query/execution/rows.d.ts +42 -0
  62. package/dist/application/query/execution/rows.js +308 -0
  63. package/dist/application/query/execution/split.d.ts +24 -0
  64. package/dist/application/query/execution/split.js +190 -0
  65. package/dist/application/query/handles/build.d.ts +10 -0
  66. package/dist/application/query/handles/build.js +53 -0
  67. package/dist/application/query/handles/conditions.d.ts +94 -0
  68. package/dist/application/query/handles/conditions.js +1 -0
  69. package/dist/application/query/handles/domain.d.ts +157 -0
  70. package/dist/application/query/handles/domain.js +1 -0
  71. package/dist/application/query/handles/handles.d.ts +268 -0
  72. package/dist/application/query/handles/handles.js +1 -0
  73. package/dist/application/query/handles/model.d.ts +96 -0
  74. package/dist/application/query/handles/model.js +246 -0
  75. package/dist/application/query/handles/plan.d.ts +99 -0
  76. package/dist/application/query/handles/plan.js +37 -0
  77. package/dist/application/query/handles/reads.d.ts +106 -0
  78. package/dist/application/query/handles/reads.js +839 -0
  79. package/dist/application/query/handles/relations.d.ts +100 -0
  80. package/dist/application/query/handles/relations.js +1 -0
  81. package/dist/application/query/handles/rows.d.ts +94 -0
  82. package/dist/application/query/handles/rows.js +4 -0
  83. package/dist/application/query/handles/terms.d.ts +103 -0
  84. package/dist/application/query/handles/terms.js +282 -0
  85. package/dist/application/query/index.d.ts +10 -7
  86. package/dist/application/query/index.js +9 -4
  87. package/dist/application/query/language/index.d.ts +2 -0
  88. package/dist/application/query/language/index.js +2 -0
  89. package/dist/application/query/language/query.d.ts +323 -0
  90. package/dist/application/query/language/query.js +2 -0
  91. package/dist/application/query/{collection → legacy/v6/collection}/identity.d.ts +2 -2
  92. package/dist/application/query/{collection → legacy/v6/collection}/metadata.d.ts +1 -1
  93. package/dist/application/query/{collection → legacy/v6/collection}/union.d.ts +3 -3
  94. package/dist/application/query/{collection → legacy/v6/collection}/union.js +1 -1
  95. package/dist/application/query/{conformance.d.ts → legacy/v6/conformance.d.ts} +3 -3
  96. package/dist/application/query/{conformance.js → legacy/v6/conformance.js} +1 -1
  97. package/dist/application/query/legacy/v6/define.d.ts +37 -0
  98. package/dist/application/query/legacy/v6/define.js +90 -0
  99. package/dist/application/query/legacy/v6/execution/execute.d.ts +16 -0
  100. package/dist/application/query/legacy/v6/execution/execute.js +50 -0
  101. package/dist/application/query/legacy/v6/index.d.ts +6 -0
  102. package/dist/application/query/legacy/v6/index.js +3 -0
  103. package/dist/application/query/legacy/v6/kernel.d.ts +6 -0
  104. package/dist/application/query/legacy/v6/kernel.js +5 -0
  105. package/dist/application/query/{single → legacy/v6/single}/pagination.js +1 -1
  106. package/dist/application/query/{single → legacy/v6/single}/query.d.ts +2 -14
  107. package/dist/application/query/legacy/v6/single/query.js +1 -0
  108. package/dist/application/query/query.d.ts +16 -1
  109. package/dist/application/query/recipe/define.d.ts +44 -0
  110. package/dist/application/query/recipe/define.js +95 -0
  111. package/dist/application/query/recipe/recipe.d.ts +134 -0
  112. package/dist/application/query/recipe/recipe.js +1 -0
  113. package/dist/application/workflow/durable.d.ts +22 -8
  114. package/dist/deployment/build/build.d.ts +8 -1
  115. package/dist/deployment/build/material.js +3 -0
  116. package/dist/execution/invocation/capabilities/bind.d.ts +6 -4
  117. package/dist/execution/invocation/capabilities/bind.js +39 -3
  118. package/dist/execution/invocation/dispatch/action.js +4 -2
  119. package/dist/execution/invocation/dispatch/context.js +1 -1
  120. package/dist/execution/invocation/dispatch/workflow.js +4 -2
  121. package/dist/execution/invocation/result/index.d.ts +1 -0
  122. package/dist/execution/invocation/result/index.js +1 -0
  123. package/dist/execution/invocation/result/recipe.d.ts +6 -0
  124. package/dist/execution/invocation/result/recipe.js +17 -0
  125. package/dist/execution/service/create.js +1 -0
  126. package/dist/execution/workflows/failure.d.ts +23 -6
  127. package/dist/execution/workflows/failure.js +78 -18
  128. package/dist/execution/workflows/receiver.d.ts +3 -0
  129. package/dist/execution/workflows/receiver.js +1 -0
  130. package/dist/execution/workflows/run.js +13 -9
  131. package/dist/execution/workflows/steps.d.ts +3 -0
  132. package/dist/execution/workflows/steps.js +2 -2
  133. package/dist/platform/schema/kernel-compiled.d.ts +2 -0
  134. package/dist/platform/schema/kernel-compiled.js +2 -0
  135. package/dist/testing/index.d.ts +2 -0
  136. package/dist/testing/index.js +1 -0
  137. package/dist/testing/recipe.d.ts +17 -0
  138. package/dist/testing/recipe.js +34 -0
  139. package/dist/tooling/cli/orchestrate.js +6 -2
  140. package/dist/tooling/linter/adapters/typescript/index.d.ts +2 -1
  141. package/dist/tooling/linter/adapters/typescript/index.js +2 -1
  142. package/dist/tooling/linter/adapters/typescript/query-observation.js +37 -12
  143. package/dist/tooling/linter/adapters/typescript/recipe-definitions.d.ts +34 -0
  144. package/dist/tooling/linter/adapters/typescript/recipe-definitions.js +88 -0
  145. package/dist/tooling/linter/adapters/typescript/type-analysis.d.ts +2 -0
  146. package/dist/tooling/linter/adapters/typescript/type-analysis.js +10 -0
  147. package/dist/tooling/linter/implementations/source/global.js +15 -9
  148. package/dist/tooling/linter/implementations/source/mutations.js +128 -19
  149. package/dist/tooling/linter/implementations/source/policy-edges.d.ts +2 -0
  150. package/dist/tooling/linter/implementations/source/policy-edges.js +113 -0
  151. package/dist/tooling/linter/implementations/source/recipes.d.ts +2 -0
  152. package/dist/tooling/linter/implementations/source/recipes.js +425 -0
  153. package/dist/tooling/linter/implementations/source/shared.d.ts +7 -1
  154. package/dist/tooling/linter/implementations/source/shared.js +31 -10
  155. package/dist/tooling/linter/implementations/source/verifiers.js +4 -0
  156. package/dist/tooling/linter/policy/generated.js +2 -2
  157. package/dist/tooling/linter/requirements/registry.js +4 -0
  158. package/docs/durable-workflows.md +48 -20
  159. package/docs/handler-dependencies.md +76 -4
  160. package/docs/legacy/query-v6.md +62 -0
  161. package/docs/queries.md +442 -0
  162. package/package.json +11 -8
  163. /package/dist/application/{query/single/query.js → mutation/legacy/v6/builder.js} +0 -0
  164. /package/dist/application/mutation/{authoring → legacy/v6}/precondition.js +0 -0
  165. /package/dist/application/query/{collection → legacy/v6/collection}/identity.js +0 -0
  166. /package/dist/application/query/{collection → legacy/v6/collection}/limits.d.ts +0 -0
  167. /package/dist/application/query/{collection → legacy/v6/collection}/limits.js +0 -0
  168. /package/dist/application/query/{collection → legacy/v6/collection}/metadata.js +0 -0
  169. /package/dist/application/query/{execution → legacy/v6/execution}/pages.d.ts +0 -0
  170. /package/dist/application/query/{execution → legacy/v6/execution}/pages.js +0 -0
  171. /package/dist/application/query/{single → legacy/v6/single}/index.d.ts +0 -0
  172. /package/dist/application/query/{single → legacy/v6/single}/index.js +0 -0
  173. /package/dist/application/query/{single → legacy/v6/single}/node.d.ts +0 -0
  174. /package/dist/application/query/{single → legacy/v6/single}/node.js +0 -0
  175. /package/dist/application/query/{single → legacy/v6/single}/pagination.d.ts +0 -0
  176. /package/dist/application/query/{single → legacy/v6/single}/selection.d.ts +0 -0
  177. /package/dist/application/query/{single → legacy/v6/single}/selection.js +0 -0
@@ -1,5 +1,5 @@
1
1
  import type { DurableEngine } from './engine.js';
2
- /** Failure code of an Execution whose Workflow did not catch a Step that spent its retry budget. */
2
+ /** Failure code of an Execution whose Workflow did not catch a Step that failed for good. */
3
3
  export declare const STEP_EXHAUSTED = "STEP_EXHAUSTED";
4
4
  /** A Kernel refusal as the wire names it: its protocol code and, when given, its reason code. */
5
5
  export interface KernelRefusal {
@@ -26,14 +26,31 @@ export declare class StepRetryAfter extends Error {
26
26
  constructor(delayMs: number, cause?: unknown);
27
27
  }
28
28
  /**
29
- * Encode a declared business error of `definition`, or a Step that spent its retry budget, as a
30
- * terminal engine failure, or return undefined for any other error, which the engine retries.
29
+ * Encode what a Workflow did not catch as the Execution's failure: a Step's recipe failure ends it
30
+ * with `STEP_EXHAUSTED`, naming the recipe and a `QueryError`'s code, never its details, which a
31
+ * read as the executor may fill with what the Execution's reader may not read; an S12 refusal names
32
+ * only Classes, so its message says what to declare. Anything else is encoded as
33
+ * `terminalFailure` encodes it. Inside a Step, a recipe failure caught from an earlier Step and
34
+ * thrown again fails that Step, as `queryFailure` encodes it.
35
+ */
36
+ export declare function uncaughtFailure(engine: DurableEngine, cause: unknown, definition: object): Error | undefined;
37
+ /**
38
+ * Encode a declared business error of `definition`, a recipe's it re-declares included, or a Step
39
+ * that spent its retry budget, as a terminal engine failure, or return undefined for any other
40
+ * error, which the engine retries.
31
41
  */
32
42
  export declare function terminalFailure(engine: DurableEngine, cause: unknown, definition: object): Error | undefined;
43
+ /**
44
+ * Encode a recipe's failure as the Step's terminal failure, or return undefined for any other
45
+ * error. A read that met data it cannot answer, a query the Host cannot serve, or a recipe S12
46
+ * refuses is not retried. A refused read is a failed attempt as any Kernel refusal: retried,
47
+ * unless the Kernel refused it for good.
48
+ */
49
+ export declare function queryFailure(engine: DurableEngine, cause: unknown): Error | undefined;
33
50
  /**
34
51
  * What a journaled Step failed with, as the Workflow sees it: its declared business error, rebuilt
35
- * through the definition's own factory, or `StepExhausted` once the engine spent its retry budget
36
- * or the Step threw an exhaustion caught from an earlier Step. A replay throws what the live run
37
- * threw.
52
+ * through the definition's own factory, its recipe's `QueryError` or S12 refusal, or
53
+ * `StepExhausted` once the engine spent its retry budget or the Step threw an exhaustion caught
54
+ * from an earlier Step. A replay throws what the live run threw.
38
55
  */
39
56
  export declare function replayedFailure(engine: DurableEngine, cause: unknown, definition: object, step: string): Error | undefined;
@@ -1,8 +1,14 @@
1
1
  import { declaredErrorFactory, declaredErrorOf } from '../../application/error/index.js';
2
+ import { UndeclaredCrossing } from '../../application/query/execution/crossings.js';
3
+ import { isQueryError, QueryError } from '../../application/query/execution/error.js';
2
4
  import { ResponseError } from '../../platform/client/index.js';
3
5
  /** Metadata key the Kernel reads a declared failure from (`backend/restate` outcome decoding). */
4
6
  const FAILURE = 'astrale.failure';
5
- /** Failure code of an Execution whose Workflow did not catch a Step that spent its retry budget. */
7
+ /** Metadata key of a Step's recipe failure, which only the Workflow reads back. */
8
+ const QUERY_FAILURE = 'astrale.query';
9
+ /** The Step each recipe failure the Workflow sees failed: uncaught, it ends the Execution. */
10
+ const queryFailures = new WeakMap();
11
+ /** Failure code of an Execution whose Workflow did not catch a Step that failed for good. */
6
12
  export const STEP_EXHAUSTED = 'STEP_EXHAUSTED';
7
13
  /** The longest delay a Step attempt may ask for, as the Kernel bounds a `retryAfterMs` hint. */
8
14
  const MAXIMUM_RETRY_AFTER_MS = 3_600_000;
@@ -85,22 +91,39 @@ const STATUS = {
85
91
  UNSUPPORTED: 422,
86
92
  };
87
93
  /**
88
- * Encode a declared business error of `definition`, or a Step that spent its retry budget, as a
89
- * terminal engine failure, or return undefined for any other error, which the engine retries.
94
+ * Encode what a Workflow did not catch as the Execution's failure: a Step's recipe failure ends it
95
+ * with `STEP_EXHAUSTED`, naming the recipe and a `QueryError`'s code, never its details, which a
96
+ * read as the executor may fill with what the Execution's reader may not read; an S12 refusal names
97
+ * only Classes, so its message says what to declare. Anything else is encoded as
98
+ * `terminalFailure` encodes it. Inside a Step, a recipe failure caught from an earlier Step and
99
+ * thrown again fails that Step, as `queryFailure` encodes it.
100
+ */
101
+ export function uncaughtFailure(engine, cause, definition) {
102
+ const step = cause instanceof Error ? queryFailures.get(cause) : undefined;
103
+ if (step === undefined)
104
+ return terminalFailure(engine, cause, definition);
105
+ if (cause instanceof UndeclaredCrossing) {
106
+ return stepFailure(engine, `Workflow Step ${step} failed: ${cause.message}`, {
107
+ step,
108
+ query: { recipe: cause.recipe },
109
+ });
110
+ }
111
+ const { code, recipe } = cause;
112
+ return stepFailure(engine, `Workflow Step ${step} failed: ${code} from ${recipe}.`, {
113
+ step,
114
+ query: { code, recipe },
115
+ });
116
+ }
117
+ /**
118
+ * Encode a declared business error of `definition`, a recipe's it re-declares included, or a Step
119
+ * that spent its retry budget, as a terminal engine failure, or return undefined for any other
120
+ * error, which the engine retries.
90
121
  */
91
122
  export function terminalFailure(engine, cause, definition) {
92
123
  if (cause instanceof StepExhausted) {
93
- return new engine.TerminalError(cause.message, {
94
- metadata: {
95
- [FAILURE]: JSON.stringify({
96
- code: STEP_EXHAUSTED,
97
- message: cause.message,
98
- details: {
99
- step: cause.step,
100
- ...(cause.refusal === undefined ? {} : { refusal: cause.refusal }),
101
- },
102
- }),
103
- },
124
+ return stepFailure(engine, cause.message, {
125
+ step: cause.step,
126
+ ...(cause.refusal === undefined ? {} : { refusal: cause.refusal }),
104
127
  });
105
128
  }
106
129
  const declared = declaredErrorOf(cause, definition);
@@ -118,17 +141,54 @@ export function terminalFailure(engine, cause, definition) {
118
141
  },
119
142
  });
120
143
  }
144
+ function stepFailure(engine, message, details) {
145
+ return new engine.TerminalError(message, {
146
+ metadata: { [FAILURE]: JSON.stringify({ code: STEP_EXHAUSTED, message, details }) },
147
+ });
148
+ }
149
+ /**
150
+ * Encode a recipe's failure as the Step's terminal failure, or return undefined for any other
151
+ * error. A read that met data it cannot answer, a query the Host cannot serve, or a recipe S12
152
+ * refuses is not retried. A refused read is a failed attempt as any Kernel refusal: retried,
153
+ * unless the Kernel refused it for good.
154
+ */
155
+ export function queryFailure(engine, cause) {
156
+ let failure;
157
+ if (cause instanceof UndeclaredCrossing)
158
+ failure = { recipe: cause.recipe, message: cause.message };
159
+ else if (isQueryError(cause) && cause.code !== 'REFUSED') {
160
+ const { code, recipe, message, details } = cause;
161
+ failure = { code, recipe, message, details };
162
+ }
163
+ else
164
+ return undefined;
165
+ return new engine.TerminalError(cause.message, {
166
+ metadata: { [QUERY_FAILURE]: JSON.stringify(failure) },
167
+ });
168
+ }
121
169
  /**
122
170
  * What a journaled Step failed with, as the Workflow sees it: its declared business error, rebuilt
123
- * through the definition's own factory, or `StepExhausted` once the engine spent its retry budget
124
- * or the Step threw an exhaustion caught from an earlier Step. A replay throws what the live run
125
- * threw.
171
+ * through the definition's own factory, its recipe's `QueryError` or S12 refusal, or
172
+ * `StepExhausted` once the engine spent its retry budget or the Step threw an exhaustion caught
173
+ * from an earlier Step. A replay throws what the live run threw.
126
174
  */
127
175
  export function replayedFailure(engine, cause, definition, step) {
128
176
  if (!(cause instanceof engine.TerminalError) || cause instanceof engine.CancelledError) {
129
177
  return undefined;
130
178
  }
131
- const encoded = cause.metadata?.[FAILURE];
179
+ const metadata = cause.metadata;
180
+ const query = metadata?.[QUERY_FAILURE];
181
+ if (query !== undefined) {
182
+ const failure = JSON.parse(query);
183
+ // Only a `QueryError` has a code.
184
+ const error = failure.code === undefined
185
+ ? new UndeclaredCrossing(failure.recipe, failure.message)
186
+ : new QueryError(failure.code, failure.recipe, failure.details);
187
+ error.message = failure.message;
188
+ queryFailures.set(error, step);
189
+ return error;
190
+ }
191
+ const encoded = metadata?.[FAILURE];
132
192
  // The Step's own code turns every terminal failure into a declared one or a failed attempt; a
133
193
  // bare one is an engine's budget.
134
194
  if (encoded === undefined)
@@ -1,4 +1,5 @@
1
1
  import type { IntegrationClientFactory, Integrations } from '../../application/integration/index.js';
2
+ import type { DeclaredClass } from '../../application/query/execution/crossings.js';
2
3
  import type { RuntimeWorkflow } from '../../application/runtime/workflows.js';
3
4
  import type { Domain } from '../../platform/schema/index.js';
4
5
  import type { Identity } from '../identity/index.js';
@@ -17,6 +18,8 @@ export interface DurableReceiver {
17
18
  export declare function createDurableReceiver(input: {
18
19
  readonly workflows: readonly RuntimeWorkflow[];
19
20
  readonly domain: Domain;
21
+ /** The Class requirements the Domain's build declares, which a Step's recipe reads are checked against. */
22
+ readonly declared?: readonly DeclaredClass[];
20
23
  readonly identity: Identity;
21
24
  readonly serving: AdmittedDurableServing;
22
25
  /** Integration clients of the initialized Runtime, which every Step holds. */
@@ -19,6 +19,7 @@ export function createDurableReceiver(input) {
19
19
  const steps = sessionSteps({
20
20
  executor: executor.bind(input.identity),
21
21
  domain: input.domain,
22
+ declared: input.declared ?? [],
22
23
  integrations: input.integrations,
23
24
  });
24
25
  const declared = new Map(input.workflows
@@ -1,10 +1,10 @@
1
1
  import { declaredErrorFactory } from '../../application/error/index.js';
2
2
  import { acceptStepId } from '../../application/workflow/step/index.js';
3
3
  import { acceptStepOutput } from '../../application/workflow/step/output.js';
4
- import { validateOutput } from '../invocation/result/index.js';
4
+ import { reportUndeclaredRecipeError, validateOutput } from '../invocation/result/index.js';
5
5
  import { BACKOFF, UNAVAILABLE, failedAttemptError, failedAttemptOf, nextAttempt, } from './attempts.js';
6
6
  import { decodeEnvelope } from './envelope.js';
7
- import { replayedFailure, StepExhausted, StepRetryAfter, terminalFailure } from './failure.js';
7
+ import { queryFailure, replayedFailure, StepExhausted, StepRetryAfter, terminalFailure, uncaughtFailure, } from './failure.js';
8
8
  import { stepServing } from './options.js';
9
9
  import { keySequence } from './steps.js';
10
10
  const MAXIMUM_SLEEP_MS = 365 * 24 * 60 * 60_000;
@@ -43,7 +43,7 @@ async function run(input, context, raw) {
43
43
  output = await definition.run(durable);
44
44
  }
45
45
  catch (cause) {
46
- throw terminalFailure(engine, cause, definition) ?? cause;
46
+ throw uncaughtFailure(engine, cause, definition) ?? cause;
47
47
  }
48
48
  return validateOutput(workflow.callable, output);
49
49
  }
@@ -130,8 +130,12 @@ function durableContext(input, context, envelope) {
130
130
  }
131
131
  }
132
132
  catch (cause) {
133
- throw (terminalFailure(engine, cause, definition) ??
134
- failedAttemptError(engine, cause, startedAt, now(), step?.repeatsEffects() ?? false));
133
+ const terminal = terminalFailure(engine, cause, definition) ?? queryFailure(engine, cause);
134
+ if (terminal !== undefined)
135
+ throw terminal;
136
+ // Retried as any failed attempt, and logged: the Workflow does not re-declare it.
137
+ reportUndeclaredRecipeError(cause, workflow.address);
138
+ throw failedAttemptError(engine, cause, startedAt, now(), step?.repeatsEffects() ?? false);
135
139
  }
136
140
  finally {
137
141
  clearTimeout(timer);
@@ -206,8 +210,8 @@ function durableContext(input, context, envelope) {
206
210
  }
207
211
  const returned = declare(Object.freeze({
208
212
  run: (id, execute) => declaration(id, execute),
209
- query: (id, query, value) => declaration(id, (authority) => authority.query(query, value)),
210
- mutate: (id, mutation, value) => declaration(id, (authority) => authority.mutate(mutation, value)),
213
+ query: (id, query, value, options) => declaration(id, (authority) => authority.query(query, value, options)),
214
+ mutate: (id, mutation, value, options) => declaration(id, (authority) => authority.mutate(mutation, value, options)),
211
215
  }));
212
216
  if (!Array.isArray(returned) ||
213
217
  returned.length !== declared.size ||
@@ -285,8 +289,8 @@ function durableContext(input, context, envelope) {
285
289
  error: declaredErrorFactory(definition),
286
290
  step: Object.freeze({
287
291
  run: step,
288
- query: (id, query, value) => step(id, (authority) => authority.query(query, value)),
289
- mutate: (id, mutation, value) => step(id, (authority) => authority.mutate(mutation, value)),
292
+ query: (id, query, value, options) => step(id, (authority) => authority.query(query, value, options)),
293
+ mutate: (id, mutation, value, options) => step(id, (authority) => authority.mutate(mutation, value, options)),
290
294
  parallel,
291
295
  }),
292
296
  async sleep(durationMs) {
@@ -1,4 +1,5 @@
1
1
  import type { IntegrationClientFactory, Integrations } from '../../application/integration/index.js';
2
+ import type { DeclaredClass } from '../../application/query/execution/crossings.js';
2
3
  import type { DurableExecution, DurableStepAuthority } from '../../application/workflow/index.js';
3
4
  import type { BoundClientSession } from '../../platform/client/session/index.js';
4
5
  import type { Domain } from '../../platform/schema/index.js';
@@ -29,6 +30,8 @@ export type StepAuthorities = (attempt: StepAttempt) => StepAuthorityBinding;
29
30
  export declare function sessionSteps(input: {
30
31
  readonly executor: Executor;
31
32
  readonly domain: Domain;
33
+ /** The Class requirements the Domain's build declares: a recipe's reads are checked against them. */
34
+ readonly declared: readonly DeclaredClass[];
32
35
  readonly integrations: IntegrationClientFactory<Integrations>;
33
36
  }): StepAuthorities;
34
37
  /**
@@ -8,7 +8,7 @@ import { stepCalls } from './integrations.js';
8
8
  * an Action over the keyed Session, and the Runtime's Integration clients over the same keys.
9
9
  */
10
10
  export function sessionSteps(input) {
11
- const { executor, domain, integrations } = input;
11
+ const { executor, domain, declared, integrations } = input;
12
12
  return ({ execution, next, lifetime }) => {
13
13
  const session = executor(execution.kernel, execution.id, lifetime);
14
14
  try {
@@ -19,7 +19,7 @@ export function sessionSteps(input) {
19
19
  });
20
20
  const auth = bindIntegrationAuthentication(lifetime, bound);
21
21
  const authority = Object.freeze({
22
- ...bindCapabilities(domain, { self }),
22
+ ...bindCapabilities(domain, { self }, declared),
23
23
  integrations: integrations(stepCalls({ next, lifetime, auth })),
24
24
  });
25
25
  return Object.freeze({
@@ -0,0 +1,2 @@
1
+ /** Generated from the Kernel Schema of @astrale-os/kernel-core 1.0.0-beta.24, reduced to its Classes. Regenerate with pnpm sync:kernel-schema. */
2
+ export declare const kernelCompiledSchema: string;