@aventara/core 1.0.0-rc.1 → 1.0.0-rc.10

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 (228) hide show
  1. package/CHANGELOG.md +943 -16
  2. package/ERRORS.md +142 -0
  3. package/README.md +274 -16
  4. package/dist/adapters/adapter-discovery-diagnostic.guidance.d.ts +6 -0
  5. package/dist/adapters/adapter-discovery-diagnostic.guidance.js +7 -0
  6. package/dist/adapters/adapter-field.d.ts +22 -0
  7. package/dist/adapters/adapter-identifier.d.ts +9 -0
  8. package/dist/adapters/adapter-identifier.js +6 -1
  9. package/dist/adapters/adapter-model.d.ts +9 -0
  10. package/dist/adapters/adapter-operation.d.ts +18 -3
  11. package/dist/adapters/adapter-resource.d.ts +5 -0
  12. package/dist/adapters/adapter.interface.d.ts +10 -0
  13. package/dist/avz/avz.d.ts +1 -1
  14. package/dist/avz/json-shape.registry.d.ts +2 -1
  15. package/dist/compiler/contract-compiler-diagnostic.guidance.d.ts +6 -0
  16. package/dist/compiler/contract-compiler-diagnostic.guidance.js +97 -0
  17. package/dist/compiler/contract.compiler.d.ts +6 -0
  18. package/dist/compiler/contract.compiler.js +227 -24
  19. package/dist/compiler/managed-elsewhere.projector.d.ts +52 -0
  20. package/dist/compiler/managed-elsewhere.projector.js +179 -0
  21. package/dist/compiler/managed-elsewhere.validator.d.ts +9 -0
  22. package/dist/compiler/managed-elsewhere.validator.js +74 -0
  23. package/dist/config/computed-fields.d.ts +62 -0
  24. package/dist/config/computed-fields.js +73 -0
  25. package/dist/config/config-diagnostic.guidance.d.ts +6 -0
  26. package/dist/config/config-diagnostic.guidance.js +32 -0
  27. package/dist/config/config.resolver.d.ts +24 -0
  28. package/dist/config/config.resolver.js +65 -0
  29. package/dist/config/config.validator.js +222 -8
  30. package/dist/config/define-resource.d.ts +1 -5
  31. package/dist/config/entrypoint.normalizer.d.ts +3 -2
  32. package/dist/config/exact-framework-config.d.ts +67 -22
  33. package/dist/config/field-compute.resolver.d.ts +2 -0
  34. package/dist/config/field-compute.resolver.js +8 -0
  35. package/dist/config/framework-config.d.ts +53 -15
  36. package/dist/config/framework-resources-config.d.ts +25 -14
  37. package/dist/config/pipeline-config.d.ts +4 -4
  38. package/dist/config/pipeline-tree.resolver.d.ts +2 -2
  39. package/dist/contracts/access-route.rules.d.ts +10 -0
  40. package/dist/contracts/access-route.rules.js +45 -0
  41. package/dist/contracts/capability.d.ts +26 -1
  42. package/dist/contracts/capability.js +20 -0
  43. package/dist/contracts/client-contract-structure.validator.d.ts +301 -89
  44. package/dist/contracts/client-contract-structure.validator.js +37 -2
  45. package/dist/contracts/contract-access.d.ts +29 -0
  46. package/dist/contracts/contract-access.js +1 -0
  47. package/dist/contracts/contract-canonicalizer.d.ts +9 -1
  48. package/dist/contracts/contract-canonicalizer.js +30 -4
  49. package/dist/contracts/contract-hash.d.ts +0 -1
  50. package/dist/contracts/contract-hash.js +1 -1
  51. package/dist/contracts/contract.d.ts +27 -1
  52. package/dist/contracts/field.d.ts +58 -1
  53. package/dist/contracts/json-schema.projector.d.ts +11 -0
  54. package/dist/contracts/json-schema.projector.js +78 -0
  55. package/dist/contracts/scalar-value-type.d.ts +3 -1
  56. package/dist/framework/access-facade.d.ts +116 -0
  57. package/dist/framework/access-facade.js +120 -0
  58. package/dist/framework/contract-view.d.ts +120 -16
  59. package/dist/framework/framework-construction.error.d.ts +14 -4
  60. package/dist/framework/framework-construction.error.js +18 -2
  61. package/dist/framework/framework.d.ts +26 -5
  62. package/dist/framework/framework.factory.d.ts +1 -1
  63. package/dist/framework/framework.factory.js +115 -23
  64. package/dist/framework/operation-facade.d.ts +80 -13
  65. package/dist/framework/operation-facade.js +2 -1
  66. package/dist/index.d.ts +17 -5
  67. package/dist/index.js +1 -0
  68. package/dist/internal.d.ts +7 -2
  69. package/dist/internal.js +6 -0
  70. package/dist/operations/database-refusal.d.ts +51 -0
  71. package/dist/operations/database-refusal.js +45 -0
  72. package/dist/operations/operation-arguments.d.ts +148 -60
  73. package/dist/operations/operation-call.d.ts +9 -5
  74. package/dist/operations/operation-result.d.ts +6 -4
  75. package/dist/operations/operation-validator-core.js +159 -36
  76. package/dist/operations/operation-validator.d.ts +1 -1
  77. package/dist/operations/structural-limits.walker.d.ts +1 -1
  78. package/dist/operations/validation-code.guidance.d.ts +6 -0
  79. package/dist/operations/validation-code.guidance.js +90 -0
  80. package/dist/operations/write-scope.resolver.d.ts +4 -0
  81. package/dist/operations/write-scope.resolver.js +2 -0
  82. package/dist/policy/access-provider.interface.d.ts +91 -0
  83. package/dist/policy/access-provider.interface.js +1 -0
  84. package/dist/policy/access-provider.registry.d.ts +17 -0
  85. package/dist/policy/access-provider.registry.js +15 -0
  86. package/dist/policy/access-question.d.ts +20 -0
  87. package/dist/policy/access-question.js +1 -0
  88. package/dist/policy/access-question.registry.d.ts +5 -0
  89. package/dist/policy/access-question.registry.js +19 -0
  90. package/dist/policy/access-question.runtime.d.ts +36 -0
  91. package/dist/policy/access-question.runtime.js +297 -0
  92. package/dist/policy/access-verb.table.d.ts +56 -0
  93. package/dist/policy/access-verb.table.js +21 -0
  94. package/dist/policy/access-verbs.d.ts +46 -0
  95. package/dist/policy/access-verbs.js +1 -0
  96. package/dist/policy/policy-admission.d.ts +20 -0
  97. package/dist/policy/policy-admission.js +409 -0
  98. package/dist/policy/policy-after-update.runtime.d.ts +79 -0
  99. package/dist/policy/policy-after-update.runtime.js +208 -0
  100. package/dist/policy/policy-condition.d.ts +15 -0
  101. package/dist/policy/policy-condition.js +36 -0
  102. package/dist/policy/policy-engine.d.ts +205 -0
  103. package/dist/policy/policy-engine.js +1 -0
  104. package/dist/policy/policy-named-rows.d.ts +18 -0
  105. package/dist/policy/policy-named-rows.js +51 -0
  106. package/dist/policy/policy-nested-write.runtime.d.ts +44 -0
  107. package/dist/policy/policy-nested-write.runtime.js +545 -0
  108. package/dist/policy/policy-read.runtime.d.ts +81 -0
  109. package/dist/policy/policy-read.runtime.js +503 -0
  110. package/dist/policy/policy-reference-write.runtime.d.ts +51 -0
  111. package/dist/policy/policy-reference-write.runtime.js +345 -0
  112. package/dist/policy/policy-request.d.ts +41 -0
  113. package/dist/policy/policy-request.js +63 -0
  114. package/dist/policy/policy-session.d.ts +106 -0
  115. package/dist/policy/policy-session.js +295 -0
  116. package/dist/policy/policy-startup.validator.d.ts +10 -0
  117. package/dist/policy/policy-startup.validator.js +112 -0
  118. package/dist/policy/policy-write.runtime.d.ts +39 -0
  119. package/dist/policy/policy-write.runtime.js +532 -0
  120. package/dist/prebuilt/core-version.generated.d.ts +2 -0
  121. package/dist/prebuilt/core-version.generated.js +1 -0
  122. package/dist/prebuilt/prebuilt-changes.d.ts +29 -0
  123. package/dist/prebuilt/prebuilt-changes.js +65 -0
  124. package/dist/prebuilt/prebuilt-contracts.d.ts +40 -0
  125. package/dist/prebuilt/prebuilt-contracts.emitter.d.ts +16 -0
  126. package/dist/prebuilt/prebuilt-contracts.emitter.js +50 -0
  127. package/dist/prebuilt/prebuilt-contracts.js +1 -0
  128. package/dist/prebuilt/prebuilt-contracts.loader.d.ts +19 -0
  129. package/dist/prebuilt/prebuilt-contracts.loader.js +77 -0
  130. package/dist/prebuilt/prebuilt-inputs.fingerprint.d.ts +16 -0
  131. package/dist/prebuilt/prebuilt-inputs.fingerprint.js +229 -0
  132. package/dist/protocol/absent-route.responder.d.ts +9 -27
  133. package/dist/protocol/absent-route.responder.js +36 -3
  134. package/dist/protocol/contract-document.responder.d.ts +2 -1
  135. package/dist/protocol/http-request.decoder.d.ts +19 -3
  136. package/dist/protocol/http-request.decoder.js +24 -1
  137. package/dist/protocol/http-request.reader.d.ts +6 -3
  138. package/dist/protocol/http-request.reader.js +1 -0
  139. package/dist/protocol/http-response.encoder.js +2 -2
  140. package/dist/protocol/protocol-headers.d.ts +3 -3
  141. package/dist/protocol/protocol-surface.d.ts +6 -1
  142. package/dist/protocol/protocol-surface.js +7 -0
  143. package/dist/protocol/protocol.binder.d.ts +16 -1
  144. package/dist/protocol/protocol.binder.js +4 -1
  145. package/dist/protocol/protocol.handler.d.ts +12 -1
  146. package/dist/protocol/protocol.handler.js +86 -17
  147. package/dist/runtime/caller-data.copier.d.ts +18 -3
  148. package/dist/runtime/caller-data.copier.js +21 -8
  149. package/dist/runtime/caller-data.door.d.ts +13 -6
  150. package/dist/runtime/computed-read-runtime.d.ts +6 -1
  151. package/dist/runtime/computed-read-runtime.js +232 -45
  152. package/dist/runtime/computed-value.error.d.ts +3 -2
  153. package/dist/runtime/computed-value.error.js +3 -2
  154. package/dist/runtime/context-executor.runtime.d.ts +4 -3
  155. package/dist/runtime/context-executor.runtime.js +4 -2
  156. package/dist/runtime/core-class.brand.d.ts +10 -0
  157. package/dist/runtime/core-class.brand.js +21 -0
  158. package/dist/runtime/create-requirement.d.ts +31 -5
  159. package/dist/runtime/create-requirement.js +129 -21
  160. package/dist/runtime/decimal.d.ts +14 -0
  161. package/dist/runtime/decimal.js +21 -0
  162. package/dist/runtime/diagnostics-reporter.d.ts +44 -9
  163. package/dist/runtime/diagnostics-reporter.js +13 -1
  164. package/dist/runtime/error-boundary.d.ts +9 -2
  165. package/dist/runtime/error-boundary.js +12 -0
  166. package/dist/runtime/error-guidance.d.ts +12 -0
  167. package/dist/runtime/error-guidance.js +1 -0
  168. package/dist/runtime/error.catalog.d.ts +49 -0
  169. package/dist/runtime/error.catalog.js +49 -0
  170. package/dist/runtime/execution-options.d.ts +8 -0
  171. package/dist/runtime/field-check.evaluator.d.ts +0 -2
  172. package/dist/runtime/field-check.evaluator.js +1 -1
  173. package/dist/runtime/field-compute.d.ts +11 -10
  174. package/dist/runtime/field-stage.runtime.d.ts +3 -1
  175. package/dist/runtime/field-stage.runtime.js +8 -4
  176. package/dist/runtime/field-validator.runtime.d.ts +19 -1
  177. package/dist/runtime/field-validator.runtime.js +47 -8
  178. package/dist/runtime/framework-error.js +9 -0
  179. package/dist/runtime/framework-warning.emitter.d.ts +6 -0
  180. package/dist/runtime/framework-warning.emitter.js +8 -0
  181. package/dist/runtime/json-value.d.ts +10 -5
  182. package/dist/runtime/level-lifecycle.runtime.d.ts +4 -3
  183. package/dist/runtime/level-lifecycle.runtime.js +3 -5
  184. package/dist/runtime/mutation-planner.d.ts +1 -6
  185. package/dist/runtime/mutation-planner.js +3 -14
  186. package/dist/runtime/operation-code.guidance.d.ts +6 -0
  187. package/dist/runtime/operation-code.guidance.js +167 -0
  188. package/dist/runtime/operation-request.d.ts +16 -9
  189. package/dist/runtime/operation-runtime.d.ts +35 -17
  190. package/dist/runtime/operation-runtime.js +220 -49
  191. package/dist/runtime/outcome-mapper.d.ts +2 -1
  192. package/dist/runtime/output-validator.d.ts +1 -1
  193. package/dist/runtime/owned-execution.registry.d.ts +13 -3
  194. package/dist/runtime/pipe-output.validator.d.ts +10 -0
  195. package/dist/runtime/pipe-output.validator.js +4 -2
  196. package/dist/runtime/pipeline.d.ts +47 -22
  197. package/dist/runtime/readonly-value.d.ts +20 -5
  198. package/dist/runtime/readonly-value.js +74 -26
  199. package/dist/runtime/referential-action.d.ts +1 -1
  200. package/dist/runtime/scalar-runtime.d.ts +4 -11
  201. package/dist/runtime/scalar-runtime.js +91 -22
  202. package/dist/runtime/unsent-value.normalizer.d.ts +15 -0
  203. package/dist/runtime/unsent-value.normalizer.js +128 -0
  204. package/dist/transactions/operation-arguments-encoder.js +8 -3
  205. package/dist/transactions/operation-fingerprint.js +2 -2
  206. package/dist/transactions/sql-statement.d.ts +10 -2
  207. package/dist/transactions/sql-statement.validator.d.ts +2 -2
  208. package/dist/transactions/sql-statement.validator.js +38 -5
  209. package/dist/transactions/transaction-envelope.d.ts +5 -4
  210. package/dist/transactions/transaction-integrity-error.js +2 -0
  211. package/dist/transactions/transaction-plan-assembler.d.ts +12 -5
  212. package/dist/transactions/transaction-plan-assembler.js +48 -10
  213. package/dist/transactions/transaction-plan-validator.d.ts +23 -7
  214. package/dist/transactions/transaction-plan-validator.js +27 -1
  215. package/dist/transactions/transaction-reference-resolver.d.ts +3 -2
  216. package/dist/transactions/transaction-reference-validator.d.ts +43 -3
  217. package/dist/transactions/transaction-reference-validator.js +83 -57
  218. package/dist/transactions/transaction-reference.d.ts +1 -1
  219. package/dist/transactions/transaction-reference.js +5 -0
  220. package/dist/transactions/transaction-request.d.ts +8 -8
  221. package/dist/transactions/transaction-runtime.d.ts +5 -2
  222. package/dist/transactions/transaction-runtime.js +79 -27
  223. package/dist/transactions/transaction-settlement.runtime.d.ts +4 -3
  224. package/dist/transactions/transaction-slot-path-error.js +2 -0
  225. package/dist/transactions/transaction-stage.runtime.d.ts +5 -3
  226. package/dist/transactions/transaction-stage.runtime.js +7 -4
  227. package/package.json +6 -5
  228. package/src/runtime/field-check.evaluator.ts +1 -1
