@aventara/core 0.1.0-pilot.4 → 1.0.0-rc.1

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 (255) hide show
  1. package/CHANGELOG.md +1478 -0
  2. package/README.md +275 -11
  3. package/dist/adapters/adapter-discovery-diagnostic.d.ts +4 -4
  4. package/dist/adapters/adapter-field.d.ts +11 -11
  5. package/dist/adapters/adapter-identifier.d.ts +6 -6
  6. package/dist/adapters/adapter-model.d.ts +17 -9
  7. package/dist/adapters/adapter-operation-executor.interface.d.ts +4 -4
  8. package/dist/adapters/adapter-operation.d.ts +3 -3
  9. package/dist/adapters/adapter-resource.d.ts +18 -9
  10. package/dist/adapters/adapter-sql-statement.d.ts +19 -0
  11. package/dist/adapters/adapter-transaction-executor.interface.d.ts +19 -0
  12. package/dist/adapters/adapter.interface.d.ts +49 -25
  13. package/dist/avz/avz-check.factory.d.ts +83 -0
  14. package/dist/avz/avz-check.factory.js +116 -0
  15. package/dist/avz/avz-check.registry.d.ts +35 -0
  16. package/dist/avz/avz-check.registry.js +9 -0
  17. package/dist/avz/avz.d.ts +203 -0
  18. package/dist/avz/avz.js +354 -0
  19. package/dist/avz/index.d.ts +7 -0
  20. package/dist/avz/index.js +1 -0
  21. package/dist/avz/json-shape.registry.d.ts +22 -0
  22. package/dist/avz/json-shape.registry.js +16 -0
  23. package/dist/avz/zod-issue.translator.d.ts +57 -0
  24. package/dist/avz/zod-issue.translator.js +149 -0
  25. package/dist/compiler/contract-compiler-diagnostic.d.ts +37 -5
  26. package/dist/compiler/contract.compiler.d.ts +18 -18
  27. package/dist/compiler/contract.compiler.js +595 -421
  28. package/dist/compiler/create-requirements.projector.d.ts +49 -0
  29. package/dist/compiler/create-requirements.projector.js +423 -0
  30. package/dist/compiler/field-validator.compiler.d.ts +47 -0
  31. package/dist/compiler/field-validator.compiler.js +238 -0
  32. package/dist/config/any-framework-config.d.ts +19 -12
  33. package/dist/config/config-diagnostic.d.ts +11 -4
  34. package/dist/config/config-layer.d.ts +15 -6
  35. package/dist/config/config.resolver.d.ts +75 -29
  36. package/dist/config/config.resolver.js +109 -44
  37. package/dist/config/config.validator.d.ts +7 -7
  38. package/dist/config/config.validator.js +586 -71
  39. package/dist/config/define-resource.d.ts +57 -0
  40. package/dist/config/define-resource.js +14 -0
  41. package/dist/config/effective-fields.d.ts +19 -23
  42. package/dist/config/entrypoint.normalizer.d.ts +1 -1
  43. package/dist/config/exact-framework-config.d.ts +280 -0
  44. package/dist/config/field-compute.resolver.d.ts +19 -0
  45. package/dist/config/field-compute.resolver.js +115 -0
  46. package/dist/config/field-pipeline-config.d.ts +47 -0
  47. package/dist/config/forced-operation.validator.d.ts +10 -0
  48. package/dist/config/forced-operation.validator.js +66 -0
  49. package/dist/config/framework-config.d.ts +111 -37
  50. package/dist/config/framework-exemptions-config.d.ts +91 -0
  51. package/dist/config/framework-exemptions-config.js +1 -0
  52. package/dist/config/framework-field-definition.d.ts +78 -0
  53. package/dist/config/framework-field-definition.js +28 -0
  54. package/dist/config/framework-resources-config.d.ts +116 -0
  55. package/dist/config/framework-resources-config.js +1 -0
  56. package/dist/config/pipeline-config.d.ts +56 -20
  57. package/dist/config/pipeline-tree.resolver.d.ts +79 -0
  58. package/dist/config/pipeline-tree.resolver.js +220 -0
  59. package/dist/config/stage-type.eraser.d.ts +65 -0
  60. package/dist/config/stage-type.eraser.js +1 -0
  61. package/dist/contracts/capability.d.ts +11 -11
  62. package/dist/contracts/client-contract-structure.validator.d.ts +344 -29
  63. package/dist/contracts/client-contract-structure.validator.js +248 -7
  64. package/dist/contracts/contract-canonicalizer.d.ts +19 -3
  65. package/dist/contracts/contract-canonicalizer.js +172 -27
  66. package/dist/contracts/contract-hash.d.ts +12 -7
  67. package/dist/contracts/contract-hash.js +3 -2
  68. package/dist/contracts/contract-limits.d.ts +4 -1
  69. package/dist/contracts/contract-limits.js +1 -0
  70. package/dist/contracts/contract-lookup.d.ts +5 -5
  71. package/dist/contracts/contract-protocol.d.ts +4 -4
  72. package/dist/contracts/contract.d.ts +31 -16
  73. package/dist/contracts/create-requirements.d.ts +35 -0
  74. package/dist/contracts/create-requirements.js +1 -0
  75. package/dist/contracts/enum-definition.d.ts +1 -1
  76. package/dist/contracts/field-check.d.ts +101 -0
  77. package/dist/contracts/field-check.js +1 -0
  78. package/dist/contracts/field.d.ts +61 -41
  79. package/dist/contracts/identifier.d.ts +4 -4
  80. package/dist/contracts/json-shape.d.ts +76 -0
  81. package/dist/contracts/json-shape.js +1 -0
  82. package/dist/contracts/lifecycle-trait.d.ts +2 -2
  83. package/dist/contracts/reference-write-limit.d.ts +7 -0
  84. package/dist/contracts/reference-write-limit.js +1 -0
  85. package/dist/contracts/resource-operations.d.ts +28 -28
  86. package/dist/contracts/resource.d.ts +15 -9
  87. package/dist/contracts/scalar-value-type.d.ts +25 -14
  88. package/dist/contracts/scalar.d.ts +3 -3
  89. package/dist/contracts/transaction-capability.d.ts +1 -1
  90. package/dist/contracts/wire-scalar-format.d.ts +4 -4
  91. package/dist/framework/contract-view.d.ts +234 -63
  92. package/dist/framework/framework-construction.error.d.ts +10 -10
  93. package/dist/framework/framework-construction.error.js +2 -2
  94. package/dist/framework/framework.d.ts +50 -24
  95. package/dist/framework/framework.factory.d.ts +8 -6
  96. package/dist/framework/framework.factory.js +95 -32
  97. package/dist/framework/operation-facade.d.ts +123 -52
  98. package/dist/framework/operation-facade.js +9 -1
  99. package/dist/index.d.ts +55 -82
  100. package/dist/index.js +6 -26
  101. package/dist/internal.d.ts +40 -0
  102. package/dist/internal.js +18 -0
  103. package/dist/operations/operation-arguments.d.ts +316 -201
  104. package/dist/operations/operation-call.d.ts +27 -28
  105. package/dist/operations/operation-identity.d.ts +12 -10
  106. package/dist/operations/operation-identity.js +3 -0
  107. package/dist/operations/operation-result.d.ts +21 -21
  108. package/dist/operations/operation-validator-core.d.ts +6 -6
  109. package/dist/operations/operation-validator-core.js +41 -12
  110. package/dist/operations/operation-validator.d.ts +24 -9
  111. package/dist/operations/operation-validator.js +26 -10
  112. package/dist/operations/projection-scope.resolver.d.ts +7 -7
  113. package/dist/operations/structural-limits.walker.d.ts +19 -0
  114. package/dist/operations/structural-limits.walker.js +489 -0
  115. package/dist/operations/validation-code.d.ts +11 -6
  116. package/dist/operations/validation-code.js +4 -0
  117. package/dist/operations/write-scope.resolver.d.ts +6 -6
  118. package/dist/protocol/absent-route.responder.d.ts +13 -11
  119. package/dist/protocol/absent-route.responder.js +42 -16
  120. package/dist/protocol/contract-document.responder.d.ts +3 -3
  121. package/dist/protocol/contract-document.responder.js +2 -2
  122. package/dist/protocol/http-request.decoder.d.ts +23 -13
  123. package/dist/protocol/http-request.decoder.js +19 -11
  124. package/dist/protocol/http-request.reader.d.ts +3 -3
  125. package/dist/protocol/http-response.encoder.d.ts +4 -4
  126. package/dist/protocol/http-response.encoder.js +94 -55
  127. package/dist/protocol/http-status.table.d.ts +2 -2
  128. package/dist/protocol/operation-response.guard.d.ts +2 -2
  129. package/dist/protocol/protocol-surface.d.ts +4 -4
  130. package/dist/protocol/protocol.binder.d.ts +52 -27
  131. package/dist/protocol/protocol.binder.js +14 -9
  132. package/dist/protocol/protocol.handler.d.ts +28 -15
  133. package/dist/protocol/protocol.handler.js +55 -10
  134. package/dist/protocol/unmounted-route.error.d.ts +19 -0
  135. package/dist/protocol/unmounted-route.error.js +10 -0
  136. package/dist/runtime/caller-data.copier.d.ts +59 -0
  137. package/dist/runtime/caller-data.copier.js +470 -0
  138. package/dist/runtime/caller-data.door.d.ts +56 -0
  139. package/dist/runtime/caller-data.door.js +67 -0
  140. package/dist/runtime/computed-read-runtime.d.ts +7 -6
  141. package/dist/runtime/computed-read-runtime.js +61 -55
  142. package/dist/runtime/computed-value.error.d.ts +13 -0
  143. package/dist/runtime/computed-value.error.js +9 -0
  144. package/dist/runtime/context-executor.runtime.d.ts +59 -0
  145. package/dist/runtime/context-executor.runtime.js +275 -0
  146. package/dist/runtime/create-requirement.d.ts +22 -57
  147. package/dist/runtime/create-requirement.js +140 -37
  148. package/dist/runtime/decimal.d.ts +2 -2
  149. package/dist/runtime/decimal.js +1 -1
  150. package/dist/runtime/diagnostics-reporter.d.ts +64 -22
  151. package/dist/runtime/diagnostics-reporter.js +35 -4
  152. package/dist/runtime/error-boundary.d.ts +73 -8
  153. package/dist/runtime/error-boundary.js +104 -48
  154. package/dist/runtime/execution-options.d.ts +10 -2
  155. package/dist/runtime/field-check.evaluator.d.ts +29 -0
  156. package/dist/runtime/field-check.evaluator.js +521 -0
  157. package/dist/runtime/field-compute.d.ts +64 -0
  158. package/dist/runtime/field-compute.js +1 -0
  159. package/dist/runtime/field-stage.plan.d.ts +15 -0
  160. package/dist/runtime/field-stage.plan.js +27 -0
  161. package/dist/runtime/field-stage.runtime.d.ts +35 -0
  162. package/dist/runtime/field-stage.runtime.js +143 -0
  163. package/dist/runtime/field-validator.runtime.d.ts +11 -0
  164. package/dist/runtime/field-validator.runtime.js +87 -0
  165. package/dist/runtime/framework-error-class.table.d.ts +33 -0
  166. package/dist/runtime/framework-error-class.table.js +25 -0
  167. package/dist/runtime/framework-error.d.ts +79 -7
  168. package/dist/runtime/framework-error.factory.d.ts +4 -0
  169. package/dist/runtime/framework-error.factory.js +15 -0
  170. package/dist/runtime/framework-error.js +23 -2
  171. package/dist/runtime/interceptor-next.error.d.ts +5 -0
  172. package/dist/runtime/interceptor-next.error.js +6 -0
  173. package/dist/runtime/json-value.d.ts +3 -3
  174. package/dist/runtime/level-lifecycle.runtime.d.ts +25 -0
  175. package/dist/runtime/level-lifecycle.runtime.js +42 -0
  176. package/dist/runtime/misuse-reporter.d.ts +32 -0
  177. package/dist/runtime/misuse-reporter.js +19 -0
  178. package/dist/runtime/mutation-planner.d.ts +19 -10
  179. package/dist/runtime/mutation-planner.js +62 -36
  180. package/dist/runtime/nested-write.walker.d.ts +32 -0
  181. package/dist/runtime/nested-write.walker.js +73 -0
  182. package/dist/runtime/operation-request.d.ts +35 -15
  183. package/dist/runtime/operation-response.d.ts +17 -17
  184. package/dist/runtime/operation-runtime.d.ts +125 -30
  185. package/dist/runtime/operation-runtime.js +423 -83
  186. package/dist/runtime/outcome-mapper.d.ts +16 -5
  187. package/dist/runtime/outcome-mapper.js +35 -8
  188. package/dist/runtime/output-validator.d.ts +16 -6
  189. package/dist/runtime/output-validator.js +12 -1
  190. package/dist/runtime/owned-execution.registry.d.ts +13 -0
  191. package/dist/runtime/owned-execution.registry.js +7 -0
  192. package/dist/runtime/pipe-output.validator.d.ts +33 -18
  193. package/dist/runtime/pipe-output.validator.js +12 -12
  194. package/dist/runtime/pipeline.d.ts +202 -28
  195. package/dist/runtime/readonly-value.d.ts +32 -0
  196. package/dist/runtime/readonly-value.js +141 -0
  197. package/dist/runtime/referential-action.d.ts +7 -0
  198. package/dist/runtime/request-envelope.validator.d.ts +5 -0
  199. package/dist/runtime/request-envelope.validator.js +123 -0
  200. package/dist/runtime/request-id.d.ts +1 -1
  201. package/dist/runtime/request-state.d.ts +14 -0
  202. package/dist/runtime/request-state.js +1 -0
  203. package/dist/runtime/request-state.resolver.d.ts +12 -0
  204. package/dist/runtime/request-state.resolver.js +20 -0
  205. package/dist/runtime/scalar-runtime.d.ts +56 -13
  206. package/dist/runtime/scalar-runtime.js +167 -86
  207. package/dist/transactions/deferred-operation.d.ts +35 -20
  208. package/dist/transactions/operation-arguments-encoder.d.ts +3 -3
  209. package/dist/transactions/operation-arguments-encoder.js +2 -2
  210. package/dist/transactions/sql-statement.d.ts +77 -0
  211. package/dist/transactions/sql-statement.js +47 -0
  212. package/dist/transactions/sql-statement.validator.d.ts +44 -0
  213. package/dist/transactions/sql-statement.validator.js +134 -0
  214. package/dist/transactions/transaction-envelope.d.ts +4 -4
  215. package/dist/transactions/transaction-integrity-error.d.ts +6 -6
  216. package/dist/transactions/transaction-integrity-error.js +5 -2
  217. package/dist/transactions/transaction-plan-assembler.d.ts +23 -9
  218. package/dist/transactions/transaction-plan-assembler.js +195 -82
  219. package/dist/transactions/transaction-plan-validator.d.ts +53 -21
  220. package/dist/transactions/transaction-plan-validator.js +246 -163
  221. package/dist/transactions/transaction-reference-collector.d.ts +30 -0
  222. package/dist/transactions/transaction-reference-collector.js +204 -0
  223. package/dist/transactions/transaction-reference-resolver.d.ts +19 -2
  224. package/dist/transactions/transaction-reference-resolver.js +27 -10
  225. package/dist/transactions/transaction-reference-validator.d.ts +34 -4
  226. package/dist/transactions/transaction-reference-validator.js +82 -43
  227. package/dist/transactions/transaction-reference.d.ts +30 -58
  228. package/dist/transactions/transaction-request.d.ts +20 -7
  229. package/dist/transactions/transaction-response.d.ts +12 -7
  230. package/dist/transactions/transaction-response.js +24 -1
  231. package/dist/transactions/transaction-runtime.d.ts +11 -8
  232. package/dist/transactions/transaction-runtime.js +167 -50
  233. package/dist/transactions/transaction-settlement.runtime.d.ts +51 -0
  234. package/dist/transactions/transaction-settlement.runtime.js +120 -0
  235. package/dist/transactions/transaction-slot-path-error.d.ts +4 -4
  236. package/dist/transactions/transaction-slot-path-error.js +2 -2
  237. package/dist/transactions/transaction-slot-writer.js +2 -2
  238. package/dist/transactions/transaction-stage.runtime.d.ts +81 -0
  239. package/dist/transactions/transaction-stage.runtime.js +123 -0
  240. package/package.json +18 -3
  241. package/src/runtime/field-check.evaluator.ts +720 -0
  242. package/dist/config/define-fields.d.ts +0 -35
  243. package/dist/config/define-fields.js +0 -3
  244. package/dist/config/framework-behaviors-config.d.ts +0 -30
  245. package/dist/config/framework-fields-config.d.ts +0 -36
  246. package/dist/config/framework-restrictions-config.d.ts +0 -142
  247. package/dist/operations/operation-boolean-nodes.d.ts +0 -11
  248. package/dist/operations/operation-boolean-nodes.js +0 -283
  249. package/dist/operations/operation-nesting.d.ts +0 -8
  250. package/dist/operations/operation-nesting.js +0 -307
  251. package/dist/runtime/field-behavior.d.ts +0 -48
  252. /package/dist/{config/framework-behaviors-config.js → adapters/adapter-sql-statement.js} +0 -0
  253. /package/dist/{config/framework-fields-config.js → adapters/adapter-transaction-executor.interface.js} +0 -0
  254. /package/dist/config/{framework-restrictions-config.js → exact-framework-config.js} +0 -0
  255. /package/dist/{runtime/field-behavior.js → config/field-pipeline-config.js} +0 -0
