@kindgi/flow 0.0.0-bootstrap.0 → 0.1.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.
@@ -0,0 +1 @@
1
+ {"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../src/types.ts"],"names":[],"mappings":"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"}
package/dist/types.js ADDED
@@ -0,0 +1,71 @@
1
+ // SPDX-License-Identifier: Apache-2.0
2
+ // Copyright (C) 2026 Kindgi Inc.
3
+ /** The set of operator names recognized by the DSL, exported for tooling. */
4
+ export const OPERATORS = [
5
+ 'eq',
6
+ 'ne',
7
+ 'lt',
8
+ 'lte',
9
+ 'gt',
10
+ 'gte',
11
+ 'in',
12
+ 'notIn',
13
+ 'exists',
14
+ 'notExists',
15
+ 'truthy',
16
+ 'falsy',
17
+ 'and',
18
+ 'or',
19
+ 'not',
20
+ ];
21
+ /**
22
+ * The set of convergence-mode names recognized by the runtime, exported for
23
+ * tooling that needs the closed enum without repeating literals.
24
+ */
25
+ export const CONVERGENCE_MODES = ['all-succeed', 'any-succeed', 'settle-all'];
26
+ /**
27
+ * The set of subgraph convergence-mode names recognized by the runtime,
28
+ * exported for tooling that needs the closed enum without duplicating
29
+ * literals.
30
+ */
31
+ export const SUBGRAPH_CONVERGENCE_MODES = ['success-only', 'settle-all'];
32
+ /**
33
+ * Minimum + maximum values for `EdgePolicy.priority`. Kept as exported
34
+ * constants so downstream tooling (linters, UI editors, docs) can share
35
+ * the same bounds without duplicating literals.
36
+ */
37
+ export const EDGE_POLICY_PRIORITY_MIN = -100;
38
+ export const EDGE_POLICY_PRIORITY_MAX = 100;
39
+ /** The `EdgePolicy.priority` default when the field is unset. */
40
+ export const EDGE_POLICY_PRIORITY_DEFAULT = 0;
41
+ /**
42
+ * Sentinel node ids used by flow edges. `$start` / `$end` are the outer
43
+ * flow's entry/exit. `$loop-start` / `$loop-end` are the body-scope
44
+ * entry/exit inside a loop node.
45
+ *
46
+ * These sentinels are never present in `flow.nodes` or `LoopBody.nodes` —
47
+ * they're virtual, and no handler executes at them.
48
+ */
49
+ export const START_NODE = '$start';
50
+ export const END_NODE = '$end';
51
+ export const LOOP_START_NODE = '$loop-start';
52
+ export const LOOP_END_NODE = '$loop-end';
53
+ /** All sentinel ids. Useful for validators that need to reject them as node ids. */
54
+ export const SENTINEL_IDS = [START_NODE, END_NODE, LOOP_START_NODE, LOOP_END_NODE];
55
+ /** Type guard: is this node a loop node? */
56
+ export function isLoopNode(node) {
57
+ return node.kind === 'loop';
58
+ }
59
+ /** Type guard: is this node a fanout node? */
60
+ export function isFanoutNode(node) {
61
+ return node.kind === 'fanout';
62
+ }
63
+ /** Type guard: is this node a subgraph-invocation node? */
64
+ export function isSubflowNode(node) {
65
+ return node.kind === 'subgraph';
66
+ }
67
+ /** Type guard: is this node a leaf? */
68
+ export function isLeafNode(node) {
69
+ return node.kind !== 'loop' && node.kind !== 'fanout' && node.kind !== 'subgraph';
70
+ }
71
+ //# sourceMappingURL=types.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"types.js","sourceRoot":"","sources":["../src/types.ts"],"names":[],"mappings":"AAAA,sCAAsC;AACtC,iCAAiC;AAiGjC,6EAA6E;AAC7E,MAAM,CAAC,MAAM,SAAS,GAAG;IACvB,IAAI;IACJ,IAAI;IACJ,IAAI;IACJ,KAAK;IACL,IAAI;IACJ,KAAK;IACL,IAAI;IACJ,OAAO;IACP,QAAQ;IACR,WAAW;IACX,QAAQ;IACR,OAAO;IACP,KAAK;IACL,IAAI;IACJ,KAAK;CACG,CAAC;AA+MX;;;GAGG;AACH,MAAM,CAAC,MAAM,iBAAiB,GAAG,CAAC,aAAa,EAAE,aAAa,EAAE,YAAY,CAAU,CAAC;AA2FvF;;;;GAIG;AACH,MAAM,CAAC,MAAM,0BAA0B,GAAG,CAAC,cAAc,EAAE,YAAY,CAAU,CAAC;AAuQlF;;;;GAIG;AACH,MAAM,CAAC,MAAM,wBAAwB,GAAG,CAAC,GAAY,CAAC;AACtD,MAAM,CAAC,MAAM,wBAAwB,GAAG,GAAY,CAAC;AACrD,iEAAiE;AACjE,MAAM,CAAC,MAAM,4BAA4B,GAAG,CAAU,CAAC;AA6HvD;;;;;;;GAOG;AACH,MAAM,CAAC,MAAM,UAAU,GAAG,QAAiB,CAAC;AAC5C,MAAM,CAAC,MAAM,QAAQ,GAAG,MAAe,CAAC;AACxC,MAAM,CAAC,MAAM,eAAe,GAAG,aAAsB,CAAC;AACtD,MAAM,CAAC,MAAM,aAAa,GAAG,WAAoB,CAAC;AAElD,oFAAoF;AACpF,MAAM,CAAC,MAAM,YAAY,GAAG,CAAC,UAAU,EAAE,QAAQ,EAAE,eAAe,EAAE,aAAa,CAAU,CAAC;AAE5F,4CAA4C;AAC5C,MAAM,UAAU,UAAU,CAAC,IAAc;IACvC,OAAO,IAAI,CAAC,IAAI,KAAK,MAAM,CAAC;AAC9B,CAAC;AAED,8CAA8C;AAC9C,MAAM,UAAU,YAAY,CAAC,IAAc;IACzC,OAAO,IAAI,CAAC,IAAI,KAAK,QAAQ,CAAC;AAChC,CAAC;AAED,2DAA2D;AAC3D,MAAM,UAAU,aAAa,CAAC,IAAc;IAC1C,OAAO,IAAI,CAAC,IAAI,KAAK,UAAU,CAAC;AAClC,CAAC;AAED,uCAAuC;AACvC,MAAM,UAAU,UAAU,CAAC,IAAc;IACvC,OAAO,IAAI,CAAC,IAAI,KAAK,MAAM,IAAI,IAAI,CAAC,IAAI,KAAK,QAAQ,IAAI,IAAI,CAAC,IAAI,KAAK,UAAU,CAAC;AACpF,CAAC"}
package/package.json CHANGED
@@ -1,7 +1,54 @@
1
1
  {
2
2
  "name": "@kindgi/flow",
3
- "version": "0.0.0-bootstrap.0",
4
- "description": "Placeholder so a trusted publisher can be attached. Releases are published from https://github.com/kindgi/kindgi-sdk with provenance; use 0.1.0 or later.",
3
+ "version": "0.1.1",
4
+ "description": "Flow model + predicate DSL for Kindgi™. Defines the task-flow shape (nodes, edges, conditional edges, data-flow mappings) executed by the kernel. Pure — no I/O, no database, no runtime. Ships types, a JSON-schema-validated loader (loadFlow / defineFlow), a predicate evaluator and mapping resolver (evaluateExpr / resolveMapping), and the scheduler tick (schedulerTick) the kernel uses to pick the nodes ready for concurrent execution.",
5
5
  "license": "Apache-2.0",
6
- "repository": { "type": "git", "url": "git+https://github.com/kindgi/kindgi-sdk.git" }
7
- }
6
+ "repository": {
7
+ "type": "git",
8
+ "url": "git+https://github.com/kindgi/kindgi-sdk.git",
9
+ "directory": "packages/flow"
10
+ },
11
+ "homepage": "https://github.com/kindgi/kindgi-sdk/tree/main/packages/flow#readme",
12
+ "bugs": {
13
+ "url": "https://github.com/kindgi/kindgi-sdk/issues"
14
+ },
15
+ "type": "module",
16
+ "main": "./dist/index.js",
17
+ "types": "./dist/index.d.ts",
18
+ "exports": {
19
+ ".": {
20
+ "types": "./dist/index.d.ts",
21
+ "import": "./dist/index.js"
22
+ }
23
+ },
24
+ "files": [
25
+ "dist",
26
+ "src",
27
+ "README.md",
28
+ "SPEC.md",
29
+ "type-manifest.json"
30
+ ],
31
+ "dependencies": {
32
+ "@kindgi/schema": "0.1.1",
33
+ "@kindgi/types": "0.1.1"
34
+ },
35
+ "devDependencies": {
36
+ "@kindgi/specs": "0.1.1",
37
+ "@types/node": "^22.10.5",
38
+ "typescript": "^5.7.3",
39
+ "vitest": "^2.1.8"
40
+ },
41
+ "engines": {
42
+ "node": ">=22.0.0"
43
+ },
44
+ "publishConfig": {
45
+ "access": "public",
46
+ "provenance": true
47
+ },
48
+ "scripts": {
49
+ "build": "tsc -p tsconfig.build.json",
50
+ "typecheck": "tsc --noEmit",
51
+ "test": "vitest run",
52
+ "clean": "rm -rf dist *.tsbuildinfo"
53
+ }
54
+ }
package/src/define.ts ADDED
@@ -0,0 +1,44 @@
1
+ // SPDX-License-Identifier: Apache-2.0
2
+ // Copyright (C) 2026 Kindgi Inc.
3
+
4
+ import type { Result, Unbranded } from '@kindgi/types';
5
+
6
+ import type { FlowError } from './errors.js';
7
+ import { loadFlow } from './loader.js';
8
+ import type { Flow } from './types.js';
9
+
10
+ /**
11
+ * The author-facing spec accepted by `defineFlow`: the shape of the runtime
12
+ * `Flow` — an object literal conforming to `flow.schema.json` — with its
13
+ * ids as plain strings. An author writes `id: 'acme.review'`, a node
14
+ * `id: 'parse'`, an edge `from: 'parse'`, with no `as FlowId` / `as NodeId`
15
+ * / `as EdgeId` casts; branded ids still fit. `defineFlow` returns the
16
+ * validated `Flow`, branded, ready for the kernel or a registry.
17
+ */
18
+ export type FlowSpec = Unbranded<Flow>;
19
+
20
+ /**
21
+ * Build a validated `Flow` from a user-supplied definition.
22
+ *
23
+ * Thin wrapper over `loadFlow` — same validation gauntlet, same error
24
+ * surface, same `Result<Flow, FlowError>` envelope. The distinction is
25
+ * ergonomic: `defineFlow` is the author-facing primitive that mirrors
26
+ * `defineTool` / `defineCheck` / `defineAgent`, so pack authors reach for
27
+ * one consistent shape when declaring workspace primitives. `loadFlow`
28
+ * remains the wire-form entry point for JSON coming off disk / network.
29
+ *
30
+ * Validates (fail-fast, in `loadFlow` order):
31
+ * 1. JSON-schema conformance against `flow.schema.json`.
32
+ * 2. Reserved-id / duplicate-id / unknown-node-reference checks.
33
+ * 3. Predicate + edge-policy + loop / fanout / subgraph well-formedness,
34
+ * data-flow mappings and the flow `output.schema`.
35
+ * 4. Start-edge check and cycle detection (outer + every loop body at
36
+ * every nesting level).
37
+ *
38
+ * The returned `Flow` is byte-identical to `loadFlow(spec).value` on
39
+ * success; consumers can treat the two entry points as interchangeable
40
+ * modulo authoring intent.
41
+ */
42
+ export function defineFlow(spec: FlowSpec): Result<Flow, FlowError> {
43
+ return loadFlow(spec);
44
+ }
package/src/errors.ts ADDED
@@ -0,0 +1,306 @@
1
+ // SPDX-License-Identifier: Apache-2.0
2
+ // Copyright (C) 2026 Kindgi Inc.
3
+
4
+ import type { EdgeId, FlowId, NodeId } from '@kindgi/types';
5
+
6
+ /**
7
+ * Every flow error carries a discriminating `code` so callers can pattern
8
+ * match without inspecting messages. Messages are intended for logs and are
9
+ * not part of the API contract.
10
+ */
11
+ export type FlowError =
12
+ | SchemaValidationError
13
+ | DuplicateNodeError
14
+ | DuplicateEdgeError
15
+ | UnknownNodeReferenceError
16
+ | ReservedIdError
17
+ | CycleError
18
+ | InvalidPredicateError
19
+ | InvalidEdgePolicyError
20
+ | MissingStartEdgeError
21
+ | LoopBodyMissingStartError
22
+ | LoopBodyCycleError
23
+ | LoopBodyEdgeReferenceError
24
+ | LoopMaxIterationsError
25
+ | LoopOutputSchemaError
26
+ | LoopVariantMismatchError
27
+ | LoopConcurrencyError
28
+ | InvalidFanoutNodeError
29
+ | InvalidSubflowNodeError
30
+ | InvalidMappingError
31
+ | InvalidFlowOutputError;
32
+
33
+ export interface SchemaValidationError {
34
+ readonly code: 'schema-validation-failed';
35
+ readonly message: string;
36
+ readonly flowId?: FlowId;
37
+ /** Ajv-style path list — one per validation failure. */
38
+ readonly issues: readonly { readonly path: string; readonly message: string }[];
39
+ }
40
+
41
+ export interface DuplicateNodeError {
42
+ readonly code: 'duplicate-node-id';
43
+ readonly message: string;
44
+ readonly flowId: FlowId;
45
+ readonly nodeId: NodeId;
46
+ }
47
+
48
+ export interface DuplicateEdgeError {
49
+ readonly code: 'duplicate-edge-id';
50
+ readonly message: string;
51
+ readonly flowId: FlowId;
52
+ readonly edgeId: EdgeId;
53
+ }
54
+
55
+ export interface UnknownNodeReferenceError {
56
+ readonly code: 'unknown-node-reference';
57
+ readonly message: string;
58
+ readonly flowId: FlowId;
59
+ readonly edgeId: EdgeId;
60
+ readonly endpoint: 'from' | 'to';
61
+ readonly referencedId: string;
62
+ }
63
+
64
+ export interface ReservedIdError {
65
+ readonly code: 'reserved-id';
66
+ readonly message: string;
67
+ readonly flowId: FlowId;
68
+ readonly nodeId: NodeId;
69
+ }
70
+
71
+ export interface CycleError {
72
+ readonly code: 'cycle-detected';
73
+ readonly message: string;
74
+ readonly flowId: FlowId;
75
+ /** Node ids in the cycle, in traversal order. */
76
+ readonly cycle: readonly NodeId[];
77
+ }
78
+
79
+ export interface InvalidPredicateError {
80
+ readonly code: 'invalid-predicate';
81
+ readonly message: string;
82
+ readonly flowId: FlowId;
83
+ readonly edgeId: EdgeId;
84
+ readonly reason: string;
85
+ }
86
+
87
+ /**
88
+ * A `FlowEdge.policy` field is structurally valid JSON-schema-wise but
89
+ * violates one of the semantic rules `loadFlow` enforces — e.g.
90
+ * `retry.maxAttempts` out of the `[1, 10]` band, negative `delayMs`, or
91
+ * `backoff: 'exponential'` without a `maxDelayMs` ceiling.
92
+ *
93
+ * The schema layer catches shape errors (wrong types, unknown fields);
94
+ * this error surfaces the semantic ones the schema can't express.
95
+ */
96
+ export interface InvalidEdgePolicyError {
97
+ readonly code: 'invalid-edge-policy';
98
+ readonly message: string;
99
+ readonly flowId: FlowId;
100
+ readonly edgeId: EdgeId;
101
+ readonly field:
102
+ | 'retry.maxAttempts'
103
+ | 'retry.delayMs'
104
+ | 'retry.backoff'
105
+ | 'retry.maxDelayMs'
106
+ | 'timeoutMs'
107
+ | 'concurrencyKey'
108
+ | 'priority';
109
+ readonly reason: string;
110
+ }
111
+
112
+ export interface MissingStartEdgeError {
113
+ readonly code: 'missing-start-edge';
114
+ readonly message: string;
115
+ readonly flowId: FlowId;
116
+ }
117
+
118
+ /**
119
+ * A loop node's body has no edge originating at `$loop-start`. Analogous to
120
+ * `MissingStartEdgeError` but scoped to a specific loop body.
121
+ */
122
+ export interface LoopBodyMissingStartError {
123
+ readonly code: 'loop-body-missing-start-edge';
124
+ readonly message: string;
125
+ readonly flowId: FlowId;
126
+ readonly loopNodeId: NodeId;
127
+ }
128
+
129
+ /** A cycle was detected inside a loop node's body sub-flow. */
130
+ export interface LoopBodyCycleError {
131
+ readonly code: 'loop-body-cycle-detected';
132
+ readonly message: string;
133
+ readonly flowId: FlowId;
134
+ readonly loopNodeId: NodeId;
135
+ readonly cycle: readonly NodeId[];
136
+ }
137
+
138
+ /**
139
+ * An edge inside a loop body references an endpoint that isn't a known
140
+ * body node or a `$loop-start` / `$loop-end` sentinel.
141
+ */
142
+ export interface LoopBodyEdgeReferenceError {
143
+ readonly code: 'loop-body-unknown-node-reference';
144
+ readonly message: string;
145
+ readonly flowId: FlowId;
146
+ readonly loopNodeId: NodeId;
147
+ readonly edgeId: EdgeId;
148
+ readonly endpoint: 'from' | 'to';
149
+ readonly referencedId: string;
150
+ }
151
+
152
+ /**
153
+ * A loop node's `maxIterations` is out of the allowed range. Checked by
154
+ * `loadFlow` in addition to the schema-level bounds.
155
+ */
156
+ export interface LoopMaxIterationsError {
157
+ readonly code: 'loop-invalid-max-iterations';
158
+ readonly message: string;
159
+ readonly flowId: FlowId;
160
+ readonly loopNodeId: NodeId;
161
+ readonly value: number;
162
+ }
163
+
164
+ /**
165
+ * A loop node's `outputSchema` is missing or is not a valid JSON Schema
166
+ * (draft 2020-12). Every loop declares a typed escape contract; a
167
+ * malformed schema is caught at load time so no execution-time surprise
168
+ * ever surfaces to the caller.
169
+ */
170
+ export interface LoopOutputSchemaError {
171
+ readonly code: 'loop-invalid-output-schema';
172
+ readonly message: string;
173
+ readonly flowId: FlowId;
174
+ readonly loopNodeId: NodeId;
175
+ /** Meta-schema validation issues (Ajv-style path + message). */
176
+ readonly issues: readonly { readonly path: string; readonly message: string }[];
177
+ }
178
+
179
+ /**
180
+ * A loop node declares fields that belong to the wrong variant. Examples:
181
+ * - `loopKind: 'foreach'` with an `exitCondition` present.
182
+ * - `loopKind: 'while'` with an `iterateOver` present.
183
+ * - `loopKind: 'foreach'` missing `iterateOver`.
184
+ * - `loopKind: 'while'` missing `exitCondition`.
185
+ *
186
+ * Enforced at load time so the executor can trust the discriminated union.
187
+ */
188
+ export interface LoopVariantMismatchError {
189
+ readonly code: 'loop-variant-mismatch';
190
+ readonly message: string;
191
+ readonly flowId: FlowId;
192
+ readonly loopNodeId: NodeId;
193
+ readonly loopKind: 'while' | 'foreach';
194
+ readonly problem:
195
+ | 'while-missing-exit-condition'
196
+ | 'while-has-iterate-over'
197
+ | 'while-has-invalid-evaluation-timing'
198
+ | 'while-has-concurrency'
199
+ | 'foreach-missing-iterate-over'
200
+ | 'foreach-has-exit-condition'
201
+ | 'foreach-has-evaluation-timing';
202
+ }
203
+
204
+ /**
205
+ * A foreach loop's `concurrency` field is out of the allowed band. Bounds:
206
+ * - Must be a positive integer.
207
+ * - `1 ≤ concurrency ≤ 32` — the upper cap is a safety limit.
208
+ * - `concurrency ≤ maxIterations` — otherwise pointless.
209
+ *
210
+ * The 32 cap prevents accidents (a stray `concurrency: 1000` spawning a
211
+ * thousand simultaneous handlers). The cap is fixed; adaptive or
212
+ * rate-aware concurrency is not part of this primitive.
213
+ */
214
+ export interface LoopConcurrencyError {
215
+ readonly code: 'loop-invalid-concurrency';
216
+ readonly message: string;
217
+ readonly flowId: FlowId;
218
+ readonly loopNodeId: NodeId;
219
+ readonly value: number;
220
+ readonly reason: 'not-integer' | 'below-minimum' | 'exceeds-max-iterations' | 'exceeds-cap';
221
+ }
222
+
223
+ /**
224
+ * A `subgraph` node is structurally valid JSON-schema-wise but violates
225
+ * one of the semantic rules `loadFlow` enforces — e.g. malformed `flowRef`,
226
+ * non-exact semver, an `inputMapping` value that isn't a valid Operand,
227
+ * an `outputSchema` that fails to compile against the draft-2020-12
228
+ * meta-schema, or an unknown `convergence` mode.
229
+ *
230
+ * `field` narrows the location of the failure so callers can attribute
231
+ * without matching on the message.
232
+ */
233
+ export interface InvalidSubflowNodeError {
234
+ readonly code: 'invalid-subgraph-node';
235
+ readonly message: string;
236
+ readonly flowId: FlowId;
237
+ readonly subgraphNodeId: NodeId;
238
+ readonly field:
239
+ | 'flowRef'
240
+ | 'flowRef.flowId'
241
+ | 'flowRef.version'
242
+ | 'inputMapping'
243
+ | 'output-schema'
244
+ | 'convergence';
245
+ readonly reason: string;
246
+ /** Meta-schema issues, when `field === 'output-schema'`. */
247
+ readonly issues?: readonly { readonly path: string; readonly message: string }[];
248
+ }
249
+
250
+ /**
251
+ * A `fanout` node is structurally valid JSON-schema-wise but violates one
252
+ * of the semantic rules `loadFlow` enforces — e.g. duplicate `branchId`,
253
+ * concurrency out of `[1, branches.length]`, an unknown convergence mode,
254
+ * or a per-branch `outputSchema` that fails to compile against the
255
+ * draft-2020-12 meta-schema.
256
+ *
257
+ * `field` narrows the location of the failure so callers can attribute
258
+ * without matching on the message.
259
+ */
260
+ export interface InvalidFanoutNodeError {
261
+ readonly code: 'invalid-fanout-node';
262
+ readonly message: string;
263
+ readonly flowId: FlowId;
264
+ readonly fanoutNodeId: NodeId;
265
+ readonly field:
266
+ | 'branches'
267
+ | 'branch-id'
268
+ | 'branch-handler'
269
+ | 'branch-output-schema'
270
+ | 'concurrency'
271
+ | 'convergence';
272
+ readonly reason: string;
273
+ /** Branch id at fault, when the failure attribution is per-branch. */
274
+ readonly branchId?: string;
275
+ /** Meta-schema issues, when `field === 'branch-output-schema'`. */
276
+ readonly issues?: readonly { readonly path: string; readonly message: string }[];
277
+ }
278
+
279
+ /**
280
+ * A leaf `inputMapping` or the flow `output.mapping` entry can't be
281
+ * resolved as written (schema-version 1.8.0+): its path names a node the
282
+ * flow doesn't have, maps the node's own output, or uses a loop-only root
283
+ * (`iterationIndex` / `iterationOutput`). A path with an unknown root
284
+ * fails the schema step instead (`schema-validation-failed`).
285
+ */
286
+ export interface InvalidMappingError {
287
+ readonly code: 'invalid-mapping';
288
+ readonly message: string;
289
+ readonly flowId: FlowId;
290
+ /** The leaf node whose `inputMapping` is invalid; absent for the flow's `output`. */
291
+ readonly nodeId?: NodeId;
292
+ /** The mapping key whose operand is invalid. */
293
+ readonly key: string;
294
+ readonly reason: string;
295
+ }
296
+
297
+ /**
298
+ * A flow's `output.schema` is not a valid JSON Schema (draft 2020-12).
299
+ */
300
+ export interface InvalidFlowOutputError {
301
+ readonly code: 'invalid-flow-output';
302
+ readonly message: string;
303
+ readonly flowId: FlowId;
304
+ /** Meta-schema validation issues (Ajv-style path + message). */
305
+ readonly issues: readonly { readonly path: string; readonly message: string }[];
306
+ }