@@ -7,14 +7,15 @@ import type { ResolvedFrameworkConfig } from "../config/config.resolver.js";
7
7
  import type { AvRequestOrigin, RemoteRequestOrigin } from "../config/config-layer.js";
8
8
  import type { AvContract } from "../contracts/contract.js";
9
9
  import type { OperationValidationOptions, SemanticOperationArguments } from "../operations/operation-validator.js";
10
- import type { FrameworkTransactionRequest } from "../transactions/transaction-request.js";
10
+ import { type PolicyCaller } from "../policy/policy-request.js";
11
+ import type { AvTransactionRequest } from "../transactions/transaction-request.js";
11
12
  import { type ArgumentsSource } from "./caller-data.door.js";
12
13
  import { type ContextExecutor, type ExecutorScope } from "./context-executor.runtime.js";
13
14
  import { type RecordWriteFacts } from "./create-requirement.js";
14
15
  import { type DiagnosticsReporter } from "./diagnostics-reporter.js";
15
16
  import { type OuterFailureLayer } from "./error-boundary.js";
16
17
  import { type FieldStagePlan } from "./field-stage.plan.js";
17
- import type { ClientProtocolIdentity, FrameworkOperationRequest, StatefulOperationRequest } from "./operation-request.js";
18
+ import type { AvOperationRequest, AvRequestProtocol, StatefulOperationRequest } from "./operation-request.js";
18
19
  import type { AvOperationFailureResponse, AvOperationResponse } from "./operation-response.js";