@@ -1,6 +1,7 @@
1
- import type { Framework } from "../framework/framework.js";
2
- import type { OperationResponse } from "../runtime/operation-response.js";
3
- import type { TransactionResponse } from "../transactions/transaction-response.js";
1
+ import type { AvFramework } from "../framework/framework.js";
2
+ import type { AvOperationResponse } from "../runtime/operation-response.js";
3
+ import type { AvState } from "../runtime/request-state.js";
4
+ import type { AvTransactionResponse } from "../transactions/transaction-response.js";
4
5
  import { type AvProtocolRequest, type DecodedOperation, type DecodedOperationRequest, type DecodedTransaction } from "./http-request.decoder.js";
5
6
  import { type AvProtocolResponse } from "./http-response.encoder.js";
6
7
  import { transportFailure } from "./protocol-failure.js";
@@ -11,49 +12,51 @@ import { type SurfaceRoute } from "./protocol-surface.js";
11
12
  */
12
13
  export type AvProtocolBinding = {
13
14
  /**
14
- * Every route a host mounts for the bound ClientContract, from one list, each
15
+ * Every route a host mounts for the bound Contract (the Client Contract, or the
16
+ * Agent Contract under `{ origin: "agent" }`), from one list, each
15
17
  * tagged by `kind`: one `POST` `operation` route per `(resource, family, variant)`
16
- * it advertises — nothing it does not — then the `contract` route `GET /_contract`
18
+ * it advertises and no other, then the `contract` route `GET /_contract`
17
19
  * (always), then the `transactions` route `POST /_transactions` exactly when its
18
20
  * `transactions` is `"interactive"`. Each path is relative to
19
- * `framework.entrypoint`. Read once at bind time: every call answers the same
21
+ * `framework.api`. Read once at bind time: every call answers the same
20
22
  * deep-frozen list, which is passive data a host may serialize.
21
23
  */
22
24
  readonly surface: () => readonly SurfaceRoute[];
23
25
  /**
24
- * An operation route's HTTP request → the client-origin request
26
+ * An operation route's HTTP request → the client-origin (or the binding's
27
+ * agent-origin) request
25
28
  * `framework.execute` takes, or the framework response that answers it instead,
26
29
  * with the request id either way. Answers absence for an unadvertised triple
27
30
  * without executing it, so a catch-all host is safe. Raw body: size, content type,
28
- * JSON and shape enforced; parsed body: shape only — the rest was the host's
29
- * parser's.
31
+ * JSON and shape enforced; parsed body: shape only, since the rest was the
32
+ * host's parser's job.
30
33
  */
31
34
  readonly decodeOperation: (request: AvProtocolRequest) => DecodedOperation;
32
35
  /**
33
- * The same for `/_transactions` → the client-origin plan request
34
- * `framework.executeTransaction` takes; absent unless the ClientContract's
36
+ * The same for `/_transactions` → the binding's origin's plan request
37
+ * `framework.executeTransaction` takes; absent unless the bound Contract's
35
38
  * transactions are `"interactive"`.
36
39
  */
37
40
  readonly decodeTransaction: (request: AvProtocolRequest) => DecodedTransaction;
38
41
  /**
39
- * One operation's framework response — what `framework.execute` answered — as the
42
+ * One operation's framework response (what `framework.execute` answered) as the
40
43
  * HTTP response a host writes: the code's status, `data` in wire forms, `Aventara-
41
44
  * Request-Id` echoed. A result with no wire form answers `A3003` → 500. A
42
45
  * diagnostic of one operation names it (`resource`, `family`, `variant`), so the
43
- * `A3003` reaches the diagnostics sink only when the host passes `decoded` —
44
- * `decodeOperation`'s success value — as `handleOperation` does; without it the
46
+ * `A3003` reaches the diagnostics sink only when the host passes `decoded`
47
+ * (`decodeOperation`'s success value), as `handleOperation` does; without it the
45
48
  * answer is the same and nothing is reported.
46
49
  */
47
- readonly encodeOperation: (response: OperationResponse, requestId: string, decoded?: DecodedOperationRequest) => AvProtocolResponse;
50
+ readonly encodeOperation: (response: AvOperationResponse, requestId: string, decoded?: DecodedOperationRequest) => AvProtocolResponse;
48
51
  /**
49
- * The same for `/_transactions` — what `framework.executeTransaction` answered. An
52
+ * The same for `/_transactions`: what `framework.executeTransaction` answered. An
50
53
  * `A3003` is reported to the Framework's diagnostics sink as a `"transaction"`
51
- * diagnostic — client scope, this `requestId`, the step it blames as `operation` —
54
+ * diagnostic (client origin, this `requestId`, the step it blames as `operation`)
52
55
  * with the value that had no wire form (or what its getter threw) as `error`.
53
56
  */
54
- readonly encodeTransaction: (response: TransactionResponse, requestId: string) => AvProtocolResponse;
57
+ readonly encodeTransaction: (response: AvTransactionResponse, requestId: string) => AvProtocolResponse;
55
58
  /**
56
- * A transport code — `A2000`, `A2010`, `A2011` or `A2012` — as the complete
59
+ * A transport code (`A2000`, `A2010`, `A2011` or `A2012`) as the complete
57
60
  * framework response. For a host that parses the body itself and must answer
58
61
  * its parser's failure. `A2012` requires the methods its route allows, so
59
62
  * every 405 carries `Allow`.
@@ -67,20 +70,30 @@ export type AvProtocolBinding = {
67
70
  * host hands it: one that is not an `AvProtocolRequest` answers `400 A2000`; it
68
71
  * never rejects.
69
72
  */
70
- readonly handleOperation: (request: AvProtocolRequest) => Promise<AvProtocolResponse>;
73
+ readonly handleOperation: (request: AvProtocolRequest, options?: {
74
+ /**
75
+ * Seeds the request's `ctx.$state` (a host reads its platform request
76
+ * here, Passport's `req.user`, say). Called once, after decoding; a
77
+ * throw is answered like any developer failure. Omitted, the state is `{}`.
78
+ */
79
+ readonly state?: () => AvState | Promise<AvState>;
80
+ }) => Promise<AvProtocolResponse>;
71
81
  /**
72
82
  * The same for `/_transactions`: `decodeTransaction` →
73
83
  * `framework.executeTransaction` → `encodeTransaction`. Every step runs under
74
84
  * ClientContract rules; a committed plan is `200 A1009`, a rolled-back one its
75
85
  * failing step's own status.
76
86
  */
77
- readonly handleTransaction: (request: AvProtocolRequest) => Promise<AvProtocolResponse>;
87
+ readonly handleTransaction: (request: AvProtocolRequest, options?: {
88
+ /** Seeds the plan's one `ctx.$state`, as for `handleOperation`. */
89
+ readonly state?: () => AvState | Promise<AvState>;
90
+ }) => Promise<AvProtocolResponse>;
78
91
  /**
79
92
  * The `GET /_contract` responder: the bound ClientContract's JCS-canonical bytes,
80
93
  * `ETag` its quoted hash, `Cache-Control: no-cache`, and `304` with no body when
81
94
  * `If-None-Match` matches (weak comparison, a list, `*`). Requires no identity
82
- * header; any other method is `405 A2012` with `Allow: GET`. The bytes are written
83
- * once, at bind time.
95
+ * header; any other method is `405 A2012` with `Allow: GET`. The bytes are the ones
96
+ * the Contract's hash was taken over, written once, at construction.
84
97
  */
85
98
  readonly encodeContract: (request: AvProtocolRequest) => AvProtocolResponse;
86
99
  /**
@@ -89,12 +102,24 @@ export type AvProtocolBinding = {
89
102
  * `A2005`, `A2001`, `A2002` or `A2012` (with `Allow`) as the operation routes
90
103
  * would, `500 A3000` for a mounted route reached with its own method, and
91
104
  * `undefined` for a path outside the protocol's namespace, which the host
92
- * answers itself.
105
+ * answers itself. An operation or `/_transactions` route answered `500 A3000`
106
+ * is also reported once to the Framework's diagnostics sink, as an
107
+ * `AvUnmountedRouteError` naming the route the host did not mount.
93
108
  */
94
109
  readonly answerAbsent: (request: AvProtocolRequest) => AvProtocolResponse | undefined;
95
110
  };
