@aventara/core 0.1.0-pilot.0 → 0.1.0-pilot.2

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 (140) hide show
  1. package/README.md +3 -3
  2. package/dist/adapters/adapter-field.d.ts +4 -4
  3. package/dist/adapters/adapter-resource.d.ts +10 -12
  4. package/dist/adapters/adapter.interface.d.ts +20 -10
  5. package/dist/compiler/contract-compiler-diagnostic.d.ts +3 -4
  6. package/dist/compiler/contract.compiler.d.ts +5 -4
  7. package/dist/compiler/contract.compiler.js +0 -132
  8. package/dist/config/config.resolver.d.ts +2 -2
  9. package/dist/config/config.resolver.js +0 -5
  10. package/dist/config/config.validator.d.ts +3 -3
  11. package/dist/config/config.validator.js +0 -8
  12. package/dist/config/define-fields.d.ts +2 -7
  13. package/dist/config/define-fields.js +0 -15
  14. package/dist/config/effective-fields.d.ts +4 -8
  15. package/dist/config/entrypoint.normalizer.d.ts +7 -7
  16. package/dist/config/entrypoint.normalizer.js +0 -22
  17. package/dist/config/framework-behaviors-config.d.ts +6 -6
  18. package/dist/config/framework-config.d.ts +3 -5
  19. package/dist/config/framework-restrictions-config.d.ts +19 -29
  20. package/dist/config/pipeline-config.d.ts +8 -18
  21. package/dist/contracts/capability.d.ts +18 -21
  22. package/dist/contracts/capability.js +0 -75
  23. package/dist/contracts/client-contract-structure.validator.d.ts +15 -22
  24. package/dist/contracts/client-contract-structure.validator.js +0 -27
  25. package/dist/contracts/contract-canonicalizer.js +0 -96
  26. package/dist/contracts/contract-hash.js +0 -2
  27. package/dist/contracts/contract-limits.js +0 -1
  28. package/dist/contracts/contract-lookup.js +0 -10
  29. package/dist/contracts/contract-protocol.js +0 -10
  30. package/dist/contracts/field.d.ts +23 -26
  31. package/dist/contracts/field.js +0 -107
  32. package/dist/contracts/lifecycle-trait.js +0 -5
  33. package/dist/contracts/resource-operations.d.ts +17 -18
  34. package/dist/contracts/resource-operations.js +0 -63
  35. package/dist/contracts/scalar-value-type.d.ts +12 -22
  36. package/dist/contracts/scalar.js +0 -1
  37. package/dist/contracts/wire-scalar-format.d.ts +20 -20
  38. package/dist/contracts/wire-scalar-format.js +0 -26
  39. package/dist/framework/contract-view.d.ts +7 -8
  40. package/dist/framework/framework-construction.error.js +0 -1
  41. package/dist/framework/framework.d.ts +26 -27
  42. package/dist/framework/framework.factory.js +0 -49
  43. package/dist/framework/operation-facade.js +0 -17
  44. package/dist/operations/operation-arguments.d.ts +36 -46
  45. package/dist/operations/operation-boolean-nodes.js +0 -16
  46. package/dist/operations/operation-call.d.ts +4 -9
  47. package/dist/operations/operation-identity.js +0 -1
  48. package/dist/operations/operation-nesting.js +0 -5
  49. package/dist/operations/operation-result.d.ts +4 -4
  50. package/dist/operations/operation-validator-core.d.ts +2 -2
  51. package/dist/operations/operation-validator-core.js +6 -71
  52. package/dist/operations/operation-validator.d.ts +4 -4
  53. package/dist/operations/operation-validator.js +0 -12
  54. package/dist/operations/projection-scope.resolver.d.ts +8 -10
  55. package/dist/operations/projection-scope.resolver.js +0 -35
  56. package/dist/operations/validation-code.d.ts +11 -18
  57. package/dist/operations/validation-code.js +0 -24
  58. package/dist/operations/write-scope.resolver.d.ts +4 -7
  59. package/dist/operations/write-scope.resolver.js +0 -37
  60. package/dist/protocol/absent-route.responder.d.ts +33 -48
  61. package/dist/protocol/absent-route.responder.js +13 -57
  62. package/dist/protocol/av-protocol.d.ts +6 -6
  63. package/dist/protocol/av-protocol.js +0 -10
  64. package/dist/protocol/contract-document.responder.d.ts +15 -18
  65. package/dist/protocol/contract-document.responder.js +0 -33
  66. package/dist/protocol/http-request.decoder.d.ts +55 -61
  67. package/dist/protocol/http-request.decoder.js +0 -62
  68. package/dist/protocol/http-request.reader.d.ts +12 -13
  69. package/dist/protocol/http-request.reader.js +0 -45
  70. package/dist/protocol/http-response.encoder.d.ts +17 -18
  71. package/dist/protocol/http-response.encoder.js +0 -59
  72. package/dist/protocol/http-status.table.d.ts +7 -11
  73. package/dist/protocol/http-status.table.js +1 -15
  74. package/dist/protocol/index.d.ts +5 -5
  75. package/dist/protocol/index.js +0 -9
  76. package/dist/protocol/operation-response.guard.d.ts +12 -19
  77. package/dist/protocol/operation-response.guard.js +0 -29
  78. package/dist/protocol/protocol-failure.d.ts +26 -23
  79. package/dist/protocol/protocol-failure.js +6 -6
  80. package/dist/protocol/protocol-headers.d.ts +30 -27
  81. package/dist/protocol/protocol-headers.js +3 -61
  82. package/dist/protocol/protocol-surface.d.ts +25 -29
  83. package/dist/protocol/protocol-surface.js +0 -19
  84. package/dist/protocol/protocol.binder.d.ts +58 -71
  85. package/dist/protocol/protocol.binder.js +0 -8
  86. package/dist/protocol/protocol.handler.d.ts +28 -32
  87. package/dist/protocol/protocol.handler.js +0 -43
  88. package/dist/runtime/computed-read-runtime.js +0 -29
  89. package/dist/runtime/create-requirement.d.ts +65 -0
  90. package/dist/runtime/create-requirement.js +141 -0
  91. package/dist/runtime/decimal.d.ts +2 -2
  92. package/dist/runtime/decimal.js +0 -8
  93. package/dist/runtime/diagnostics-reporter.d.ts +6 -6
  94. package/dist/runtime/diagnostics-reporter.js +0 -35
  95. package/dist/runtime/error-boundary.d.ts +3 -3
  96. package/dist/runtime/error-boundary.js +2 -167
  97. package/dist/runtime/execution-options.d.ts +4 -4
  98. package/dist/runtime/field-behavior.d.ts +6 -9
  99. package/dist/runtime/framework-error.js +0 -4
  100. package/dist/runtime/mutation-planner.d.ts +5 -6
  101. package/dist/runtime/mutation-planner.js +0 -23
  102. package/dist/runtime/operation-response.d.ts +1 -1
  103. package/dist/runtime/operation-response.js +1 -17
  104. package/dist/runtime/operation-runtime.d.ts +24 -22
  105. package/dist/runtime/operation-runtime.js +18 -52
  106. package/dist/runtime/outcome-mapper.js +0 -22
  107. package/dist/runtime/output-validator.js +0 -1
  108. package/dist/runtime/pipe-output.validator.d.ts +48 -0
  109. package/dist/runtime/pipe-output.validator.js +79 -0
  110. package/dist/runtime/pipeline.d.ts +20 -26
  111. package/dist/runtime/referential-action.d.ts +14 -19
  112. package/dist/runtime/referential-action.js +0 -23
  113. package/dist/runtime/request-id.js +0 -21
  114. package/dist/runtime/scalar-runtime.d.ts +14 -16
  115. package/dist/runtime/scalar-runtime.js +12 -57
  116. package/dist/transactions/deferred-operation.d.ts +9 -14
  117. package/dist/transactions/operation-arguments-encoder.d.ts +0 -1
  118. package/dist/transactions/operation-arguments-encoder.js +0 -14
  119. package/dist/transactions/operation-fingerprint.js +0 -1
  120. package/dist/transactions/transaction-envelope.js +0 -14
  121. package/dist/transactions/transaction-integrity-error.d.ts +10 -11
  122. package/dist/transactions/transaction-integrity-error.js +0 -5
  123. package/dist/transactions/transaction-plan-assembler.d.ts +0 -1
  124. package/dist/transactions/transaction-plan-assembler.js +0 -35
  125. package/dist/transactions/transaction-plan-validator.d.ts +5 -5
  126. package/dist/transactions/transaction-plan-validator.js +0 -63
  127. package/dist/transactions/transaction-reference-resolver.d.ts +12 -13
  128. package/dist/transactions/transaction-reference-resolver.js +0 -16
  129. package/dist/transactions/transaction-reference-validator.js +0 -8
  130. package/dist/transactions/transaction-reference.d.ts +19 -43
  131. package/dist/transactions/transaction-reference.js +0 -11
  132. package/dist/transactions/transaction-request.d.ts +4 -5
  133. package/dist/transactions/transaction-response.d.ts +1 -1
  134. package/dist/transactions/transaction-runtime.d.ts +2 -3
  135. package/dist/transactions/transaction-runtime.js +5 -44
  136. package/dist/transactions/transaction-slot-path-error.d.ts +10 -11
  137. package/dist/transactions/transaction-slot-path-error.js +0 -7
  138. package/dist/transactions/transaction-slot-writer.d.ts +12 -12
  139. package/dist/transactions/transaction-slot-writer.js +0 -34
  140. package/package.json +2 -2