19
20
  import type { AvState } from "./request-state.js";
20
21
  import { type NormalizationWrite } from "./scalar-runtime.js";
@@ -45,7 +46,7 @@ export type OperationPipelineDependencies<M extends AvAdapterModel> = Omit<Opera
45
46
  * Where one operation's Adapter call runs: standalone, through the Adapter, or
46
47
  * inside an open transaction, through its executor.
47
48
  */
48
- export type OperationBinding<M extends AvAdapterModel> = {
49
+ type OperationBinding<M extends AvAdapterModel> = {
49
50
  readonly kind: "standalone";
50
51
  readonly executor: AvAdapterOperationExecutor<M>;
51
52
  } | {
@@ -79,13 +80,15 @@ export declare function createPipelineDependencies<M extends AvAdapterModel>(dep
79
80
  * request's arguments are the caller's own objects, copied at the door, or data
80
81
  * no caller holds (see {@link ArgumentsSource}).
81
82
  */
82
- export type FrameworkOperationExecutor = (request: FrameworkOperationRequest, report: DiagnosticsReporter, source: ArgumentsSource) => Promise<AvOperationResponse>;
83
+ export type FrameworkOperationExecutor = (request: AvOperationRequest, report: DiagnosticsReporter, source: ArgumentsSource,
84
+ /** The principal an application call runs as (`{ as }`), when it names one. */
85
+ caller?: PolicyCaller) => Promise<AvOperationResponse>;
83
86
  /** Selects the Contract of the request's origin. */
84
- export declare function activeContract(contracts: AvContracts, request: FrameworkOperationRequest | FrameworkTransactionRequest): AvContract;
87
+ export declare function activeContract(contracts: AvContracts, request: AvOperationRequest | AvTransactionRequest): AvContract;
85
88
  /** Creates the transport-independent operation executor owned by core. */
86
89
  export declare function createOperationRuntime<M extends AvAdapterModel>(dependencies: OperationRuntimeDependencies<M>, pipelineDependencies: OperationPipelineDependencies<M>): FrameworkOperationExecutor;
87
90
  /** Validates the request-level protocol identity. */
88
- export declare function validateProtocolIdentity(contracts: AvContracts, request: FrameworkOperationRequest | FrameworkTransactionRequest): AvOperationFailureResponse | undefined;
91
+ export declare function validateProtocolIdentity(contracts: AvContracts, request: AvOperationRequest | AvTransactionRequest): AvOperationFailureResponse | undefined;
89
92
  /**
90
93
  * The stale-client check on one remote protocol identity: the protocol version first
91
94
  * (`A2006`), then the hash of the origin's Contract (`A2005`): the ClientContract's
@@ -94,8 +97,8 @@ export declare function validateProtocolIdentity(contracts: AvContracts, request
94
97
  * (`@aventara/core/protocol`) call it too, so a stale client hears the same envelope
95
98
  * whichever layer answers.
96
99
  */
97
- export declare function protocolIdentityFailure(contracts: AvContracts, protocol: ClientProtocolIdentity, origin: RemoteRequestOrigin): AvOperationFailureResponse | undefined;
98
- export type ValidatedOperationArguments = {
100
+ export declare function protocolIdentityFailure(contracts: AvContracts, protocol: AvRequestProtocol, origin: RemoteRequestOrigin): AvOperationFailureResponse | undefined;
101
+ type ValidatedOperationArguments = {
99
102
  readonly ok: true;
100
103
  readonly arguments: SemanticOperationArguments;
101
104
  } | {
@@ -103,8 +106,14 @@ export type ValidatedOperationArguments = {
103
106
  readonly response: AvOperationFailureResponse;
104
107
  };
105
108
  /** Validates one operation's arguments through the Framework Validation Layer. */
106
- export declare function validateOperationRequest(contract: AvContract, request: FrameworkOperationRequest, options?: OperationValidationOptions, write?: NormalizationWrite): ValidatedOperationArguments;
107
- /** Every sent field's path: a single call's arguments hold no `$ref`. */
109
+ export declare function validateOperationRequest(contract: AvContract, request: AvOperationRequest, options?: OperationValidationOptions, write?: NormalizationWrite): ValidatedOperationArguments;
110
+ /** The subject a refused output of an operation's pipes is reported under at a plan step. */
111
+ export declare const STEP_PIPES = "Pipes";
112
+ /**
113
+ * Every sent field's path. A `$ref` is an object of `$`-keys, which no field
114
+ * pipe or validator takes, so a plan step's literal values before BEGIN are
115
+ * every field too, wherever a pipe left a reference or a literal.
116
+ */
108
117
  export declare const EVERY_FIELD: () => boolean;
109
118
  /**
110
119
  * What admission leaves: the deep-frozen arguments every later stage reads, and
@@ -120,23 +129,31 @@ export type AdmittedOperation = {
120
129
  readonly response: AvOperationFailureResponse;
121
130
  };
122
131
  /** Which sent values an operation's field stages and validators take, and how its pipe output is checked. */
123
- export type AdmissionScope = {
132
+ type AdmissionScope = {
124
133
  /**
125
134
  * The sent values the field pipes and validators take: every one for a single
126
- * call, a plan step's literal values before BEGIN, its resolved `$ref` values
127
- * at the step.
135
+ * call and for a plan step before BEGIN (an unresolved `$ref` is an object of
136
+ * `$`-keys, which they never take), its resolved `$ref` values at the step.
128
137
  */
129
138
  readonly select: (path: readonly (string | number)[]) => boolean;
130
139
  /** Before BEGIN a plan step's `$ref` slots are unresolved: these admit them. */
131
140
  readonly validation?: OperationValidationOptions;
141
+ /**
142
+ * A plan step or a forced call, admitted before BEGIN: the validators judge
143
+ * there the sent values no later stage can change (a field with no write
144
+ * compute stage of its record's phase), so a caller's refusal opens no
145
+ * transaction. Everything is judged again after write compute.
146
+ */
147
+ readonly beforeBegin?: boolean;
132
148
  };
133
149
  /**
134
- * Runs an operation's admission — its guards, pipes and validators — and answers
135
- * the deep-frozen arguments the rest of the operation reads, or the refusal.
150
+ * Runs an operation's admission — its guards and pipes, and before BEGIN the
151
+ * validators of the values nothing after it changes — and answers the
152
+ * deep-frozen arguments the rest of the operation reads, or the refusal.
136
153
  */
137
154
  export declare function admitOperation<M extends AvAdapterModel>(dependencies: OperationPipelineDependencies<M>, request: StatefulOperationRequest, contract: AvContract, args: unknown, argumentsPath: readonly (string | number)[], report: DiagnosticsReporter, scope: ExecutorScope<M>, admission?: AdmissionScope): Promise<AdmittedOperation>;
138
155
  /** How a plan step's arguments were changed between their admission and the step. */
139
- export type StepChanges = {
156
+ type StepChanges = {
140
157
  /** The sent `$ref` values written at this step: their field stages run now. */
141
158
  readonly written: (path: readonly (string | number)[]) => boolean;
142
159
  /** A transaction pipe changed the step: every value is judged again. */
@@ -146,7 +163,7 @@ export type StepChanges = {
146
163
  };
147
164
  /**
148
165
  * A plan step's (or a forced call's) arguments at the step: resolved values
149
- * through their field stages, and re-checked when a stage changed them.
166
+ * through their field pipes, and re-checked when a stage changed them.
150
167
  */
151
168
  export declare function prepareStep<M extends AvAdapterModel>(dependencies: OperationPipelineDependencies<M>, request: StatefulOperationRequest, contract: AvContract, args: unknown, argumentsPath: readonly (string | number)[], report: DiagnosticsReporter, executor: AvAdapterTransactionExecutor<M>, changes: StepChanges, outer: OuterFailureLayer): Promise<AdmittedOperation>;
152
169
  /**
@@ -155,3 +172,4 @@ export declare function prepareStep<M extends AvAdapterModel>(dependencies: Oper
155
172
  * failures never reach this function, so developer filters never see them.
156
173
  */
157
174
  export declare function executeAdmittedOperation<M extends AvAdapterModel>(dependencies: OperationPipelineDependencies<M>, request: StatefulOperationRequest, contract: AvContract, admittedArguments: unknown, argumentsPath: readonly (string | number)[], binding: OperationBinding<M>, report: DiagnosticsReporter): Promise<AvOperationResponse>;
175
+ export {};
@@ -1,19 +1,24 @@
1
1
  import { hasFieldValidators } from "../compiler/field-validator.compiler.js";
2
+ import { createComputedFields } from "../config/field-compute.resolver.js";
2
3
  import { fieldStagesOf, isForcedOperation, nestedTargetLevels, operationLevels, rawPipelineTree, transactionLevelsOf, } from "../config/pipeline-tree.resolver.js";
3
4
  import { AVENTARA_PROTOCOL_VERSION } from "../contracts/contract-protocol.js";
4
5
  import { findOperationAvailabilityIssue, validateOperationArguments, } from "../operations/operation-validator.js";
6
+ import { enforceReadPolicy, } from "../policy/policy-read.runtime.js";
7
+ import { admitRequestPolicy, openRequestPolicy, } from "../policy/policy-request.js";
8
+ import { enforceWritePolicy, writeNeedsTransaction, } from "../policy/policy-write.runtime.js";
5
9
  import { transactionInfrastructureFailure } from "../transactions/transaction-response.js";
6
10
  import { settleTransaction } from "../transactions/transaction-settlement.runtime.js";
7
11
  import { TRANSACTION_PIPES, transactionFacts, } from "../transactions/transaction-stage.runtime.js";
8
12
  import { copyAtDoor, misuseIdentityOf, refuseCallerData, } from "./caller-data.door.js";
9
13
  import { materializeReadOperation, planReadOperation, } from "./computed-read-runtime.js";
14
+ import { AvComputedValueError } from "./computed-value.error.js";
10
15
  import { createContextExecutor, } from "./context-executor.runtime.js";
11
- import { createRequirementIssues, recordWriteFactsOf, } from "./create-requirement.js";
16
+ import { computedRequirementGapsOf, createRequirementIssues, recordWriteFactsOf, } from "./create-requirement.js";
12
17
  import { createDiagnosticsReporter, } from "./diagnostics-reporter.js";
13
18
  import { AdapterBoundary, OPERATION_ARGUMENTS_PATH, resolveOperationFailure, sanitizeOperationFailure, } from "./error-boundary.js";
14
19
  import { planFieldStages } from "./field-stage.plan.js";
15
20
  import { guardSentFields, pipeSentFields, valueAt, writeRecordPathsOf, } from "./field-stage.runtime.js";
16
- import { fieldValidatorIssues } from "./field-validator.runtime.js";
21
+ import { fieldValidatorIssues, hiddenFieldRefusal, } from "./field-validator.runtime.js";
17
22
  import { thrownFailure } from "./framework-error.factory.js";
18
23
  import { AvInterceptorNextError } from "./interceptor-next.error.js";
19
24
  import { runLevelLifecycle, } from "./level-lifecycle.runtime.js";
@@ -23,10 +28,11 @@ import { nestedWriteTargetsOf, } from "./nested-write.walker.js";
23
28
  import { internalFailure, operationFailure } from "./operation-response.js";
24
29
  import { mapOperationOutcome, mapValidationOutcome, uniqueMissFailure, } from "./outcome-mapper.js";
25
30
  import { AvOutputValidationError, validateOperationOutput, } from "./output-validator.js";
26
- import { refusePipeOutput, refuseStageOutput, } from "./pipe-output.validator.js";
31
+ import { AvPipeOutputError, PIPE_OUTPUT_FAILURE_MESSAGE, refusePipeOutput, refuseStageOutput, } from "./pipe-output.validator.js";
27
32
  import { deepFreeze, frozenCopy } from "./readonly-value.js";
28
33
  import { requestStateOf } from "./request-state.resolver.js";
29
34
  import { normalizeOperationScalarValues, } from "./scalar-runtime.js";
35
+ import { withoutUnsentWriteValues } from "./unsent-value.normalizer.js";
30
36
  function scopeOf(request, binding) {
31
37
  return {
32
38
  requestId: request.requestId,
@@ -37,9 +43,30 @@ function scopeOf(request, binding) {
37
43
  export function withRequestState(request) {
38
44
  return { ...request, state: requestStateOf(request.state) };
39
45
  }
46
+ function withRequestPolicy(dependencies, request, caller, report) {
47
+ const failed = (error) => {
48
+ report(error, "A3000");
49
+ return internalFailure();
50
+ };
51
+ const withPolicy = (policy) => policy === undefined ? request : { ...request, policy };
52
+ try {
53
+ const policy = openRequestPolicy(dependencies.config.policy, dependencies.contracts.core, request, caller, dependencies.adapter);
54
+ return policy instanceof Promise
55
+ ? policy.then(withPolicy, failed)
56
+ : withPolicy(policy);
57
+ }
58
+ catch (error) {
59
+ return failed(error);
60
+ }
61
+ }
40
62
  export function createPipelineDependencies(dependencies, model) {
41
63
  const misuse = createMisuseReporter(dependencies.config.misuse);
42
- const recordWrites = recordWriteFactsOf(dependencies.adapter);
64
+ const recordWrites = recordWriteFactsOf({
65
+ ...(dependencies.adapter.referentialActions === undefined
66
+ ? {}
67
+ : { referentialActions: dependencies.adapter.referentialActions }),
68
+ model,
69
+ });
43
70
  const contexts = createContextExecutor({
44
71
  model,
45
72
  adapter: dependencies.adapter,
@@ -121,7 +148,7 @@ function operationFacts(contract, request, args) {
121
148
  family: request.family,
122
149
  variant: request.variant,
123
150
  },
124
- $args: args,
151
+ $args: frozenCopy(args),
125
152
  $origin: request.origin,
126
153
  $requestId: request.requestId,
127
154
  $contract: contract,
@@ -162,7 +189,7 @@ function outputAccepted(contract, request, projection, data, report) {
162
189
  }
163
190
  export function createOperationRuntime(dependencies, pipelineDependencies) {
164
191
  const misuse = createMisuseReporter(dependencies.config.misuse);
165
- return async (request, report, source) => {
192
+ return async (request, report, source, caller) => {
166
193
  let validated;
167
194
  try {
168
195
  validated = validateOperation(dependencies, request, source, misuse);
@@ -176,17 +203,34 @@ export function createOperationRuntime(dependencies, pipelineDependencies) {
176
203
  if (!validated.ok) {
177
204
  return validated.response;
178
205
  }
179
- const stateful = withRequestState(request);
206
+ const opened = withRequestPolicy(dependencies, withRequestState(request), caller, report);
207
+ const stateful = opened instanceof Promise ? await opened : opened;
208
+ if (!("state" in stateful)) {
209
+ return stateful;
210
+ }
211
+ const forced = isForcedOperation(activeScopeConfig(dependencies.config, request).pipelines, request);
180
212
  const admitted = await admitOperation(pipelineDependencies, stateful, validated.contract, validated.arguments, OPERATION_ARGUMENTS_PATH, report, {
181
213
  requestId: request.requestId,
182
214
  transaction: undefined,
183
215
  state: stateful.state,
184
- });
216
+ }, forced ? FORCED_CALL : SINGLE_CALL);
185
217
  if (!admitted.ok) {
186
218
  return admitted.response;
187
219
  }
188
- if (isForcedOperation(activeScopeConfig(dependencies.config, request).pipelines, request)) {
189
- return executeForcedOperation(pipelineDependencies, dependencies.adapter, stateful, validated.contract, admitted.args, report);
220
+ let checkedWrite = false;
221
+ if (stateful.policy !== undefined &&
222
+ request.family !== "find" &&
223
+ validated.contract.transactions === "interactive" &&
224
+ !forced) {
225
+ try {
226
+ checkedWrite = await writeNeedsTransaction(stateful.policy, dependencies.contracts.core, stateful, () => planReadOperation(dependencies.contracts.core, dependencies.config.adapter.model, validated.contract, activeScopeConfig(dependencies.config, request).compute, stateful, admitted.args), admitted.args);
227
+ }
228
+ catch (error) {
229
+ return sanitizeOperationFailure(error, stateful.policy.execution.boundary.originOf(error), report, { path: OPERATION_ARGUMENTS_PATH, arguments: admitted.args });
230
+ }
231
+ }
232
+ if (forced || checkedWrite) {
233
+ return executeForcedOperation(pipelineDependencies, dependencies.adapter, stateful, validated.contract, admitted.args, report, forced);
190
234
  }
191
235
  return executeAdmittedOperation(pipelineDependencies, stateful, validated.contract, admitted.args, OPERATION_ARGUMENTS_PATH, { kind: "standalone", executor: dependencies.adapter }, report);
192
236
  };
@@ -198,9 +242,11 @@ function validateOperation(dependencies, request, source, misuse) {
198
242
  }
199
243
  const contract = activeContract(dependencies.contracts, request);
200
244
  let owned = request;
201
- if (source === "caller" &&
245
+ if (source !== "owned" &&
202
246
  findOperationAvailabilityIssue(contract, request) === undefined) {
203
- const copy = copyAtDoor(request.arguments);
247
+ const copy = source === "caller"
248
+ ? copyAtDoor(request.arguments)
249
+ : { ok: false, error: source.refused };
204
250
  if (!copy.ok) {
205
251
  return rejected(mapValidationOutcome([
206
252
  refuseCallerData(copy.error, OPERATION_ARGUMENTS_PATH, misuseIdentityOf(request), misuse),
@@ -235,6 +281,12 @@ export function protocolIdentityFailure(contracts, protocol, origin) {
235
281
  return undefined;
236
282
  }
237
283
  export function validateOperationRequest(contract, request, options, write = "copy") {
284
+ if (findOperationAvailabilityIssue(contract, request) === undefined) {
285
+ const sent = withoutUnsentWriteValues(contract, request, request.arguments);
286
+ if (sent !== request.arguments) {
287
+ request = { ...request, arguments: sent };
288
+ }
289
+ }
238
290
  const validation = validateOperationArguments(contract, request, options);
239
291
  if (!validation.ok) {
240
292
  return { ok: false, response: mapValidationOutcome(validation.issues) };
@@ -251,12 +303,13 @@ function rejected(response) {
251
303
  return { ok: false, response };
252
304
  }
253
305
  const FIELD_PIPES = "Field pipes";
254
- const STEP_PIPES = "Pipes";
306
+ export const STEP_PIPES = "Pipes";
255
307
  export const EVERY_FIELD = () => true;
256
308
  function filtersOf(levels) {
257
309
  return levels.flatMap((level) => level.filters);
258
310
  }
259
311
  const SINGLE_CALL = { select: EVERY_FIELD };
312
+ const FORCED_CALL = { select: EVERY_FIELD, beforeBegin: true };
260
313
  export async function admitOperation(dependencies, request, contract, args, argumentsPath, report, scope, admission = SINGLE_CALL) {
261
314
  const contexts = dependencies.contexts;
262
315
  const tree = activeScopeConfig(dependencies.config, request).pipelines;
@@ -299,8 +352,10 @@ export async function admitOperation(dependencies, request, contract, args, argu
299
352
  let pipeIndex = 0;
300
353
  for (const level of levels) {
301
354
  for (const pipe of level.pipes) {
302
- const returned = await pipe(current, context());
303
- if (returned !== undefined && returned !== current) {
355
+ const told = frozenCopy(current);
356
+ const output = await pipe(told, context());
357
+ if (output !== undefined && output !== told && output !== current) {
358
+ const returned = withoutUnsentWriteValues(dependencies.contracts.core, request, output);
304
359
  const refused = refusePipeOutput(contracts, request, returned, pipe, pipeIndex, admission.validation);
305
360
  if (refused !== undefined) {
306
361
  report(refused.error, "A3004");
@@ -322,6 +377,16 @@ export async function admitOperation(dependencies, request, contract, args, argu
322
377
  piped: piped || fields.piped,
323
378
  };
324
379
  };
380
+ const absent = createRequirementIssues(contract, dependencies.recordWrites, request, current, argumentsPath);
381
+ if (absent.length > 0) {
382
+ return { ok: false, response: mapValidationOutcome(absent) };
383
+ }
384
+ if (request.policy !== undefined) {
385
+ const refused = await admitRequestPolicy(request.policy, dependencies.contracts.core, contract, request, current, report, { path: argumentsPath, arguments: current });
386
+ if (refused !== undefined) {
387
+ return { ok: false, response: refused };
388
+ }
389
+ }
325
390
  try {
326
391
  return await admit();
327
392
  }
@@ -333,10 +398,12 @@ export async function admitOperation(dependencies, request, contract, args, argu
333
398
  }
334
399
  }
335
400
  async function runFieldInputStages(dependencies, request, contract, args, argumentsPath, report, admission) {
336
- const tree = activeScopeConfig(dependencies.config, request).pipelines;
401
+ const scopeConfig = activeScopeConfig(dependencies.config, request);
402
+ const tree = scopeConfig.pipelines;
337
403
  const planned = dependencies.fieldStages[request.origin];
338
404
  const pipes = planned.anyPipes;
339
- if (!pipes && !hasFieldValidators(contract)) {
405
+ const judge = admission.beforeBegin === true && hasFieldValidators(contract);
406
+ if (!pipes && !judge) {
340
407
  return { ok: true, args, piped: false };
341
408
  }
342
409
  let current = args;
@@ -364,14 +431,25 @@ async function runFieldInputStages(dependencies, request, contract, args, argume
364
431
  }
365
432
  }
366
433
  }
367
- const broken = fieldValidatorIssues(contract, dependencies.recordWrites.references, request, current, argumentsPath, admission.select);
368
- if (broken.length > 0) {
369
- return { ok: false, response: mapValidationOutcome(broken) };
434
+ if (judge) {
435
+ const compute = scopeConfig.compute;
436
+ const broken = fieldValidatorIssues(contract, dependencies.recordWrites.references, request, current, argumentsPath, admission.select, (resource, stage, field) => {
437
+ const fields = compute !== undefined && Object.hasOwn(compute, resource)
438
+ ? compute[resource]
439
+ : undefined;
440
+ const phases = fields !== undefined && Object.hasOwn(fields, field)
441
+ ? fields[field]
442
+ : undefined;
443
+ return phases?.[stage] !== undefined;
444
+ });
445
+ if (broken.length > 0) {
446
+ return { ok: false, response: mapValidationOutcome(broken) };
447
+ }
370
448
  }
371
449
  return { ok: true, args: current, piped: changed };
372
450
  }
373
451
  export async function prepareStep(dependencies, request, contract, args, argumentsPath, report, executor, changes, outer) {
374
- let current = deepFreeze(args);
452
+ let current = deepFreeze(withoutUnsentWriteValues(dependencies.contracts.core, request, args));
375
453
  const scope = {
376
454
  requestId: request.requestId,
377
455
  transaction: executor,
@@ -395,12 +473,6 @@ export async function prepareStep(dependencies, request, contract, args, argumen
395
473
  return { ok: false, response: refused.response };
396
474
  }
397
475
  }
398
- if (changes.transactionPiped) {
399
- const broken = fieldValidatorIssues(contract, dependencies.recordWrites.references, request, current, argumentsPath, EVERY_FIELD);
400
- if (broken.length > 0) {
401
- return { ok: false, response: mapValidationOutcome(broken) };
402
- }
403
- }
404
476
  return { ok: true, args: deepFreeze(current), piped: resolved.piped };
405
477
  }
406
478
  catch (error) {
@@ -410,7 +482,7 @@ export async function prepareStep(dependencies, request, contract, args, argumen
410
482
  };
411
483
  }
412
484
  }
413
- async function executeForcedOperation(dependencies, adapter, request, contract, args, report) {
485
+ async function executeForcedOperation(dependencies, adapter, request, contract, args, report, forced) {
414
486
  const plan = [
415
487
  {
416
488
  resource: request.resource,
@@ -421,7 +493,9 @@ async function executeForcedOperation(dependencies, adapter, request, contract,
421
493
  ];
422
494
  const settled = await settleTransaction({
423
495
  adapter,
424
- levels: transactionLevelsOf(activeScopeConfig(dependencies.config, request).pipelines, request.resource),
496
+ levels: forced
497
+ ? transactionLevelsOf(activeScopeConfig(dependencies.config, request).pipelines, request.resource)
498
+ : [],
425
499
  plan,
426
500
  contextOf: (current, executor) => dependencies.contexts.transaction({
427
501
  requestId: request.requestId,
@@ -465,15 +539,8 @@ export async function executeAdmittedOperation(dependencies, request, contract,
465
539
  const adapterBoundary = new AdapterBoundary();
466
540
  const contracts = { core: dependencies.contracts.core, active: contract };
467
541
  let args = deepFreeze(admittedArguments);
468
- let told;
469
- const view = () => {
470
- if (told === undefined || told.of !== args) {
471
- told = { of: args, view: frozenCopy(args) };
472
- }
473
- return told.view;
474
- };
475
- const context = () => contexts.operation(scope, operationFacts(contract, request, view()));
476
- const computeContext = () => contexts.compute(scope, operationFacts(contract, request, view()));
542
+ const context = () => contexts.operation(scope, operationFacts(contract, request, args));
543
+ const computeContext = () => contexts.compute(scope, operationFacts(contract, request, args));
477
544
  const reuse = { refusal: undefined };
478
545
  const refusedReuse = (refusal) => {
479
546
  report(refusal, "A3000");
@@ -493,11 +560,52 @@ export async function executeAdmittedOperation(dependencies, request, contract,
493
560
  async function runLifecycle() {
494
561
  let computed = await applyWriteCompute(contracts, scopeConfig.compute, request, args, computeContext);
495
562
  computed = await applyNestedWriteCompute(contracts, scopeConfig.compute, computed, nestedWriteTargetsOf(contract, dependencies.recordWrites.references, request, computed), (target, payload) => contexts.compute(scope, nestedFacts(contract, request, target, payload)));
496
- const missing = createRequirementIssues(contract, dependencies.recordWrites, request, computed, argumentsPath);
497
- if (missing.length > 0) {
498
- return mapValidationOutcome(missing);
563
+ const broken = createRequirementIssues(contract, dependencies.recordWrites, request, computed, argumentsPath);
564
+ const [firstBroken] = broken;
565
+ if (firstBroken !== undefined) {
566
+ const what = firstBroken.code === "V1000"
567
+ ? "dropped a required field"
568
+ : "wrote a reference twice";
569
+ report(new AvPipeOutputError(`Pipes or write compute ${what} of ${request.resource}.${request.family}.${request.variant} at "${(firstBroken.path ?? []).join(".")}" (${firstBroken.code}: ${firstBroken.message})`, broken), "A3004");
570
+ return operationFailure("A3004", {
571
+ message: PIPE_OUTPUT_FAILURE_MESSAGE,
572
+ });
573
+ }
574
+ const unfilled = computedRequirementGapsOf(contract, dependencies.recordWrites, request, computed, argumentsPath, (resource) => createComputedFields(scopeConfig.compute, resource));
575
+ const [firstUnfilled] = unfilled;
576
+ if (firstUnfilled !== undefined) {
577
+ throw new AvComputedValueError(firstUnfilled.resource, firstUnfilled.field, "create", unfilled.map((gap) => gap.issue), `compute.create on ${firstUnfilled.resource}.${firstUnfilled.field} returned undefined for a required field`);
578
+ }
579
+ if (hasFieldValidators(contract)) {
580
+ const refused = fieldValidatorIssues(contract, dependencies.recordWrites.references, request, computed, argumentsPath, EVERY_FIELD);
581
+ if (refused.length > 0) {
582
+ return mapValidationOutcome(refused);
583
+ }
584
+ }
585
+ const hiddenRefusal = hiddenFieldRefusal({ core: dependencies.contracts.core, active: contract }, dependencies.recordWrites.references, request, computed, argumentsPath);
586
+ if (hiddenRefusal !== undefined) {
587
+ throw hiddenRefusal;
499
588
  }
500
589
  args = deepFreeze(computed);
590
+ let policyWrite;
591
+ if (request.policy !== undefined && request.family !== "find") {
592
+ const planned = planReadOperation(dependencies.contracts.core, dependencies.config.adapter.model, contract, scopeConfig.compute, request, args);
593
+ const plannedArguments = await stripVirtualMutationInput(contracts, request, planned.arguments);
594
+ try {
595
+ policyWrite = await enforceWritePolicy(request.policy.on({ executor, boundary: adapterBoundary }), dependencies.contracts.core, dependencies.config.adapter.model, request, planned, plannedArguments, binding.kind === "transaction");
596
+ }
597
+ catch (error) {
598
+ return sanitizeOperationFailure(error, adapterBoundary.originOf(error), report, { path: argumentsPath, arguments: args });
599
+ }
600
+ if (policyWrite.kind === "refused") {
601
+ return policyWrite.response;
602
+ }
603
+ }
604
+ let policyFailure;
605
+ const refuseWrite = (response) => {
606
+ policyFailure = response;
607
+ throw thrownFailure(response);
608
+ };
501
609
  let readMaterialized = false;
502
610
  let executedReadPlan;
503
611
  const materialize = async (data, plan) => {
@@ -506,24 +614,87 @@ export async function executeAdmittedOperation(dependencies, request, contract,
506
614
  return materializeReadOperation(contract, scopeConfig.compute, request, plan, data, computeContext);
507
615
  };
508
616
  const invoke = async () => {
509
- const readPlan = planReadOperation(dependencies.contracts.core, dependencies.config.adapter.model, contract, scopeConfig.compute, request, args);
510
- const adapterArguments = await stripVirtualMutationInput(contracts, request, readPlan.arguments);
511
- const identity = request;
512
- const adapterData = await adapterBoundary.execute(() => executor.execute({
513
- ...identity,
514
- resource: request.resource,
515
- arguments: adapterArguments,
516
- }));
617
+ let readPlan = planReadOperation(dependencies.contracts.core, dependencies.config.adapter.model, contract, scopeConfig.compute, request, args);
618
+ let adapterArguments = await stripVirtualMutationInput(contracts, request, readPlan.arguments);
619
+ let operation = request;
620
+ let settle;
621
+ let writeMiss;
622
+ let failedWrite;
623
+ if (policyWrite !== undefined && policyWrite.kind !== "refused") {
624
+ writeMiss = policyWrite.miss;
625
+ failedWrite = policyWrite.failed;
626
+ if (policyWrite.kind === "empty") {
627
+ if (writeMiss !== undefined && policyWrite.data === null) {
628
+ refuseWrite(await writeMiss());
629
+ }
630
+ return materialize(policyWrite.data, readPlan);
631
+ }
632
+ operation = policyWrite.identity;
633
+ adapterArguments = policyWrite.arguments;
634
+ readPlan = policyWrite.plan;
635
+ settle = policyWrite.settle;
636
+ }
637
+ else if (request.policy !== undefined && request.family === "find") {
638
+ const read = await enforceReadPolicy(request.policy.on({ executor, boundary: adapterBoundary }), dependencies.contracts.core, dependencies.config.adapter.model, request, readPlan, adapterArguments);
639
+ if (read.kind === "refused") {
640
+ throw thrownFailure(read.response);
641
+ }
642
+ if (read.kind === "empty") {
643
+ const miss = uniqueMissFailure(request, read.data);
644
+ if (miss !== undefined) {
645
+ throw thrownFailure(miss);
646
+ }
647
+ return materialize(read.data, readPlan);
648
+ }
649
+ operation = read.identity;
650
+ adapterArguments = read.arguments;
651
+ readPlan = read.plan;
652
+ settle = read.settle;
653
+ }
654
+ const { policy: _session, ...identity } = operation;
655
+ let adapterData;
656
+ try {
657
+ adapterData = await adapterBoundary.execute(() => executor.execute({
658
+ ...identity,
659
+ resource: request.resource,
660
+ arguments: adapterArguments,
661
+ }));
662
+ }
663
+ catch (error) {
664
+ const missed = failedWrite === undefined
665
+ ? undefined
666
+ : await failedWrite(error).catch(() => undefined);
667
+ if (missed !== undefined) {
668
+ refuseWrite(missed);
669
+ }
670
+ throw error;
671
+ }
672
+ if (writeMiss !== undefined && adapterData === null) {
673
+ refuseWrite(await writeMiss());
674
+ }
517
675
  const miss = uniqueMissFailure(request, adapterData);
518
676
  if (miss !== undefined) {
519
677
  throw thrownFailure(miss);
520
678
  }
679
+ if (settle !== undefined) {
680
+ const settled = await settle(adapterData);
681
+ if (!settled.ok) {
682
+ if (policyWrite !== undefined) {
683
+ refuseWrite(settled.response);
684
+ }
685
+ throw thrownFailure(settled.response);
686
+ }
687
+ adapterData = settled.data;
688
+ }
521
689
  return materialize(adapterData, readPlan);
522
690
  };
523
691
  const materialized = async (data) => readMaterialized
524
692
  ? data
525
693
  : materialize(data, planReadOperation(dependencies.contracts.core, dependencies.config.adapter.model, contract, scopeConfig.compute, request, args));
526
694
  const data = await materialized(await runLevelLifecycle(levels, context, invoke, materialized, reuse, () => new AvInterceptorNextError()));
695
+ if (policyFailure !== undefined) {
696
+ return policyFailure;
697
+ }
527
698
  if (!outputAccepted(contract, request, executedReadPlan?.projection, data, report)) {
528
699
  return internalFailure();
529
700
  }
@@ -13,10 +13,11 @@ export declare function uniqueMissFailure(operation: AvOperationIdentity, data:
13
13
  */
14
14
  export declare function mapOperationOutcome(operation: AvOperationIdentity, data: unknown): AvOperationResponse;
15
15
  /** The A-codes a set of Framework Validation Layer issues can roll up to. */
16
- export type ValidationOutcomeCode = "A2001" | "A2002" | "A2004" | "A2007" | "A2009";
16
+ type ValidationOutcomeCode = "A2001" | "A2002" | "A2004" | "A2007" | "A2009";
17
17
  /** The framework's top-level `cause.message` for each validation outcome code. */
18
18
  export declare const VALIDATION_OUTCOME_MESSAGES: {
19
19
  readonly [K in ValidationOutcomeCode]: string;
20
20
  };
21
21
  /** Maps framework validation issues to their stable failure envelope. */
22
22
  export declare function mapValidationOutcome(issues: readonly AvValidationIssue[]): AvOperationFailureResponse;
23
+ export {};
@@ -2,7 +2,7 @@ import type { AvContract } from "../contracts/contract.js";
2
2
  import type { AvOperationIdentity } from "../operations/operation-identity.js";
3
3
  import type { AvValidationIssue } from "../operations/validation-code.js";
4
4
  import type { ReadProjectionPlan } from "./computed-read-runtime.js";
5
- export type OutputValidationResult = {
5
+ type OutputValidationResult = {
6
6
  readonly ok: true;
7
7
  } | {
8
8
  readonly ok: false;
@@ -1,11 +1,21 @@
1
- import type { AgentTransactionRequest, ClientTransactionRequest } from "../transactions/transaction-request.js";
1
+ import type { AvAgentTransactionRequest, AvClientTransactionRequest } from "../transactions/transaction-request.js";
2
2
  import type { AvTransactionResponse } from "../transactions/transaction-response.js";
3
+ import type { AvCallerDataError } from "./caller-data.copier.js";
3
4
  import type { RemoteOperationRequest } from "./operation-request.js";
4
5
  import type { AvOperationResponse } from "./operation-response.js";
5
6
  /** The two entries that run a request the protocol decoded itself, uncopied. */
6
7
  export type OwnedExecution = {
7
- readonly execute: (request: RemoteOperationRequest) => Promise<AvOperationResponse>;
8
- readonly executeTransaction: (request: ClientTransactionRequest | AgentTransactionRequest) => Promise<AvTransactionResponse>;
8
+ /**
9
+ * Runs `request` uncopied; with `refused`, its arguments are a host's parsed body
10
+ * whose copy at the call failed, answered as the door answers that failure.
11
+ */
12
+ readonly execute: (request: RemoteOperationRequest, refused?: AvCallerDataError) => Promise<AvOperationResponse>;
13
+ /**
14
+ * Runs `request` uncopied; with `refused`, its plan is a host's parsed plan taken
15
+ * at the call, and these steps' arguments could not be copied there: each is
16
+ * answered at its turn as the door answers that failure.
17
+ */
18
+ readonly executeTransaction: (request: AvClientTransactionRequest | AvAgentTransactionRequest, refused?: ReadonlyMap<number, AvCallerDataError>) => Promise<AvTransactionResponse>;
9
19
  };
10
20
  /** Records `framework`'s owned entries; called once, at construction. */
11
21
  export declare function recordOwnedExecution(framework: object, execution: OwnedExecution): void;
@@ -24,6 +24,8 @@ import type { AvOperationFailureResponse } from "./operation-response.js";
24
24
  */
25
25
  /** The one text every `A3004` carries on the wire. */
26
26
  export declare const PIPE_OUTPUT_FAILURE_MESSAGE = "A server pipeline produced invalid arguments.";
27
+ /** The Contract a stage's output is held to: Core's Resources plus what `active` adds. */
28
+ export declare function serverContractFor(core: AvContractCore, active: AvContract): AvContract;
27
29
  /** The error the diagnostics channel receives for a refused pipe output. */
28
30
  export declare class AvPipeOutputError extends Error {
29
31
  readonly issues: readonly AvValidationIssue[];
@@ -61,3 +63,11 @@ export declare function refuseStageOutput(contracts: {
61
63
  }, request: AvOperationIdentity & {
62
64
  readonly resource: string;
63
65
  }, args: unknown, subject: string, options?: OperationValidationOptions): RefusedStageOutput | undefined;
66
+ /**
67
+ * The `A3004` for a stage output the server's rules raised `issues` against
68
+ * (paths under `["arguments", …]`), the first named in the diagnostic;
69
+ * `undefined` when there are none.
70
+ */
71
+ export declare function refusedStageOutput(request: AvOperationIdentity & {
72
+ readonly resource: string;
73
+ }, issues: readonly AvValidationIssue[], subject: string): RefusedStageOutput | undefined;