96
111
  /**
97
- * `AvProtocol.bind(framework)`: reads the instance's compiled ClientContract
98
- * once and returns the bound members, frozen.
112
+ * `AvProtocol.bind(framework, options?)`: reads the instance's compiled Client
113
+ * Contract (or, with `{ origin: "agent" }`, its Agent Contract) once and returns
114
+ * the bound members, frozen. Every request decoded through it runs under that
115
+ * origin.
99
116
  */
100
- export declare function bind(framework: Framework): AvProtocolBinding;
117
+ export declare function bind(framework: AvFramework, options?: {
118
+ /**
119
+ * The origin every request through this binding runs under: `"client"`
120
+ * (the default: the Client Contract, `/_contract`'s document) or `"agent"`
121
+ * (the Agent Contract, its hash and its layer's pipelines), for a host
122
+ * that serves an AI agent — an MCP server.
123
+ */
124
+ readonly origin?: "client" | "agent";
125
+ }): AvProtocolBinding;
@@ -1,4 +1,5 @@
1
1
  import { diagnosticsSinkOf } from "../runtime/diagnostics-reporter.js";
2
+ import { ownedExecutionOf } from "../runtime/owned-execution.registry.js";
2
3
  import { answerAbsentRequest } from "./absent-route.responder.js";