@@ -1,36 +1,14 @@
1
1
  import { requestIdOf } from "../runtime/request-id.js";
2
2
  import { transportFailure } from "./protocol-failure.js";
3
3
  import { adoptedRequestId, normalizeHeaders, protocolIdentityOf, } from "./protocol-headers.js";
4
- /**
5
- * Reading a host's request before any route answers it: the request as a
6
- * value of its declared type, read once; the request id it is answered under
7
- * (Q13); its headers as one spelling (Q7); its identity headers; and the
8
- * route paths the protocol owns (§12.1). Shared by the decoders, the absence
9
- * responder and the contract responder, so each reads a request one way.
10
- */
11
- /** `<entrypoint>/_resources/:resource/:family/:variant` (§12.1). */
12
4
  const OPERATION_ROUTE = /^\/_resources\/([^/]*)\/([^/]*)\/([^/]*)$/;
13
- /** `POST <entrypoint>/_transactions` (§12.1). */
14
5
  export const TRANSACTIONS_ROUTE = "/_transactions";
15
- /** `GET <entrypoint>/_contract` (§12.1, §12.5). */
16
6
  export const CONTRACT_ROUTE = "/_contract";
17
- /** The methods an operation or `/_transactions` route accepts: `POST`, only (§12.2). */
18
7
  export const POST_ONLY = Object.freeze(["POST"]);