3
4
  import { contractDocumentOf, encodeContractRequest, } from "./contract-document.responder.js";
4
5
  import { decodeOperationRequest, decodeTransactionRequest, } from "./http-request.decoder.js";
@@ -6,29 +7,33 @@ import { encodeOperationResponse, encodeTransactionResponse, } from "./http-resp
6
7
  import { handleOperationRequest, handleTransactionRequest, operationUnencodableReport, planUnencodableReport, } from "./protocol.handler.js";
7
8
  import { transportFailure } from "./protocol-failure.js";
8
9
  import { surfaceOf } from "./protocol-surface.js";
9
- export function bind(framework) {
10
+ export function bind(framework, options) {
10
11
  const { contracts } = framework;
11
- const surface = surfaceOf(contracts.client);
12
- const document = contractDocumentOf(contracts.client);
12
+ const origin = options?.origin === "agent" ? "agent" : "client";
13
+ const contract = contracts[origin];
14
+ const surface = surfaceOf(contract);
15
+ const document = contractDocumentOf(contract);
13
16
  const sink = diagnosticsSinkOf(framework);
14
17
  const handler = {
15
18
  contracts,
19
+ origin,
16
20
  execute: (request) => framework.execute(request),
17
21
  executeTransaction: (request) => framework.executeTransaction(request),
22
+ owned: ownedExecutionOf(framework),
18
23
  sink,
19
24
  };
20
25
  return Object.freeze({
21
26
  surface: () => surface,
22
- decodeOperation: (request) => decodeOperationRequest(contracts, request),
23
- decodeTransaction: (request) => decodeTransactionRequest(contracts, request),
27
+ decodeOperation: (request) => decodeOperationRequest(contracts, request, origin),
28
+ decodeTransaction: (request) => decodeTransactionRequest(contracts, request, origin),
24
29
  encodeOperation: (response, requestId, decoded) => encodeOperationResponse(response, requestId, decoded === undefined
25
30
  ? undefined
26
31
  : operationUnencodableReport(sink, decoded.request)),
27
- encodeTransaction: (response, requestId) => encodeTransactionResponse(response, requestId, planUnencodableReport(sink, requestId)),
32
+ encodeTransaction: (response, requestId) => encodeTransactionResponse(response, requestId, planUnencodableReport(sink, requestId, origin)),
28
33
  failure: transportFailure,
29
- handleOperation: (request) => handleOperationRequest(handler, request),
30
- handleTransaction: (request) => handleTransactionRequest(handler, request),
34
+ handleOperation: (request, options) => handleOperationRequest(handler, request, options),
35
+ handleTransaction: (request, options) => handleTransactionRequest(handler, request, options),
31
36
  encodeContract: (request) => encodeContractRequest(document, request),
32
- answerAbsent: (request) => answerAbsentRequest(contracts, request),
37
+ answerAbsent: (request) => answerAbsentRequest(contracts, request, sink, origin),
33
38
  });
34
39
  }
@@ -1,34 +1,47 @@
1
- import type { FrameworkContracts } from "../compiler/contract.compiler.js";
2
- import type { Framework } from "../framework/framework.js";
3
- import { type FrameworkDiagnosticsSink } from "../runtime/diagnostics-reporter.js";
4
- import type { ClientOperationRequest } from "../runtime/operation-request.js";
1
+ import type { AvContracts } from "../compiler/contract.compiler.js";
2
+ import type { RemoteRequestOrigin } from "../config/config-layer.js";
3
+ import type { AvFramework } from "../framework/framework.js";
4
+ import { type AvDiagnosticsSink } from "../runtime/diagnostics-reporter.js";
5
+ import type { RemoteOperationRequest } from "../runtime/operation-request.js";
6
+ import type { OwnedExecution } from "../runtime/owned-execution.registry.js";
7
+ import type { AvState } from "../runtime/request-state.js";
5
8
  import { type AvProtocolRequest } from "./http-request.decoder.js";
6
9
  import { type AvProtocolResponse, type UnencodableReport } from "./http-response.encoder.js";
7
10
  /**
8
11
  * What the shortcuts read off the bound Framework: its compiled Contracts, its
9
- * execution entry points and its configured diagnostics sink.
12
+ * execution entry points — the public ones, and the owned ones that run a body this
13
+ * decoder parsed without copying it again (absent for anything but a
14
+ * constructed Framework) — and its configured diagnostics sink.
10
15
  */
11
16
  export type HandlerContext = {
12
- readonly contracts: FrameworkContracts;
13
- readonly execute: Framework["execute"];
14
- readonly executeTransaction: Framework["executeTransaction"];
15
- readonly sink: FrameworkDiagnosticsSink | undefined;
17
+ readonly contracts: AvContracts;
18
+ /** The origin every request the binding decodes runs under. */
19
+ readonly origin: RemoteRequestOrigin;
20
+ readonly execute: AvFramework["execute"];
21
+ readonly executeTransaction: AvFramework["executeTransaction"];
22
+ readonly owned: OwnedExecution | undefined;
23
+ readonly sink: AvDiagnosticsSink | undefined;
24
+ };
25
+ /** What a host passes beside one protocol request. */
26
+ export type ProtocolCallOptions = {
27
+ /** Seeds the request's `ctx.$state`; called once, after decoding. Omitted, the state is `{}`. */
28
+ readonly state?: () => AvState | Promise<AvState>;
16
29
  };
17
30
  /**
18
31
  * Where a plan's `A3003` goes: the Framework's diagnostics sink, as a `"transaction"`
19
- * diagnostic — client scope, the request id the plan ran under, and the step the
32
+ * diagnostic — client origin, the request id the plan ran under, and the step the
20
33
  * encoder blames as `operation` when it blames one. One spelling for both
21
34
  * `protocol.encodeTransaction` and `protocol.handleTransaction`.
22
35
  */
23
- export declare function planUnencodableReport(sink: FrameworkDiagnosticsSink | undefined, requestId: string): UnencodableReport;
36
+ export declare function planUnencodableReport(sink: AvDiagnosticsSink | undefined, requestId: string, origin?: RemoteRequestOrigin): UnencodableReport;
24
37
  /**
25
38
  * Where one operation's `A3003` goes: the Framework's diagnostics sink, as an
26
39
  * `"operation"` diagnostic carrying the decoded request's identity and id — the shape
27
- * the public `OperationDiagnostic` already has. One spelling for
40
+ * the public `AvOperationDiagnostic` already has. One spelling for
28
41
  * `protocol.handleOperation` and for `protocol.encodeOperation` given the decoded
29
42
  * request.
30
43
  */
31
- export declare function operationUnencodableReport(sink: FrameworkDiagnosticsSink | undefined, request: ClientOperationRequest): UnencodableReport;
44
+ export declare function operationUnencodableReport(sink: AvDiagnosticsSink | undefined, request: RemoteOperationRequest): UnencodableReport;
32
45
  /**
33
46
  * `protocol.handleOperation(request)`: the three steps a host would otherwise spell
34
47
  * out — `decodeOperation` → `framework.execute` → `encodeOperation` — in one call,
@@ -36,7 +49,7 @@ export declare function operationUnencodableReport(sink: FrameworkDiagnosticsSin
36
49
  * itself (a transport failure, an identity mismatch, an unadvertised route) is
37
50
  * answered without executing.
38
51
  */
39
- export declare function handleOperationRequest(context: HandlerContext, request: AvProtocolRequest): Promise<AvProtocolResponse>;
52
+ export declare function handleOperationRequest(context: HandlerContext, request: AvProtocolRequest, options?: ProtocolCallOptions): Promise<AvProtocolResponse>;
40
53
  /**
41
54
  * `protocol.handleTransaction(request)`: the same shortcut for `/_transactions` —
42
55
  * `decodeTransaction` → `framework.executeTransaction` → `encodeTransaction`. The
@@ -48,4 +61,4 @@ export declare function handleOperationRequest(context: HandlerContext, request:
48
61
  * handleOperationRequest} is; an `A3003` is reported through {@link
49
62
  * planUnencodableReport}.
50
63
  */
51
- export declare function handleTransactionRequest(context: HandlerContext, request: AvProtocolRequest): Promise<AvProtocolResponse>;
64
+ export declare function handleTransactionRequest(context: HandlerContext, request: AvProtocolRequest, options?: ProtocolCallOptions): Promise<AvProtocolResponse>;
@@ -1,10 +1,41 @@
1
1
  import { createDiagnosticsReporter, createReporter, } from "../runtime/diagnostics-reporter.js";
2
- import { decodeOperationRequest, decodeTransactionRequest, } from "./http-request.decoder.js";
2
+ import { sanitizeOperationFailure } from "../runtime/error-boundary.js";
3
+ import { decodeOperationRequest, decodeTransactionRequest, isParsedByDecoder, } from "./http-request.decoder.js";
3
4
  import { encodeOperationResponse, encodeTransactionResponse, } from "./http-response.encoder.js";
4
- export function planUnencodableReport(sink, requestId) {
5
+ function operationEntry(context, request) {
6
+ return context.owned !== undefined && isParsedByDecoder(request.arguments)
7
+ ? context.owned.execute
8
+ : context.execute;
9
+ }
10
+ function transactionEntry(context, request) {
11
+ return context.owned !== undefined && isParsedByDecoder(request.plan)
12
+ ? context.owned.executeTransaction
13
+ : context.executeTransaction;
14
+ }
15
+ async function seededState(options, report, view) {
16
+ if (options?.state === undefined) {
17
+ return { ok: true, state: undefined };
18
+ }
19
+ try {
20
+ const state = await options.state();
21
+ return {
22
+ ok: true,
23
+ state: typeof state === "object" && state !== null && !Array.isArray(state)
24
+ ? state
25
+ : undefined,
26
+ };
27
+ }
28
+ catch (error) {
29
+ return {
30
+ ok: false,
31
+ response: sanitizeOperationFailure(error, "runtime", report, view),
32
+ };
33
+ }
34
+ }
35
+ export function planUnencodableReport(sink, requestId, origin = "client") {
5
36
  return (error, operation) => createReporter(sink, {
6
37
  kind: "transaction",
7
- scope: "client",
38
+ origin,
8
39
  requestId,
9
40
  ...(operation === undefined ? {} : { operation }),
10
41
  })(error, "A3003");
@@ -12,19 +43,33 @@ export function planUnencodableReport(sink, requestId) {
12
43
  export function operationUnencodableReport(sink, request) {
13
44
  return (error) => createDiagnosticsReporter(sink, request)(error, "A3003");
14
45
  }
15
- export async function handleOperationRequest(context, request) {
16
- const decoded = decodeOperationRequest(context.contracts, request);
46
+ export async function handleOperationRequest(context, request, options) {
47
+ const decoded = decodeOperationRequest(context.contracts, request, context.origin);
17
48
  if (!decoded.ok) {
18
49
  return decoded.response;
19
50
  }
20
- const response = await context.execute(decoded.request);
51
+ const seeded = await seededState(options, createDiagnosticsReporter(context.sink, decoded.request), { path: ["arguments"], arguments: decoded.request.arguments });
52
+ const response = seeded.ok
53
+ ? await operationEntry(context, decoded.request)(seeded.state === undefined
54
+ ? decoded.request
55
+ : { ...decoded.request, state: seeded.state })
56
+ : seeded.response;
21
57
  return encodeOperationResponse(response, decoded.requestId, operationUnencodableReport(context.sink, decoded.request));
22
58
  }
23
- export async function handleTransactionRequest(context, request) {
24
- const decoded = decodeTransactionRequest(context.contracts, request);
59
+ export async function handleTransactionRequest(context, request, options) {
60
+ const decoded = decodeTransactionRequest(context.contracts, request, context.origin);
25
61
  if (!decoded.ok) {
26
62
  return decoded.response;
27
63
  }
28
- const response = await context.executeTransaction(decoded.request);
29
- return encodeTransactionResponse(response, decoded.requestId, planUnencodableReport(context.sink, decoded.requestId));
64
+ const seeded = await seededState(options, createReporter(context.sink, {
65
+ kind: "transaction",
66
+ origin: context.origin,
67
+ requestId: decoded.requestId,
68
+ }), { path: ["plan"], arguments: decoded.request.plan });
69
+ const response = seeded.ok
70
+ ? await transactionEntry(context, decoded.request)(seeded.state === undefined
71
+ ? decoded.request
72
+ : { ...decoded.request, state: seeded.state })
73
+ : seeded.response;
74
+ return encodeTransactionResponse(response, decoded.requestId, planUnencodableReport(context.sink, decoded.requestId, context.origin));
30
75
  }
@@ -0,0 +1,19 @@
1
+ /**
2
+ * What the diagnostics sink receives when `protocol.answerAbsent` is handed a
3
+ * request for a route the ClientContract advertises, with that route's own
4
+ * method: the host mounted only part of `protocol.surface()`. The caller's
5
+ * `500 A3000` is unchanged; this error names the route the host left out, so the
6
+ * server's diagnostics show it too. It is never sent to the caller.
7
+ */
8
+ export declare class AvUnmountedRouteError extends Error {
9
+ /** What the ClientContract advertises: `resource.family.variant`, or `transactions`. */
10
+ readonly advertised: string;
11
+ /** The route as the request reached it: method and api-relative path. */
12
+ readonly route: string;
13
+ readonly name = "AvUnmountedRouteError";
14
+ constructor(
15
+ /** What the ClientContract advertises: `resource.family.variant`, or `transactions`. */
16
+ advertised: string,
17
+ /** The route as the request reached it: method and api-relative path. */
18
+ route: string);
19
+ }
@@ -0,0 +1,10 @@
1
+ export class AvUnmountedRouteError extends Error {
2
+ advertised;
3
+ route;
4
+ name = "AvUnmountedRouteError";
5
+ constructor(advertised, route) {
6
+ super(`The ClientContract advertises ${advertised}, but the host mounted no route for ${route}, so protocol.answerAbsent answered it 500 A3000. Mount every protocol.surface() entry.`);
7
+ this.advertised = advertised;
8
+ this.route = route;
9
+ }
10
+ }
@@ -0,0 +1,59 @@
1
+ /** Why a caller value could not be copied. */
2
+ export type CallerDataFailureKind = "unreadable-value" | "non-plain-value";
3
+ /** A data location inside the copied value, from its root. */
4
+ export type CallerDataPath = readonly (string | number)[];
5
+ /**
6
+ * The curated failure of a door copy: what failed and where, relative to the copied
7
+ * root. Thrown by {@link copyCallerData} and caught by every door, which answers it as
8
+ * the caller's `A2004`/`V1001` at its own address. It never carries the value.
9
+ */
10
+ export declare class AvCallerDataError extends Error {
11
+ readonly kind: CallerDataFailureKind;
12
+ readonly path: CallerDataPath;
13
+ /**
14
+ * The control mirror `path` starts from, when the failure is a mirror's
15
+ * tripwire read after the door; {@link locateCallerDataError} resolves it.
16
+ */
17
+ readonly within?: object | undefined;
18
+ readonly name = "AvCallerDataError";
19
+ constructor(kind: CallerDataFailureKind, path: CallerDataPath,
20
+ /**
21
+ * The control mirror `path` starts from, when the failure is a mirror's
22
+ * tripwire read after the door; {@link locateCallerDataError} resolves it.
23
+ */
24
+ within?: object | undefined);
25
+ }
26
+ /**
27
+ * Objects a door keeps by identity rather than copying: values the framework built
28
+ * itself (a builder's `$ref` placeholder), or a request envelope's members, each
29
+ * copied by its own door. Never a caller's own object that a later reader reads.
30
+ * Asked about every object, arrays included, before anything else of it is read.
31
+ */
32
+ export type CallerDataKeep = (value: object) => boolean;
33
+ /**
34
+ * Objects a door mirrors by their descriptors rather than copying by value: a plan's
35
+ * `$ref` control objects (see {@link mirrorControlData}). Asked about every object
36
+ * the door does not keep, before anything else of it is read.
37
+ */
38
+ export type CallerDataMirror = (value: object) => boolean;
39
+ /** How a door treats the objects it meets; copying by value unless stated. */
40
+ export type CallerDataPolicy = {
41
+ readonly keep?: CallerDataKeep;
42
+ readonly mirror?: CallerDataMirror;
43
+ };
44
+ /**
45
+ * Places a mirror tripwire's failure in the value the door copied: its path from the
46
+ * copy's root, where `error.path` started from the mirror. A failure that is not a
47
+ * tripwire's, or a mirror the copy does not hold, is returned as it is.
48
+ */
49
+ export declare function locateCallerDataError(error: AvCallerDataError, copy: unknown): AvCallerDataError;
50
+ /**
51
+ * Copies a caller's value into fresh plain data (see the module note), reading the
52
+ * caller's objects exactly once.
53
+ *
54
+ * @throws {@link AvCallerDataError} when a value cannot be read or is not plain data,
55
+ * naming its path from `value`.
56
+ */
57
+ export declare function copyCallerData(value: unknown, policy?: CallerDataPolicy): unknown;
58
+ /** The `V1001` message a door answers a {@link AvCallerDataError} with. */
59
+ export declare function callerDataFailureMessage(kind: CallerDataFailureKind): string;