19
- /** The methods the contract route accepts: `GET`, only (§12.2). */
20
8
  export const GET_ONLY = Object.freeze(["GET"]);
21
- /**
22
- * Whether a path lies in the protocol's namespace: underscore-prefixed paths
23
- * beneath the entrypoint are reserved for framework facilities; every other
24
- * path is the host's (§12.1).
25
- */
26
9
  export function isProtocolPath(path) {
27
10
  return path.startsWith("/_");
28
11
  }
29
- /**
30
- * The host's value read as a request, or — when it is not an
31
- * `AvProtocolRequest` at all — the `400 A2000` answering it, under a minted
32
- * id (the director, 2026-10-05).
33
- */
34
12
  export function readRequest(received) {
35
13
  const request = wellFormedRequest(received);
36
14
  if (request === undefined) {
@@ -45,10 +23,6 @@ export function readRequest(received) {
45
23
  protocol: protocolIdentityOf(headers),
46
24
  };
47
25
  }
48
- /**
49
- * The three segments of an operation route, each URL-decoded and none empty
50
- * (§12.6 refuses an empty-resource route); `undefined` when it is not one.
51
- */
52
26
  export function operationRouteSegments(path) {
53
27
  const match = OPERATION_ROUTE.exec(path);
54
28
  if (match === null) {
@@ -61,7 +35,6 @@ export function operationRouteSegments(path) {
61
35
  ? { resource, family, variant }
62
36
  : undefined;
63
37
  }
64
- /** One path segment, URL-decoded once; `undefined` when it is not decodable. */
65
38
  function decodeSegment(segment) {
66
39
  try {
67
40
  return decodeURIComponent(segment);
@@ -70,11 +43,6 @@ function decodeSegment(segment) {
70
43
  return undefined;
71
44
  }
72
45
  }
73
- /**
74
- * The answer to a value that is not an `AvProtocolRequest`: `A2000` under a
75
- * freshly minted id — the value's own headers are not believed, so no id is
76
- * adopted from them.
77
- */
78
46
  function malformedRequest() {
79
47
  const requestId = requestIdOf(undefined);
80
48
  return {
@@ -83,20 +51,8 @@ function malformedRequest() {
83
51
  requestId,
84
52
  };
85
53
  }
86
- /**
87
- * The host's request, read ONCE into a value of its declared type, or
88
- * `undefined` when it is not one: not an object, a `method` or `path` that is
89
- * not text, `headers` that are not a record of text or lists of text, or a
90
- * `body` of neither arm (Q11) — raw content that is neither text nor bytes
91
- * has no byte count to measure. Each member is read once, so a getter cannot
92
- * answer one check and lie to the next, and one that throws — like any trap —
93
- * makes the request malformed rather than the decoder throw. A parsed body's
94
- * value is kept as the same object, never read into (§12.3).
95
- */
96
54
  function wellFormedRequest(received) {
97
55
  try {
98
- // `null` and `undefined` throw here; any other non-object has no
99
- // members, so its `method` is not text.
100
56
  const { method, path, headers, body } = received;
101
57
  const copied = headerRecord(headers);
102
58
  const armed = armedBody(body);
@@ -130,7 +86,6 @@ function headerRecord(headers) {
130
86
  return undefined;
131
87
  }
132
88
  }
133
- // `fromEntries` defines each member, so a header named `__proto__` stays data.
134
89
  return Object.fromEntries(copied);
135
90
  }
136
91
  function armedBody(body) {
@@ -7,41 +7,40 @@ import type { TransactionResponse } from "../transactions/transaction-response.j
7
7
  * text, and adds nothing of the framework's.
8
8
  */
9
9
  export type AvProtocolResponse = {
10
- /** `AvProtocol.httpStatus` of the envelope's code (§13.2). */
10
+ /** `AvProtocol.httpStatus` of the envelope's code. */
11
11
  readonly status: number;
12
12
  /**
13
13
  * The headers the framework owns on this response, canonically spelled:
14
- * `Content-Type: application/json` and the `Aventara-Request-Id` it echoes
15
- * (Q13).
14
+ * `Content-Type: application/json` and the `Aventara-Request-Id` it echoes.
16
15
  */
17
16
  readonly headers: Readonly<Record<string, string>>;
18
- /** The JSON text of the envelope (§13.1), its data in wire forms (P1). */
17
+ /** The JSON text of the envelope, its data in wire forms. */
19
18
  readonly body: string;
20
19
  };
21
20
  /**
22
21
  * Where an encoder hands the raw failure behind an `A3003` — the binding's
23
- * diagnostics channel (the director, 2026-10-05) — with the plan step it
24
- * blames, if any. The wire never carries it (Q5).
22
+ * diagnostics channel — with the plan step it blames, if any. The wire never
23
+ * carries it.
25
24
  */
26
25
  export type UnencodableReport = (error: unknown, operation?: number) => void;
27
26
  /**
28
27
  * `protocol.encodeOperation(response, requestId)`: one operation's framework
29
- * response as the HTTP response a host writes. Status is the code's (§13.2);
30
- * `data` is wire-encoded (P1); `requestId` is echoed as `Aventara-Request-Id`
31
- * (Q13) — pass the id the request ran under, which the decoder supplies.
28
+ * response as the HTTP response a host writes. Status is the code's; `data` is
29
+ * wire-encoded; `requestId` is echoed as `Aventara-Request-Id` — pass the id the
30
+ * request ran under, which the decoder supplies.
32
31
  *
33
- * Total: a result it cannot encode — and a response whose code is not
34
- * allocated — answers `A3003` → 500 with the framework's own text, and none of
35
- * the result reaches the body.
32
+ * Total: a result it cannot encode — and a response whose code is not allocated —
33
+ * answers `A3003` → 500 with the framework's own text, and none of the result
34
+ * reaches the body.
36
35
  */
37
36
  export declare function encodeOperationResponse(response: OperationResponse, requestId: string, report?: UnencodableReport): AvProtocolResponse;
38
37
  /**
39
38
  * `protocol.encodeTransaction(response, requestId)`: the same for a plan's
40
- * response (§14). A committed plan is `200 A1009` — even when it created
41
- * something (P3) — with each operation's data wire-encoded in plan order by
42
- * the same walker as {@link encodeOperationResponse}; a rolled-back plan
43
- * answers its failing operation's own status (Q4). A step whose result cannot
44
- * be encoded answers `A3003` → 500 naming that step as `cause.operation`, as
45
- * every internal failure inside a plan does (Q5).
39
+ * response. A committed plan is `200 A1009` — even when it created something —
40
+ * with each operation's data wire-encoded in plan order by the same walker as
41
+ * {@link encodeOperationResponse}; a rolled-back plan answers its failing
42
+ * operation's own status. A step whose result cannot be encoded answers `A3003` →
43
+ * 500 naming that step as `cause.operation`, as every internal failure inside a
44
+ * plan does.
46
45
  */
47
46
  export declare function encodeTransactionResponse(response: TransactionResponse, requestId: string, report?: UnencodableReport): AvProtocolResponse;
@@ -4,16 +4,6 @@ import { SERIALIZATION_FAILURE_MESSAGE } from "../runtime/error-boundary.js";
4
4
  import { operationFailure, } from "../runtime/operation-response.js";
5
5
  import { httpStatus } from "./http-status.table.js";
6
6
  import { headers } from "./protocol-headers.js";
7
- /**
8
- * `protocol.encodeOperation(response, requestId)`: one operation's framework
9
- * response as the HTTP response a host writes. Status is the code's (§13.2);
10
- * `data` is wire-encoded (P1); `requestId` is echoed as `Aventara-Request-Id`
11
- * (Q13) — pass the id the request ran under, which the decoder supplies.
12
- *
13
- * Total: a result it cannot encode — and a response whose code is not
14
- * allocated — answers `A3003` → 500 with the framework's own text, and none of
15
- * the result reaches the body.
16
- */
17
7
  export function encodeOperationResponse(response, requestId, report) {
18
8
  try {
19
9
  return written(response, toWire(response.data, new Set()), requestId);
@@ -23,15 +13,6 @@ export function encodeOperationResponse(response, requestId, report) {
23
13
  return written(serializationFailure(), null, requestId);
24
14
  }
25
15
  }
26
- /**
27
- * `protocol.encodeTransaction(response, requestId)`: the same for a plan's
28
- * response (§14). A committed plan is `200 A1009` — even when it created
29
- * something (P3) — with each operation's data wire-encoded in plan order by
30
- * the same walker as {@link encodeOperationResponse}; a rolled-back plan
31
- * answers its failing operation's own status (Q4). A step whose result cannot
32
- * be encoded answers `A3003` → 500 naming that step as `cause.operation`, as
33
- * every internal failure inside a plan does (Q5).
34
- */
35
16
  export function encodeTransactionResponse(response, requestId, report) {
36
17
  if (response.code !== "A1009") {
37
18
  return encodeOperationResponse(response, requestId, report);
@@ -53,18 +34,12 @@ export function encodeTransactionResponse(response, requestId, report) {
53
34
  return written(serializationFailure(step), null, requestId);
54
35
  }
55
36
  }
56
- /** The one A3003 envelope: the framework's text, plus the step in a plan. */
57
37
  function serializationFailure(operation) {
58
38
  return operationFailure("A3003", {
59
39
  message: SERIALIZATION_FAILURE_MESSAGE,
60
40
  ...(operation === undefined ? {} : { operation }),
61
41
  });
62
42
  }
63
- /**
64
- * Writes an envelope whose data is already in wire form. Throws for a code
65
- * with no status (only an untyped caller can supply one), which every caller
66
- * turns into `A3003`.
67
- */
68
43
  function written(response, wireData, requestId) {
69
44
  const { code, cause } = response;
70
45
  if (!Object.hasOwn(httpStatus, code)) {
@@ -79,37 +54,9 @@ function written(response, wireData, requestId) {
79
54
  body: JSON.stringify({ data: wireData, code, cause }),
80
55
  };
81
56
  }
82
- /**
83
- * What the walker throws for a value with no wire form — never past an
84
- * encoder, which answers `A3003` and hands it to the diagnostics channel, so
85
- * it names the offending value as its `cause` for the developer.
86
- */
87
57
  function unencodable(value) {
88
58
  return new TypeError("A result value has no wire form.", { cause: value });
89
59
  }
90
- /**
91
- * The P1 wire walker: a result's runtime value as the JSON value the wire
92
- * carries. Value-directed, with no Contract read: exactly four runtime classes
93
- * are scalars whose wire form differs from their runtime form (A6), and a
94
- * `json` value is a `JsonValue`, which contains none of them —
95
- *
96
- * - `bigint` → its base-10 string;
97
- * - `Decimal` (core's) → its decimal string (not through `toJSON`, Q16);
98
- * - `Date` → `toISOString()`, which must match the datetime wire grammar — an
99
- * invalid Date, or a year the grammar's four digits cannot spell, has none;
100
- * - `Uint8Array` → canonical base64.
101
- *
102
- * Everything else must already be JSON: `null`, a boolean, a string, a finite
103
- * number, a list, or a plain record (prototype `Object.prototype` or `null`).
104
- * A record member whose value is `undefined` is omitted, as JSON omits it; any
105
- * other value — `undefined` in a list or a hole, a non-finite number, a
106
- * function, a symbol, any other object, a cycle — has no wire form, and the
107
- * walk throws. So does a getter or a proxy that throws; the encoders catch all
108
- * of it.
109
- *
110
- * `ancestors` holds the containers on the current path only, so a shared
111
- * reference is encoded twice, as JSON writes it, while a cycle is refused.
112
- */
113
60
  function toWire(value, ancestors) {
114
61
  switch (typeof value) {
115
62
  case "string":
@@ -163,11 +110,6 @@ function toWireList(list, ancestors) {
163
110
  }
164
111
  return wire;
165
112
  }
166
- /**
167
- * One list element. A hole has no wire form (JSON would write `null`), and is
168
- * never filled from the prototype chain; an `undefined` element has none
169
- * either ({@link toWire}).
170
- */
171
113
  function toWireElement(list, index, ancestors) {
172
114
  if (!Object.hasOwn(list, index)) {
173
115
  throw unencodable(list);
@@ -186,6 +128,5 @@ function toWireRecord(record, ancestors) {
186
128
  members.push([key, toWire(member, ancestors)]);
187
129
  }
188
130
  }
189
- // `fromEntries` defines each member, so an own `__proto__` key stays data.
190
131
  return Object.fromEntries(members);
191
132
  }
@@ -1,18 +1,14 @@
1
1
  import type { OperationCode } from "../runtime/operation-response.js";
2
2
  /**
3
- * `AvProtocol.httpStatus` — the HTTP status each A-code carries (§13.2's
4
- * "default HTTP" column), as passive data.
3
+ * `AvProtocol.httpStatus` — the HTTP status each A-code carries, as passive data.
5
4
  *
6
- * Status is a function of the code alone (N14): §13.2 gives every code exactly
7
- * one status, and its success table's two 201s are exactly `A1002` and `A1003`.
8
- * So this one table serves both encoders — an operation's response and a
9
- * plan's — and a rolled-back plan answers its failing operation's own status
10
- * (Q4). The status is the coarse signal; the A-code is the exact one.
5
+ * So this one table serves both encoders — an operation's response and a plan's —
6
+ * and a rolled-back plan answers its failing operation's own status. The status is
7
+ * the coarse signal; the A-code is the exact one.
11
8
  *
12
- * Total by type: the literal `satisfies` the mapped type over `OperationCode`,
13
- * so a code added to core does not compile until its status is written here.
14
- * Passive (P5): numbers only, frozen, emitted by value where a consumer needs
15
- * it.
9
+ * Total by type: the literal `satisfies` the mapped type over `OperationCode`, so
10
+ * a code added to core does not compile until its status is written here. Passive:
11
+ * numbers only, frozen, emitted by value where a consumer needs it.
16
12
  */
17
13
  export declare const httpStatus: {
18
14
  readonly [C in OperationCode]: number;
@@ -1,18 +1,3 @@
1
- /**
2
- * `AvProtocol.httpStatus` — the HTTP status each A-code carries (§13.2's
3
- * "default HTTP" column), as passive data.
4
- *
5
- * Status is a function of the code alone (N14): §13.2 gives every code exactly
6
- * one status, and its success table's two 201s are exactly `A1002` and `A1003`.
7
- * So this one table serves both encoders — an operation's response and a
8
- * plan's — and a rolled-back plan answers its failing operation's own status
9
- * (Q4). The status is the coarse signal; the A-code is the exact one.
10
- *
11
- * Total by type: the literal `satisfies` the mapped type over `OperationCode`,
12
- * so a code added to core does not compile until its status is written here.
13
- * Passive (P5): numbers only, frozen, emitted by value where a consumer needs
14
- * it.
15
- */
16
1
  export const httpStatus = Object.freeze({
17
2
  A1000: 200,
18
3
  A1001: 200,
@@ -43,6 +28,7 @@ export const httpStatus = Object.freeze({
43
28
  A3001: 500,
44
29
  A3002: 500,
45
30
  A3003: 500,
31
+ A3004: 500,
46
32
  A4000: 401,
47
33
  A4001: 403,
48
34
  A4002: 403,
@@ -1,11 +1,11 @@
1
1
  /**
2
2
  * `@aventara/core/protocol` — the HTTP protocol, as passive data and pure
3
- * functions over core (§Q1). It mounts nothing and imports no HTTP library.
3
+ * functions over core. It mounts nothing and imports no HTTP library.
4
4
  *
5
- * The direction is one-way: this entry may import core's internals, and no
6
- * module of core's execution side imports anything under `protocol/`
7
- * (`protocol-direction.spec.ts`). The main `@aventara/core` entry exports no
8
- * name from here.
5
+ * The direction is one-way: this entry may import core's internals, and no module
6
+ * of core's execution side imports anything under `protocol/`
7
+ * (`protocol-direction.spec.ts`). The main `@aventara/core` entry exports no name
8
+ * from here.
9
9
  */
10
10
  export * as AvProtocol from "./av-protocol.js";
11
11
  export type { AvProtocolRequest } from "./http-request.decoder.js";
@@ -1,10 +1 @@
1
- /**
2
- * `@aventara/core/protocol` — the HTTP protocol, as passive data and pure
3
- * functions over core (§Q1). It mounts nothing and imports no HTTP library.
4
- *
5
- * The direction is one-way: this entry may import core's internals, and no
6
- * module of core's execution side imports anything under `protocol/`
7
- * (`protocol-direction.spec.ts`). The main `@aventara/core` entry exports no
8
- * name from here.
9
- */
10
1
  export * as AvProtocol from "./av-protocol.js";
@@ -1,27 +1,20 @@
1
1
  import { type OperationResponse } from "../runtime/operation-response.js";
2
2
  /**
3
- * `AvProtocol.isOperationResponse` — whether a parsed response body is a
4
- * framework envelope (§13.1), the boundary §13.5 draws: an envelope's A1xxx
5
- * resolves and its every other code is a `FrameworkError`; anything else means
6
- * no envelope arrived, which a client raises as `TransportError`. The HTTP
7
- * status plays no part — a code is read even at an unexpected status.
3
+ * The HTTP status plays no part — a code is read even at an unexpected status.
8
4
  *
9
- * `value` is the body as parsed JSON, or `undefined` when there was no body or
10
- * it was not JSON (neither is an envelope). An envelope here is:
5
+ * `value` is the body as parsed JSON, or `undefined` when there was no body or it
6
+ * was not JSON (neither is an envelope). An envelope here is:
11
7
  *
12
8
  * - an object (not an array) with an own `data` member and an allocated `code`;
13
- * - for an A1xxx code, a `cause` of exactly `null`, and `data` of `null` when
14
- * the code is `A1001`;
15
- * - for every other code, `data` of `null` and a cause: an object whose
16
- * `message` is a string, whose `issues`, if present, is a list of objects each
17
- * with an allocated V-code, a string `message` and, if present, a `path` of
18
- * strings and integers, and whose `operation`, if present, is a non-negative
19
- * integer.
9
+ * - for an A1xxx code, a `cause` of exactly `null`, and `data` of `null` when the
10
+ * code is `A1001`;
11
+ * - for every other code, `data` of `null` and a cause: an object whose `message`
12
+ * is a string, whose `issues`, if present, is a list of objects each with an
13
+ * allocated V-code, a string `message` and, if present, a `path` of strings and
14
+ * integers, and whose `operation`, if present, is a non-negative integer.
20
15
  *
21
- * Members §13.1 does not define are no reason to refuse; a reader drops them.
22
- *
23
- * The generated client's own check (`envelopeOf` in its emitted transport) is
24
- * held to agree with this one on every row of the fixture corpus's family 11
25
- * (R5, `packages/client`), so the two cannot drift apart silently.
16
+ * The generated client's own check (`envelopeOf` in its emitted transport) is held
17
+ * to agree with this one on every row of the fixture corpus's family 11, so the
18
+ * two cannot drift apart silently.
26
19
  */
27
20
  export declare function isOperationResponse(value: unknown): value is OperationResponse;
@@ -1,30 +1,5 @@
1
1
  import { VALIDATION_CODES } from "../operations/validation-code.js";
2
2
  import { OPERATION_CODES, } from "../runtime/operation-response.js";
3
- /**
4
- * `AvProtocol.isOperationResponse` — whether a parsed response body is a
5
- * framework envelope (§13.1), the boundary §13.5 draws: an envelope's A1xxx
6
- * resolves and its every other code is a `FrameworkError`; anything else means
7
- * no envelope arrived, which a client raises as `TransportError`. The HTTP
8
- * status plays no part — a code is read even at an unexpected status.
9
- *
10
- * `value` is the body as parsed JSON, or `undefined` when there was no body or
11
- * it was not JSON (neither is an envelope). An envelope here is:
12
- *
13
- * - an object (not an array) with an own `data` member and an allocated `code`;
14
- * - for an A1xxx code, a `cause` of exactly `null`, and `data` of `null` when
15
- * the code is `A1001`;
16
- * - for every other code, `data` of `null` and a cause: an object whose
17
- * `message` is a string, whose `issues`, if present, is a list of objects each
18
- * with an allocated V-code, a string `message` and, if present, a `path` of
19
- * strings and integers, and whose `operation`, if present, is a non-negative
20
- * integer.
21
- *
22
- * Members §13.1 does not define are no reason to refuse; a reader drops them.
23
- *
24
- * The generated client's own check (`envelopeOf` in its emitted transport) is
25
- * held to agree with this one on every row of the fixture corpus's family 11
26
- * (R5, `packages/client`), so the two cannot drift apart silently.
27
- */
28
3
  export function isOperationResponse(value) {
29
4
  if (!isRecord(value) || !Object.hasOwn(value, "data")) {
30
5
  return false;
@@ -72,10 +47,6 @@ function isValidationIssue(value) {
72
47
  (Array.isArray(path) &&
73
48
  everyElement(path, (segment) => typeof segment === "string" || Number.isInteger(segment))));
74
49
  }
75
- /**
76
- * Every element, holes included (a hole reads as `undefined`, which no member
77
- * test accepts) — unlike `Array.prototype.every`, which skips them.
78
- */
79
50
  function everyElement(list, test) {
80
51
  for (const element of list) {
81
52
  if (!test(element)) {
@@ -1,37 +1,40 @@
1
1
  import { type AvProtocolResponse } from "./http-response.encoder.js";
2
+ import type { IdentityHeaderName } from "./protocol-headers.js";
2
3
  /**
3
- * The four transport codes (§13.2): failures of the HTTP request itself, which
4
- * the protocol answers before any operation exists, so no execution path
5
- * produces them (N4). Module type — not an entry export.
4
+ * The four transport codes: failures of the HTTP request itself, which the
5
+ * protocol answers before any operation exists, so no execution path produces
6
+ * them. Module type — not an entry export.
6
7
  */
7
8
  export type TransportFailureCode = "A2000" | "A2010" | "A2011" | "A2012";
9
+ /**
10
+ * pilot.1 — the `400 A2000` answering a request that did not send an identity
11
+ * header: its message names the missing header or headers, and echoes nothing the
12
+ * request sent — so a developer calling the API by hand learns what to add.
13
+ */
14
+ export declare function identityHeadersMissing(missing: readonly IdentityHeaderName[], requestId: string): AvProtocolResponse;
8
15
  /**
9
16
  * `protocol.failure(code, requestId?)` / `protocol.failure("A2012", requestId,
10
- * allow)` (§5.9; a bound member, ruled 2026-10-05): a transport code as the
11
- * complete framework response — the envelope `{ data: null, code, cause: {
12
- * message } }`, encoded exactly as `protocol.encodeOperation` encodes it, at
13
- * the code's status.
17
+ * allow)`: a transport code as the complete framework response — the envelope `{
18
+ * data: null, code, cause: { message } }`, encoded exactly as
19
+ * `protocol.encodeOperation` encodes it, at the code's status.
14
20
  *
15
- * The decoders produce their transport failures through it. A host that
16
- * parses the body itself (Q11's parsed arm) answers its own parser's failures
17
- * with it — `A2000` for text that is not JSON, `A2010` for a body over the
18
- * limit, `A2011` for another content type.
21
+ * The decoders produce their transport failures through it. A host that parses the
22
+ * body itself answers its own parser's failures with it — `A2000` for text that is
23
+ * not JSON, `A2010` for a body over the limit, `A2011` for another content type.
19
24
  *
20
- * `requestId` is echoed as `Aventara-Request-Id` (Q13): pass the id the
21
- * decoder gave the request when there is one. When there is none — or it is
22
- * empty — core mints one through its one helper (Q10), so a failure is never
23
- * refused or left uncorrelated.
25
+ * `requestId` is echoed as `Aventara-Request-Id`: pass the id the decoder gave the
26
+ * request when there is one. When there is none — or it is empty — core mints one
27
+ * through its one helper, so a failure is never refused or left uncorrelated.
24
28
  *
25
29
  * `allow` belongs to `A2012`, and `A2012` requires it: every 405 carries the
26
- * `Allow` header naming the methods its route DOES accept (RFC 9110 §15.5.6;
27
- * the director, 2026-10-05), joined with `", "` — `[]` is RFC 9110's "no
28
- * method", still a header. `failure` knows no route, so the caller names the
29
- * methods; the decoders pass `["POST"]`.
30
+ * `Allow` header naming the methods its route DOES accept, joined with `", "` —
31
+ * `[]` is RFC 9110's "no method", still a header. `failure` knows no route, so the
32
+ * caller names the methods; the decoders pass `["POST"]`.
30
33
  *
31
- * A code outside the four, `A2012` without `allow`, `allow` with any other
32
- * code, or a method that is not an RFC 9110 token is a programming error that
33
- * the type already refuses; an untyped caller gets a `TypeError`, and no
34
- * envelope or header is invented for it.
34
+ * A code outside the four, `A2012` without `allow`, `allow` with any other code,
35
+ * or a method that is not an RFC 9110 token is a programming error that the type
36
+ * already refuses; an untyped caller gets a `TypeError`, and no envelope or header
37
+ * is invented for it.
35
38
  */
36
39
  export declare function transportFailure(code: "A2012", requestId: string | undefined, allow: readonly string[]): AvProtocolResponse;
37
40
  export declare function transportFailure(code: Exclude<TransportFailureCode, "A2012">, requestId?: string): AvProtocolResponse;
@@ -1,18 +1,18 @@
1
1
  import { operationFailure } from "../runtime/operation-response.js";
2
2
  import { requestIdOf } from "../runtime/request-id.js";
3
3
  import { encodeOperationResponse, } from "./http-response.encoder.js";
4
- /**
5
- * The framework's own text for each transport code. It names the defect and
6
- * never echoes the request (§13.5): no body, no content type, no method, no
7
- * configured limit.
8
- */
9
4
  const TRANSPORT_FAILURE_MESSAGES = Object.freeze({
10
5
  A2000: "The request is malformed and cannot be interpreted.",
11
6
  A2010: "The request body exceeds the maximum request size.",
12
7
  A2011: "The request content type is not supported; send application/json.",
13
8
  A2012: "The HTTP method is not allowed on this framework route.",
14
9
  });
15
- /** An HTTP method as RFC 9110 §9.1 spells one: a `token` (§5.6.2). */
10
+ export function identityHeadersMissing(missing, requestId) {
11
+ const named = missing.length === 1
12
+ ? `The ${missing[0]} header is`
13
+ : `The ${missing.join(" and ")} headers are`;
14
+ return encodeOperationResponse(operationFailure("A2000", { message: `${named} missing.` }), requestIdOf({ requestId }));
15
+ }
16
16
  const METHOD_TOKEN = /^[!#$%&'*+.^_`|~0-9A-Za-z-]+$/;
17
17
  export function transportFailure(code, requestId, allow) {
18
18
  if (!Object.hasOwn(TRANSPORT_FAILURE_MESSAGES, code)) {
@@ -3,19 +3,18 @@ import type { ClientProtocolIdentity } from "../runtime/operation-request.js";
3
3
  * `AvProtocol.headers` — the header names the protocol owns, as passive data.
4
4
  *
5
5
  * - `protocolVersion`, `contractHash`: the two identity headers every
6
- * generated-client resource and transaction request sends (§12.4); the
7
- * `_contract` request needs neither.
8
- * - `requestId`: the correlation header (Q13). A valid one is adopted as the
9
- * request's id, an invalid one ignored, and every framework-produced
10
- * response echoes it.
6
+ * generated-client resource and transaction request sends; the `_contract`
7
+ * request needs neither.
8
+ * - `requestId`: the correlation header. A valid one is adopted as the request's
9
+ * id, an invalid one ignored, and every framework-produced response echoes it.
11
10
  *
12
- * Spelled as the canonical wire text. HTTP header names are case-insensitive
13
- * (§12.4), so a reader matches them without regard to case; these spellings are
14
- * what the framework and the generated client SEND.
11
+ * Spelled as the canonical wire text. HTTP header names are case-insensitive, so a
12
+ * reader matches them without regard to case; these spellings are what the
13
+ * framework and the generated client SEND.
15
14
  *
16
- * Passive data (P5): strings only, frozen, so a consumer — the client generator
17
- * emits it by value into generated source — can neither mutate it nor receive
18
- * anything `JSON.stringify` would drop or reshape.
15
+ * Passive data: strings only, frozen, so a consumer — the client generator emits
16
+ * it by value into generated source — can neither mutate it nor receive anything
17
+ * `JSON.stringify` would drop or reshape.
19
18
  */
20
19
  export declare const headers: Readonly<{
21
20
  readonly protocolVersion: "Aventara-Protocol-Version";
@@ -25,10 +24,9 @@ export declare const headers: Readonly<{
25
24
  /** A request's headers as a host hands them over (`AvProtocolRequest.headers`). */
26
25
  type ReceivedHeaders = Readonly<Record<string, string | readonly string[] | undefined>>;
27
26
  /**
28
- * The request's headers as one spelling (Q7, accepted 2026-10-04): names
29
- * lower-cased (they are case-insensitive, §12.4), a repeated header's values —
30
- * a list, or one name received in several casings — joined with `", "` in the
31
- * order received (RFC 9110 §5.3), and an `undefined` entry or an empty list
27
+ * The request's headers as one spelling: names lower-cased, a repeated header's
28
+ * values — a list, or one name received in several casings — joined with `", "` in
29
+ * the order received (RFC 9110 §5.3), and an `undefined` entry or an empty list
32
30
  * dropped as absent. Values are otherwise as received. This is what a client
33
31
  * request's `transport.headers` carries to the developer's pipelines, and what
34
32
  * every header read below reads.
@@ -43,24 +41,29 @@ export declare function normalizeHeaders(received: ReceivedHeaders): Readonly<Re
43
41
  */
44
42
  export declare function headerValue(normalized: Readonly<Record<string, string>>, name: string): string | undefined;
45
43
  /**
46
- * The identity headers (§12.4) as the `ClientProtocolIdentity` core checks, or
47
- * `undefined` when either is ABSENT — a request without them is malformed
48
- * (`A2000`; the architect, 2026-10-05): it does not say which protocol and
49
- * ClientContract it speaks, so there is nothing to compare.
44
+ * The identity headers as the `ClientProtocolIdentity` core checks, or `undefined`
45
+ * when either is ABSENT — a request without them is malformed: it does not say
46
+ * which protocol and ClientContract it speaks, so there is nothing to compare.
50
47
  *
51
48
  * Present values are read, never judged: whether they match is the Framework
52
49
  * Validation Layer's call (cross-phase invariant 13), made by core's one
53
- * stale-client check. A present version that is not a decimal integer (no
54
- * sign, no leading zero) reads as `NaN`, so it cannot match (`A2006`); a
55
- * present hash is passed as received (`A2005` unless it is the current one).
56
- * Present includes empty: a header sent with no value was still sent.
50
+ * stale-client check. A present version that is not a decimal integer (no sign, no
51
+ * leading zero) reads as `NaN`, so it cannot match (`A2006`); a present hash is
52
+ * passed as received (`A2005` unless it is the current one). Present includes
53
+ * empty: a header sent with no value was still sent.
57
54
  */
58
55
  export declare function protocolIdentityOf(normalized: Readonly<Record<string, string>>): ClientProtocolIdentity | undefined;
59
56
  /**
60
- * Q13 (the architect's, 2026-10-04): the request's `Aventara-Request-Id` when
61
- * it is 1–128 characters of visible ASCII; otherwise `undefined` — the header
62
- * is ignored, never refused, and core mints an id instead. A repeated header
63
- * joins with `", "`, which holds a space, so it is never adopted.
57
+ * The identity headers a request did not send, in the order the framework sends
58
+ * them — what the `A2000` answering it names (pilot.1). Empty exactly when {@link
59
+ * protocolIdentityOf} reads an identity.
60
+ */
61
+ export declare function missingIdentityHeaders(normalized: Readonly<Record<string, string>>): readonly IdentityHeaderName[];
62
+ /** The two identity headers' names, as the framework spells them. */
63
+ export type IdentityHeaderName = (typeof headers)["protocolVersion"] | (typeof headers)["contractHash"];
64
+ /**
65
+ * A repeated header joins with `", "`, which holds a space, so it is never
66
+ * adopted.
64
67
  */
65
68
  export declare function adoptedRequestId(normalized: Readonly<Record<string, string>>): string | undefined;
66
69
  export {};