@hyperscale0/udl 1.0.0-beta.1 → 1.0.0
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.
- package/CHANGELOG.md +78 -25
- package/README.md +37 -99
- package/conformance/README.md +44 -41
- package/conformance/evolution/action-contract.expected.json +10 -0
- package/conformance/evolution/action-contract.live.udl +44 -0
- package/conformance/evolution/action-contract.next.udl +45 -0
- package/conformance/evolution/product-identity.expected.json +10 -0
- package/conformance/evolution/product-identity.live.udl +55 -0
- package/conformance/evolution/product-identity.next.udl +55 -0
- package/conformance/evolution/version-required.expected.json +10 -0
- package/conformance/evolution/version-required.live.udl +55 -0
- package/conformance/evolution/version-required.next.udl +58 -0
- package/conformance/invalid/action-without-transition.expected.json +10 -0
- package/conformance/invalid/{verb-without-transition.udl → action-without-transition.udl} +7 -2
- package/conformance/invalid/agent-description-too-long.expected.json +10 -0
- package/conformance/invalid/agent-description-too-long.udl +57 -0
- package/conformance/invalid/blank-title.expected.json +1 -1
- package/conformance/invalid/blank-title.udl +6 -2
- package/conformance/invalid/composition-dial-duplicate-key.expected.json +10 -0
- package/conformance/invalid/composition-dial-duplicate-key.udl +73 -0
- package/conformance/invalid/depth-budget.expected.json +1 -1
- package/conformance/invalid/duplicate-subject.expected.json +10 -0
- package/conformance/invalid/duplicate-subject.udl +230 -0
- package/conformance/invalid/forged-effects.expected.json +10 -0
- package/conformance/invalid/forged-effects.udl +76 -0
- package/conformance/invalid/format-version.expected.json +1 -1
- package/conformance/invalid/format-version.udl +6 -2
- package/conformance/invalid/instrument-id-not-snake-case.expected.json +10 -0
- package/conformance/invalid/{noun-id-not-snake-case.udl → instrument-id-not-snake-case.udl} +6 -2
- package/conformance/invalid/invalid-aggregate-gate-shape.expected.json +10 -0
- package/conformance/invalid/invalid-aggregate-gate-shape.udl +1819 -0
- package/conformance/invalid/invalid-check-duration.expected.json +10 -0
- package/conformance/invalid/invalid-check-duration.udl +219 -0
- package/conformance/invalid/invalid-dial-anchor.expected.json +10 -0
- package/conformance/invalid/invalid-dial-anchor.udl +219 -0
- package/conformance/invalid/invalid-exception-parent-ref.expected.json +10 -0
- package/conformance/invalid/invalid-exception-parent-ref.udl +2487 -0
- package/conformance/invalid/invalid-exposure-shape.expected.json +10 -0
- package/conformance/invalid/invalid-exposure-shape.udl +1819 -0
- package/conformance/invalid/invalid-remainder.expected.json +10 -0
- package/conformance/invalid/invalid-remainder.udl +220 -0
- package/conformance/invalid/invalid-schema-keyword.expected.json +10 -0
- package/conformance/invalid/invalid-schema-keyword.udl +220 -0
- package/conformance/invalid/invalid-utf8.expected.json +1 -1
- package/conformance/invalid/malformed-json.expected.json +1 -1
- package/conformance/invalid/missing-create-action.expected.json +10 -0
- package/conformance/invalid/{missing-create-verb.udl → missing-create-action.udl} +5 -2
- package/conformance/invalid/missing-exception-amount-field.expected.json +10 -0
- package/conformance/invalid/missing-exception-amount-field.udl +2487 -0
- package/conformance/invalid/missing-exception-contract.expected.json +14 -0
- package/conformance/invalid/missing-exception-contract.udl +2523 -0
- package/conformance/invalid/missing-exception-reason-field.expected.json +10 -0
- package/conformance/invalid/missing-exception-reason-field.udl +2487 -0
- package/conformance/invalid/not-an-object.expected.json +1 -1
- package/conformance/invalid/payout-reconcile-not-a-bank-debit.expected.json +10 -0
- package/conformance/invalid/payout-reconcile-not-a-bank-debit.udl +259 -0
- package/conformance/invalid/quote-freeze-set-incomplete.expected.json +10 -0
- package/conformance/invalid/quote-freeze-set-incomplete.udl +261 -0
- package/conformance/invalid/quote-named-reference-gate.expected.json +10 -0
- package/conformance/invalid/quote-named-reference-gate.udl +50 -0
- package/conformance/invalid/reconcile-named-reference-gate.expected.json +10 -0
- package/conformance/invalid/reconcile-named-reference-gate.udl +50 -0
- package/conformance/invalid/unknown-key.expected.json +1 -1
- package/conformance/invalid/unknown-key.udl +6 -2
- package/conformance/invalid/unknown-reference-gate-field.expected.json +10 -0
- package/conformance/invalid/unknown-reference-gate-field.udl +1819 -0
- package/conformance/invalid/unknown-required-field.expected.json +10 -0
- package/conformance/invalid/unknown-required-field.udl +220 -0
- package/conformance/invalid/unreachable-state.expected.json +2 -2
- package/conformance/invalid/unreachable-state.udl +6 -2
- package/conformance/invalid/wrong-exception-amount-field.expected.json +10 -0
- package/conformance/invalid/wrong-exception-amount-field.udl +2487 -0
- package/conformance/invalid/wrong-exception-reason-field.expected.json +10 -0
- package/conformance/invalid/wrong-exception-reason-field.udl +2487 -0
- package/conformance/valid/agent-description.expected.json +6 -0
- package/conformance/valid/agent-description.udl +66 -0
- package/conformance/valid/cards.expected.json +1 -0
- package/conformance/valid/cards.udl +843 -356
- package/conformance/valid/commerce-escrow.expected.json +1 -0
- package/conformance/valid/commerce-escrow.udl +792 -291
- package/conformance/valid/compiled-crowdfunding.expected.json +6 -0
- package/conformance/valid/compiled-crowdfunding.udl +1843 -0
- package/conformance/valid/compiled-watch-club.expected.json +6 -0
- package/conformance/valid/compiled-watch-club.udl +2486 -0
- package/conformance/valid/complete-contract.expected.json +6 -0
- package/conformance/valid/complete-contract.udl +218 -0
- package/conformance/valid/effect-signatures.expected.json +6 -0
- package/conformance/valid/effect-signatures.udl +75 -0
- package/conformance/valid/hand-edited.expected.json +1 -0
- package/conformance/valid/hand-edited.udl +1 -1
- package/conformance/valid/insured-car-marketplace.expected.json +1 -0
- package/conformance/valid/insured-car-marketplace.udl +534 -315
- package/conformance/valid/insured-travel.expected.json +2 -1
- package/conformance/valid/insured-travel.udl +1489 -641
- package/conformance/valid/minimal.expected.json +1 -0
- package/conformance/valid/minimal.udl +18 -14
- package/conformance/valid/protection.expected.json +1 -0
- package/conformance/valid/protection.udl +719 -304
- package/conformance/valid/string-escaping.expected.json +6 -0
- package/conformance/valid/string-escaping.udl +54 -0
- package/dist/canonical.d.ts +2 -0
- package/dist/canonical.d.ts.map +1 -1
- package/dist/canonical.js +7 -0
- package/dist/canonical.js.map +1 -1
- package/dist/check-profiles.d.ts +57 -0
- package/dist/check-profiles.d.ts.map +1 -0
- package/dist/check-profiles.js +62 -0
- package/dist/check-profiles.js.map +1 -0
- package/dist/cli.js +48 -4
- package/dist/cli.js.map +1 -1
- package/dist/diagnostics.d.ts +168 -0
- package/dist/diagnostics.d.ts.map +1 -0
- package/dist/diagnostics.js +164 -0
- package/dist/diagnostics.js.map +1 -0
- package/dist/effects.d.ts +41 -0
- package/dist/effects.d.ts.map +1 -0
- package/dist/effects.js +110 -0
- package/dist/effects.js.map +1 -0
- package/dist/evolution.d.ts +51 -18
- package/dist/evolution.d.ts.map +1 -1
- package/dist/evolution.js +244 -102
- package/dist/evolution.js.map +1 -1
- package/dist/finance.d.ts +17 -13
- package/dist/finance.d.ts.map +1 -1
- package/dist/finance.js +165 -109
- package/dist/finance.js.map +1 -1
- package/dist/index.d.ts +12 -8
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +8 -5
- package/dist/index.js.map +1 -1
- package/dist/limits.d.ts +2 -2
- package/dist/limits.d.ts.map +1 -1
- package/dist/limits.js +4 -3
- package/dist/limits.js.map +1 -1
- package/dist/parser.d.ts.map +1 -1
- package/dist/parser.js +6 -16
- package/dist/parser.js.map +1 -1
- package/dist/schema.d.ts +2059 -135
- package/dist/schema.d.ts.map +1 -1
- package/dist/schema.js +759 -73
- package/dist/schema.js.map +1 -1
- package/dist/validation.d.ts +22 -9
- package/dist/validation.d.ts.map +1 -1
- package/dist/validation.js +1463 -457
- package/dist/validation.js.map +1 -1
- package/docs/README.md +14 -0
- package/docs/guide/01-a-document.md +37 -0
- package/docs/guide/02-money-steps.md +23 -0
- package/docs/guide/03-laws.md +18 -0
- package/docs/guide/04-fees-and-remainder.md +15 -0
- package/docs/guide/05-checks-updates-dials.md +7 -0
- package/docs/guide/06-effects.md +11 -0
- package/docs/guide/07-evolution.md +11 -0
- package/docs/guide/08-implementing.md +13 -0
- package/docs/llms-full.txt +1241 -0
- package/docs/llms.txt +14 -0
- package/docs/reference/canonical.md +16 -0
- package/docs/reference/clauses.md +986 -0
- package/docs/reference/cli.md +22 -0
- package/docs/reference/diagnostics.md +32 -0
- package/package.json +6 -2
- package/skills/udl/SKILL.md +28 -0
- package/spec/README.md +82 -51
- package/spec/udl.schema.json +1191 -119
- package/src/canonical.ts +11 -0
- package/src/check-profiles.ts +80 -0
- package/src/cli.ts +49 -3
- package/src/diagnostics.ts +221 -0
- package/src/effects.ts +163 -0
- package/src/evolution.ts +375 -125
- package/src/finance.ts +255 -160
- package/src/index.ts +50 -14
- package/src/limits.ts +4 -3
- package/src/parser.ts +15 -18
- package/src/schema.ts +855 -81
- package/src/validation.ts +2666 -560
- package/conformance/invalid/missing-create-verb.expected.json +0 -10
- package/conformance/invalid/noun-id-not-snake-case.expected.json +0 -10
- package/conformance/invalid/verb-without-transition.expected.json +0 -10
package/src/schema.ts
CHANGED
|
@@ -1,5 +1,8 @@
|
|
|
1
1
|
import { z } from "zod";
|
|
2
2
|
|
|
3
|
+
import { udlCheckEvidenceProfiles } from "./check-profiles.js";
|
|
4
|
+
import type { UdlEffectKind } from "./effects.js";
|
|
5
|
+
|
|
3
6
|
export const UDL_FORMAT_VERSION = 1 as const;
|
|
4
7
|
|
|
5
8
|
const snakeCasePattern = /^[a-z][a-z0-9]*(?:_[a-z0-9]+)*$/;
|
|
@@ -11,20 +14,32 @@ const eventNamePattern = /^[a-z][a-z0-9_]*(?:\.[a-z][a-z0-9_]*)+$/;
|
|
|
11
14
|
const udlSnakeCaseSchema = z
|
|
12
15
|
.string()
|
|
13
16
|
.regex(snakeCasePattern, "must be a snake_case identifier");
|
|
14
|
-
const
|
|
17
|
+
const udlActionNameSchema = z
|
|
15
18
|
.string()
|
|
16
|
-
.regex(snakeCasePattern, "must be a snake_case
|
|
19
|
+
.regex(snakeCasePattern, "must be a snake_case action identifier");
|
|
17
20
|
const udlFieldNameSchema = z
|
|
18
21
|
.string()
|
|
19
22
|
.regex(camelCasePattern, "must be a camelCase field name");
|
|
20
23
|
|
|
21
|
-
export const
|
|
24
|
+
export const udlPublicActionSchema = z
|
|
25
|
+
.string()
|
|
26
|
+
.regex(camelCasePattern, "must be a camelCase public action name");
|
|
27
|
+
|
|
28
|
+
export const udlInstrumentActionIdSchema = z
|
|
22
29
|
.string()
|
|
23
|
-
.
|
|
30
|
+
.max(160)
|
|
31
|
+
.regex(
|
|
32
|
+
/^[a-z][a-z0-9_]*\.[a-z][a-z0-9_]*$/,
|
|
33
|
+
"must name an instrument action as instrument_id.action_key",
|
|
34
|
+
);
|
|
24
35
|
|
|
25
36
|
const nonEmptyTextSchema = z
|
|
26
37
|
.string()
|
|
27
38
|
.refine((value) => value.trim().length > 0, "must not be blank");
|
|
39
|
+
// Agent-facing presentation prose. Every MCP tool description an agent reads is
|
|
40
|
+
// this string, so it is capped: a 400-character ceiling keeps a 60-tool surface
|
|
41
|
+
// under the token budget a client spends before it can pick a tool.
|
|
42
|
+
const udlAgentDescriptionSchema = nonEmptyTextSchema.max(400);
|
|
28
43
|
const fieldPathSchema = z
|
|
29
44
|
.string()
|
|
30
45
|
.regex(fieldPathPattern, "must be a dot-separated camelCase field path");
|
|
@@ -37,6 +52,26 @@ const instanceValuePathSchema = z
|
|
|
37
52
|
const jsonObjectSchema = z.record(z.string(), z.json());
|
|
38
53
|
const stringMapSchema = z.record(nonEmptyTextSchema, nonEmptyTextSchema);
|
|
39
54
|
|
|
55
|
+
const providerFamilyIds = [
|
|
56
|
+
"accounts_ledger_first_party",
|
|
57
|
+
"identity_verification",
|
|
58
|
+
"national_identity",
|
|
59
|
+
"credit_bureau",
|
|
60
|
+
"sanctions_screening",
|
|
61
|
+
"enforcement_instrument",
|
|
62
|
+
"credit_servicing",
|
|
63
|
+
"collections_agency",
|
|
64
|
+
"settlement_ingestion",
|
|
65
|
+
"payouts",
|
|
66
|
+
"banking_or_card_issuing",
|
|
67
|
+
"insurance_carrier",
|
|
68
|
+
"insurance_claims_adjuster",
|
|
69
|
+
"air_carrier",
|
|
70
|
+
"lodging_supplier",
|
|
71
|
+
"email_or_notification",
|
|
72
|
+
] as const;
|
|
73
|
+
export const udlProviderFamilyIdSchema = z.enum(providerFamilyIds);
|
|
74
|
+
|
|
40
75
|
const udlDeclaredValuePolicySchema = z.enum(["required", "optional", "none"]);
|
|
41
76
|
|
|
42
77
|
const udlSubjectSchema = z.strictObject({
|
|
@@ -47,10 +82,17 @@ const udlSubjectSchema = z.strictObject({
|
|
|
47
82
|
version: z.number().int().positive(),
|
|
48
83
|
});
|
|
49
84
|
|
|
50
|
-
const
|
|
85
|
+
const udlInstrumentSubjectSchema = z.strictObject({
|
|
86
|
+
extensible: z.boolean().optional(),
|
|
51
87
|
kinds: z.array(udlSnakeCaseSchema).min(1),
|
|
52
88
|
});
|
|
53
89
|
|
|
90
|
+
const udlExampleSchema = z.strictObject({
|
|
91
|
+
input: jsonObjectSchema,
|
|
92
|
+
name: nonEmptyTextSchema,
|
|
93
|
+
output: z.json().optional(),
|
|
94
|
+
});
|
|
95
|
+
|
|
54
96
|
const udlLifecycleTransitionSchema = z.strictObject({
|
|
55
97
|
from: z.array(udlSnakeCaseSchema).min(1),
|
|
56
98
|
to: udlSnakeCaseSchema,
|
|
@@ -59,16 +101,17 @@ const udlLifecycleTransitionSchema = z.strictObject({
|
|
|
59
101
|
const udlLifecycleSchema = z.strictObject({
|
|
60
102
|
initial: udlSnakeCaseSchema,
|
|
61
103
|
states: z.array(udlSnakeCaseSchema).min(1),
|
|
62
|
-
transitions: z.record(
|
|
104
|
+
transitions: z.record(udlActionNameSchema, udlLifecycleTransitionSchema),
|
|
63
105
|
});
|
|
64
106
|
|
|
65
107
|
const udlUpdatePolicySchema = z.strictObject({
|
|
108
|
+
examples: z.array(udlExampleSchema).optional(),
|
|
66
109
|
fields: z.array(udlFieldNameSchema).min(1),
|
|
67
110
|
states: z.array(udlSnakeCaseSchema).min(1),
|
|
68
111
|
});
|
|
69
112
|
|
|
70
113
|
const udlGateSchema = z.strictObject({
|
|
71
|
-
/** Local field key <- referenced instance path; create
|
|
114
|
+
/** Local field key <- referenced instance path; create actions only. */
|
|
72
115
|
bind: z.record(udlFieldNameSchema, fieldPathSchema).optional(),
|
|
73
116
|
field: udlFieldNameSchema,
|
|
74
117
|
/** Local instance path === referenced instance path at admission. */
|
|
@@ -76,7 +119,7 @@ const udlGateSchema = z.strictObject({
|
|
|
76
119
|
/** Opt-in over an optional reference field: absent passes, set is held to the clause. */
|
|
77
120
|
optional: z.literal(true).optional(),
|
|
78
121
|
statuses: z.array(udlSnakeCaseSchema).min(1),
|
|
79
|
-
/** One dependent ever per referenced instance; create
|
|
122
|
+
/** One dependent ever per referenced instance; create actions only. */
|
|
80
123
|
unique: z.literal(true).optional(),
|
|
81
124
|
});
|
|
82
125
|
|
|
@@ -119,18 +162,23 @@ const udlMoveSchema = z.strictObject({
|
|
|
119
162
|
|
|
120
163
|
const udlDueRecurrenceSchema = z.strictObject({
|
|
121
164
|
countField: udlFieldNameSchema.optional(),
|
|
165
|
+
delinquency: z.literal("parent_policy").optional(),
|
|
166
|
+
drainAction: udlActionNameSchema.optional(),
|
|
122
167
|
period: z.union([
|
|
123
168
|
nonEmptyTextSchema,
|
|
124
169
|
z.strictObject({
|
|
125
170
|
calendar: z.enum(["gregorian", "hijri"]),
|
|
171
|
+
monthEnd: z.literal("clamp_to_last_day"),
|
|
126
172
|
months: z.number().int().positive(),
|
|
127
173
|
}),
|
|
128
174
|
]),
|
|
175
|
+
liability: z.literal("one_open").optional(),
|
|
176
|
+
untilAction: udlActionNameSchema.optional(),
|
|
129
177
|
untilField: udlFieldNameSchema.optional(),
|
|
130
178
|
});
|
|
131
179
|
|
|
132
180
|
const udlDueParentStatusSchema = z.strictObject({
|
|
133
|
-
|
|
181
|
+
instrumentId: udlSnakeCaseSchema,
|
|
134
182
|
refField: udlFieldNameSchema,
|
|
135
183
|
statuses: z.array(udlSnakeCaseSchema).min(1),
|
|
136
184
|
});
|
|
@@ -153,23 +201,72 @@ const udlSetsAtSchema = z.strictObject({
|
|
|
153
201
|
offset: nonEmptyTextSchema,
|
|
154
202
|
});
|
|
155
203
|
|
|
156
|
-
const
|
|
204
|
+
const udlQuoteChargeSchema = z.strictObject({
|
|
157
205
|
bps: z.number().int().min(0).max(9_999),
|
|
158
206
|
withinOffset: nonEmptyTextSchema.optional(),
|
|
159
207
|
});
|
|
160
208
|
|
|
161
|
-
|
|
162
|
-
|
|
163
|
-
|
|
164
|
-
|
|
165
|
-
|
|
166
|
-
|
|
167
|
-
|
|
168
|
-
|
|
209
|
+
// A priced, expiring offer. The quoting action splits `baseField` into a charge
|
|
210
|
+
// and a net at its own clock, freezes the fields the price was read from, and
|
|
211
|
+
// stamps an expiry. Only the paired `commit` action may spend the offer, and
|
|
212
|
+
// only while it is unexpired and its frozen fields still hold.
|
|
213
|
+
const udlQuoteShape = {
|
|
214
|
+
/** Date-time whose remaining time picks the charge tier; omit for elapsed age. */
|
|
215
|
+
anchorField: udlFieldNameSchema.optional(),
|
|
216
|
+
baseField: udlFieldNameSchema,
|
|
217
|
+
chargeRef: udlFieldNameSchema,
|
|
218
|
+
charges: z.array(udlQuoteChargeSchema).min(1),
|
|
219
|
+
/** Fixed ISO-8601 duration from the quoting action, or a stored deadline. */
|
|
220
|
+
expires: z.union([
|
|
221
|
+
z.strictObject({ field: udlFieldNameSchema }),
|
|
222
|
+
z.strictObject({ offset: nonEmptyTextSchema }),
|
|
223
|
+
]),
|
|
224
|
+
fixes: z.array(udlFieldNameSchema).min(1),
|
|
225
|
+
netDestinationField: udlFieldNameSchema,
|
|
226
|
+
netRef: udlFieldNameSchema,
|
|
227
|
+
};
|
|
228
|
+
const udlQuoteSchema = z.strictObject(udlQuoteShape);
|
|
229
|
+
|
|
230
|
+
/**
|
|
231
|
+
* Where a quoting action stamps the instant its offer stops being committable.
|
|
232
|
+
* Derived from the author's net ref rather than a fixed name, so two offers on
|
|
233
|
+
* one instrument never share the slot.
|
|
234
|
+
*/
|
|
235
|
+
export function quoteExpiresAtRefKey(quote: {
|
|
236
|
+
readonly netRef: string;
|
|
237
|
+
}): string {
|
|
238
|
+
return `${quote.netRef}ExpiresAt`;
|
|
239
|
+
}
|
|
240
|
+
|
|
241
|
+
/**
|
|
242
|
+
* Where a quoting action stamps the fingerprint of the field values it froze.
|
|
243
|
+
* The committing action recomputes it against the live fields, which is how an
|
|
244
|
+
* offer priced on one set of terms refuses to pay out against another.
|
|
245
|
+
*/
|
|
246
|
+
export function quoteFrozenRefKey(quote: { readonly netRef: string }): string {
|
|
247
|
+
return `${quote.netRef}Frozen`;
|
|
248
|
+
}
|
|
249
|
+
|
|
250
|
+
/**
|
|
251
|
+
* Every ref key one quote seeds: the charge and the net the author named, plus
|
|
252
|
+
* the two the machinery derives to hold the offer itself. One derivation, read
|
|
253
|
+
* by the validator, the compiler, and the runtime alike.
|
|
254
|
+
*/
|
|
255
|
+
export function quoteSeededRefKeys(quote: {
|
|
256
|
+
readonly chargeRef: string;
|
|
257
|
+
readonly netRef: string;
|
|
258
|
+
}): readonly string[] {
|
|
259
|
+
return [
|
|
260
|
+
quote.chargeRef,
|
|
261
|
+
quote.netRef,
|
|
262
|
+
quoteExpiresAtRefKey(quote),
|
|
263
|
+
quoteFrozenRefKey(quote),
|
|
264
|
+
];
|
|
265
|
+
}
|
|
169
266
|
|
|
170
267
|
const udlDecisionSchema = z.strictObject({
|
|
171
|
-
capability:
|
|
172
|
-
deadlineMs: z.number().int().positive(),
|
|
268
|
+
capability: udlProviderFamilyIdSchema,
|
|
269
|
+
deadlineMs: z.number().int().positive().max(15_000),
|
|
173
270
|
// A decision that never came back is not an approval. `approve` would let a
|
|
174
271
|
// document release money because a counterparty went quiet, so the grammar
|
|
175
272
|
// admits only the fail-closed answer. Every published document already
|
|
@@ -178,12 +275,6 @@ const udlDecisionSchema = z.strictObject({
|
|
|
178
275
|
onTimeout: z.literal("decline"),
|
|
179
276
|
});
|
|
180
277
|
|
|
181
|
-
const udlExampleSchema = z.strictObject({
|
|
182
|
-
input: jsonObjectSchema,
|
|
183
|
-
name: nonEmptyTextSchema,
|
|
184
|
-
output: z.json().optional(),
|
|
185
|
-
});
|
|
186
|
-
|
|
187
278
|
const udlAggregateCheckSchema = z.discriminatedUnion("kind", [
|
|
188
279
|
z.strictObject({
|
|
189
280
|
amountField: udlFieldNameSchema,
|
|
@@ -220,7 +311,7 @@ const udlAggregateCheckSchema = z.discriminatedUnion("kind", [
|
|
|
220
311
|
|
|
221
312
|
const udlAggregateConditionSchema = z.strictObject({
|
|
222
313
|
check: udlAggregateCheckSchema,
|
|
223
|
-
|
|
314
|
+
instrumentId: udlSnakeCaseSchema.optional(),
|
|
224
315
|
over: z.enum(["children", "siblings"]),
|
|
225
316
|
refField: udlFieldNameSchema,
|
|
226
317
|
statuses: z.array(udlSnakeCaseSchema).min(1),
|
|
@@ -231,12 +322,12 @@ const udlExposureRequirementSchema = z.strictObject({
|
|
|
231
322
|
anchorField: udlFieldNameSchema,
|
|
232
323
|
capField: udlFieldNameSchema,
|
|
233
324
|
capOnAnchor: z.literal(true).optional(),
|
|
234
|
-
|
|
325
|
+
childInstrumentId: udlSnakeCaseSchema,
|
|
235
326
|
statuses: z.array(udlSnakeCaseSchema).min(1),
|
|
236
327
|
});
|
|
237
328
|
|
|
238
|
-
// The tenant-backend decision port: the
|
|
239
|
-
// party, checked at admission against the
|
|
329
|
+
// The tenant-backend decision port: the action's caller asserts the acting
|
|
330
|
+
// party, checked at admission against the instrument's party bindings for the
|
|
240
331
|
// allowed roles.
|
|
241
332
|
const udlPortSchema = z.strictObject({
|
|
242
333
|
allowedParties: z
|
|
@@ -254,14 +345,61 @@ const udlPayoutSchema = z.strictObject({
|
|
|
254
345
|
speed: z.literal("standard"),
|
|
255
346
|
});
|
|
256
347
|
|
|
257
|
-
|
|
348
|
+
/**
|
|
349
|
+
* One expectation an action asserts about money it cannot see yet: how much,
|
|
350
|
+
* in which currency, which way, and against whose provider-side row. Evidence
|
|
351
|
+
* that lands later either matches under the declared law or the expectation
|
|
352
|
+
* breaks: past the window the kernel raises the declared exception child, binds
|
|
353
|
+
* the unmatched amount and the break reason onto it, and spends the due
|
|
354
|
+
* occurrence. There is no third outcome and no silent wait.
|
|
355
|
+
*/
|
|
356
|
+
const udlReconcileSchema = z.strictObject({
|
|
357
|
+
/** `fields.<name>` or `refs.<name>`: the money this action says will land. */
|
|
358
|
+
amount: instanceValuePathSchema,
|
|
359
|
+
/** Where the matched evidence id lands in refs. */
|
|
258
360
|
capture: udlFieldNameSchema,
|
|
259
|
-
|
|
361
|
+
/** The ref naming the provider-side row the evidence must cite. */
|
|
362
|
+
counterpartyRef: udlFieldNameSchema,
|
|
363
|
+
currencyField: udlFieldNameSchema,
|
|
364
|
+
direction: z.enum(["credit", "debit"]),
|
|
365
|
+
/** Exactly one source. A reconcile never reads two ledgers at once. */
|
|
366
|
+
evidence: z.enum(["movement", "provider_confirmation", "statement_line"]),
|
|
367
|
+
/**
|
|
368
|
+
* Where an expectation that never matched lands. The named child instrument
|
|
369
|
+
* carries the break, and `maxOpen` caps how many of them one instance may
|
|
370
|
+
* hold open at once, the same count measure the aggregate invariants use.
|
|
371
|
+
*/
|
|
372
|
+
exception: z.strictObject({
|
|
373
|
+
amountField: udlFieldNameSchema,
|
|
374
|
+
childInstrumentId: udlSnakeCaseSchema,
|
|
375
|
+
maxOpen: z.number().int().min(1).max(1_000),
|
|
376
|
+
reasonField: udlFieldNameSchema,
|
|
377
|
+
refField: udlFieldNameSchema,
|
|
378
|
+
}),
|
|
379
|
+
/**
|
|
380
|
+
* How a candidate becomes the match. `exact` demands equal minor units,
|
|
381
|
+
* `tolerance` allows a bounded difference, `window` drops the amount test
|
|
382
|
+
* for a source that nets several items into one line.
|
|
383
|
+
*/
|
|
384
|
+
match: z.discriminatedUnion("law", [
|
|
385
|
+
z.strictObject({ law: z.literal("exact") }),
|
|
386
|
+
z.strictObject({
|
|
387
|
+
dial: udlSnakeCaseSchema,
|
|
388
|
+
law: z.literal("tolerance"),
|
|
389
|
+
minorUnits: z.number().int().positive(),
|
|
390
|
+
}),
|
|
391
|
+
z.strictObject({ law: z.literal("window") }),
|
|
392
|
+
]),
|
|
393
|
+
/** Fixed ISO-8601 duration from the expecting action, or a stored deadline. */
|
|
394
|
+
within: z.union([
|
|
395
|
+
z.strictObject({ field: udlFieldNameSchema }),
|
|
396
|
+
z.strictObject({ offset: nonEmptyTextSchema }),
|
|
397
|
+
]),
|
|
260
398
|
});
|
|
261
399
|
|
|
262
400
|
const udlSignedSumSourceSchema = z.strictObject({
|
|
263
401
|
amountField: udlFieldNameSchema,
|
|
264
|
-
|
|
402
|
+
instrumentId: udlSnakeCaseSchema,
|
|
265
403
|
refField: udlFieldNameSchema,
|
|
266
404
|
sign: z.enum(["add", "subtract"]),
|
|
267
405
|
statuses: z.array(udlSnakeCaseSchema).min(1),
|
|
@@ -287,9 +425,98 @@ const udlDistributeSchema = z.strictObject({
|
|
|
287
425
|
weightField: udlFieldNameSchema,
|
|
288
426
|
});
|
|
289
427
|
|
|
428
|
+
const udlRemainderCollectedSchema = z.strictObject({
|
|
429
|
+
amountField: udlFieldNameSchema,
|
|
430
|
+
instrumentId: udlSnakeCaseSchema,
|
|
431
|
+
path: z.literal("refs").optional(),
|
|
432
|
+
refField: udlFieldNameSchema,
|
|
433
|
+
statuses: z.array(udlSnakeCaseSchema).min(1),
|
|
434
|
+
});
|
|
435
|
+
|
|
436
|
+
const udlRemainderSchema = z.strictObject({
|
|
437
|
+
accumulateRef: udlFieldNameSchema.optional(),
|
|
438
|
+
amountRef: udlFieldNameSchema,
|
|
439
|
+
collected: z.array(udlRemainderCollectedSchema).optional(),
|
|
440
|
+
inputKey: udlFieldNameSchema.optional(),
|
|
441
|
+
onZero: z.enum(["refuse", "skip_steps"]),
|
|
442
|
+
totalPath: instanceValuePathSchema,
|
|
443
|
+
});
|
|
444
|
+
|
|
445
|
+
type UdlCheckRequirementShape = {
|
|
446
|
+
checkKind: string;
|
|
447
|
+
family: z.infer<typeof udlProviderFamilyIdSchema>;
|
|
448
|
+
maxAge?: string;
|
|
449
|
+
statuses: string[];
|
|
450
|
+
subjectField: string;
|
|
451
|
+
};
|
|
452
|
+
|
|
453
|
+
const udlCheckRequirementVariants = udlCheckEvidenceProfiles.map((profile) =>
|
|
454
|
+
z.strictObject({
|
|
455
|
+
checkKind: z.literal(profile.checkKind),
|
|
456
|
+
family: z.literal(profile.family),
|
|
457
|
+
maxAge: nonEmptyTextSchema.optional(),
|
|
458
|
+
statuses: z.array(z.enum(profile.statuses)).min(1),
|
|
459
|
+
subjectField: udlFieldNameSchema,
|
|
460
|
+
}),
|
|
461
|
+
) as unknown as readonly [
|
|
462
|
+
z.ZodType<UdlCheckRequirementShape>,
|
|
463
|
+
z.ZodType<UdlCheckRequirementShape>,
|
|
464
|
+
...z.ZodType<UdlCheckRequirementShape>[],
|
|
465
|
+
];
|
|
466
|
+
|
|
467
|
+
const udlCheckRequirementSchema = z.union(udlCheckRequirementVariants);
|
|
468
|
+
|
|
469
|
+
const udlDialSchema = z.discriminatedUnion("kind", [
|
|
470
|
+
z.strictObject({
|
|
471
|
+
field: udlFieldNameSchema,
|
|
472
|
+
key: udlSnakeCaseSchema,
|
|
473
|
+
kind: z.literal("window"),
|
|
474
|
+
maxOffset: nonEmptyTextSchema.optional(),
|
|
475
|
+
minOffset: nonEmptyTextSchema.optional(),
|
|
476
|
+
summary: nonEmptyTextSchema,
|
|
477
|
+
title: nonEmptyTextSchema,
|
|
478
|
+
}),
|
|
479
|
+
z.strictObject({
|
|
480
|
+
action: udlActionNameSchema,
|
|
481
|
+
key: udlSnakeCaseSchema,
|
|
482
|
+
kind: z.literal("decision_deadline_ms"),
|
|
483
|
+
maxMs: z.number().int().positive().max(15_000).optional(),
|
|
484
|
+
minMs: z.number().int().positive().max(15_000).optional(),
|
|
485
|
+
summary: nonEmptyTextSchema,
|
|
486
|
+
title: nonEmptyTextSchema,
|
|
487
|
+
}),
|
|
488
|
+
z.strictObject({
|
|
489
|
+
key: udlSnakeCaseSchema,
|
|
490
|
+
kind: z.literal("reconcile_tolerance"),
|
|
491
|
+
/** Ceiling on the minor units any reconcile may forgive under this dial. */
|
|
492
|
+
maxMinorUnits: z.number().int().positive().max(1_000_000),
|
|
493
|
+
summary: nonEmptyTextSchema,
|
|
494
|
+
title: nonEmptyTextSchema,
|
|
495
|
+
}),
|
|
496
|
+
z.strictObject({
|
|
497
|
+
key: udlSnakeCaseSchema,
|
|
498
|
+
kind: z.literal("unwind_penalty"),
|
|
499
|
+
summary: nonEmptyTextSchema,
|
|
500
|
+
title: nonEmptyTextSchema,
|
|
501
|
+
}),
|
|
502
|
+
]);
|
|
503
|
+
|
|
290
504
|
// A same-instance conservation law: the piece fields (money, minor units)
|
|
291
505
|
// must sum exactly to the total field; admission refuses a create whose
|
|
292
506
|
// pieces diverge.
|
|
507
|
+
// A composition-level dial. Instrument dials tune one instrument's frozen slots;
|
|
508
|
+
// this one is a property of the whole product, so it hangs off the document.
|
|
509
|
+
// `confirmation_threshold` carries minor units of the kernel currency: a
|
|
510
|
+
// money-moving tool call whose declared money inputs sum below the configured
|
|
511
|
+
// value skips the explicit confirmation argument.
|
|
512
|
+
const udlCompositionDialSchema = z.strictObject({
|
|
513
|
+
key: udlSnakeCaseSchema,
|
|
514
|
+
kind: z.literal("confirmation_threshold"),
|
|
515
|
+
maxMinor: z.number().int().positive().max(1_000_000_000_000).optional(),
|
|
516
|
+
summary: nonEmptyTextSchema,
|
|
517
|
+
title: nonEmptyTextSchema,
|
|
518
|
+
});
|
|
519
|
+
|
|
293
520
|
const udlPartitionSchema = z.strictObject({
|
|
294
521
|
pieceFields: z.array(udlFieldNameSchema).min(2),
|
|
295
522
|
totalField: udlFieldNameSchema,
|
|
@@ -305,38 +532,117 @@ const udlDerivedAmountSchema = z.strictObject({
|
|
|
305
532
|
sourceField: udlFieldNameSchema,
|
|
306
533
|
});
|
|
307
534
|
|
|
308
|
-
const
|
|
535
|
+
const udlFeeLeafRuleSchema = z.discriminatedUnion("kind", [
|
|
536
|
+
z.strictObject({
|
|
537
|
+
bps: z.number().int().min(1).max(9_999),
|
|
538
|
+
kind: z.literal("bps"),
|
|
539
|
+
}),
|
|
540
|
+
z.strictObject({
|
|
541
|
+
currencyField: udlFieldNameSchema,
|
|
542
|
+
field: udlFieldNameSchema,
|
|
543
|
+
kind: z.literal("exact"),
|
|
544
|
+
}),
|
|
545
|
+
]);
|
|
546
|
+
|
|
547
|
+
const nonNegativeDecimalIntegerSchema = z
|
|
548
|
+
.string()
|
|
549
|
+
.regex(/^(0|[1-9][0-9]*)$/, "must be a nonnegative decimal integer");
|
|
550
|
+
|
|
551
|
+
const udlFeeRuleSchema = z.strictObject({
|
|
552
|
+
amountField: udlFieldNameSchema,
|
|
553
|
+
baseField: udlFieldNameSchema,
|
|
554
|
+
bearerField: udlFieldNameSchema,
|
|
555
|
+
position: z.enum(["carved", "on_top"]),
|
|
556
|
+
rule: z.discriminatedUnion("kind", [
|
|
557
|
+
...udlFeeLeafRuleSchema.options,
|
|
558
|
+
z.strictObject({
|
|
559
|
+
kind: z.literal("tiered"),
|
|
560
|
+
tiers: z
|
|
561
|
+
.array(
|
|
562
|
+
z.strictObject({
|
|
563
|
+
fromInclusive: nonNegativeDecimalIntegerSchema,
|
|
564
|
+
rule: udlFeeLeafRuleSchema,
|
|
565
|
+
toExclusive: nonNegativeDecimalIntegerSchema.optional(),
|
|
566
|
+
}),
|
|
567
|
+
)
|
|
568
|
+
.min(1)
|
|
569
|
+
.max(16),
|
|
570
|
+
}),
|
|
571
|
+
]),
|
|
572
|
+
});
|
|
573
|
+
|
|
574
|
+
const udlDecidedAmountSchema = z.strictObject({
|
|
575
|
+
boundField: udlFieldNameSchema,
|
|
576
|
+
field: udlFieldNameSchema,
|
|
577
|
+
remainderAction: udlActionNameSchema,
|
|
578
|
+
});
|
|
579
|
+
|
|
580
|
+
const udlEffectRowSchema = z.strictObject({
|
|
581
|
+
signature: nonEmptyTextSchema,
|
|
582
|
+
source: nonEmptyTextSchema,
|
|
583
|
+
});
|
|
584
|
+
|
|
585
|
+
const udlNotifyEffectSchema = z.strictObject({
|
|
586
|
+
channel: udlSnakeCaseSchema,
|
|
587
|
+
role: udlSnakeCaseSchema,
|
|
588
|
+
signature: nonEmptyTextSchema,
|
|
589
|
+
source: nonEmptyTextSchema,
|
|
590
|
+
});
|
|
591
|
+
|
|
592
|
+
const udlEffectsShape = {
|
|
593
|
+
decides: z.array(udlEffectRowSchema).min(1).optional(),
|
|
594
|
+
holds: z.array(udlEffectRowSchema).min(1).optional(),
|
|
595
|
+
moves: z.array(udlEffectRowSchema).min(1).optional(),
|
|
596
|
+
notifies: z.array(udlNotifyEffectSchema).min(1).optional(),
|
|
597
|
+
reads: z.array(udlEffectRowSchema).min(1).optional(),
|
|
598
|
+
schedules: z.array(udlEffectRowSchema).min(1).optional(),
|
|
599
|
+
} satisfies Record<UdlEffectKind, z.ZodType>;
|
|
600
|
+
const udlEffectsSchema = z.strictObject(udlEffectsShape);
|
|
601
|
+
|
|
602
|
+
const udlActionShape = {
|
|
603
|
+
agentDescription: udlAgentDescriptionSchema.optional(),
|
|
309
604
|
captureInput: z.record(udlFieldNameSchema, udlFieldNameSchema).optional(),
|
|
605
|
+
/** Names the quoting action whose offer this action spends. */
|
|
606
|
+
commit: udlActionNameSchema.optional(),
|
|
607
|
+
decidedAmount: udlDecidedAmountSchema.optional(),
|
|
310
608
|
deadline: udlDeadlineSchema.optional(),
|
|
311
609
|
decision: udlDecisionSchema.optional(),
|
|
312
610
|
distribute: udlDistributeSchema.optional(),
|
|
313
611
|
description: nonEmptyTextSchema.optional(),
|
|
314
612
|
due: udlDueSchema.optional(),
|
|
315
613
|
earnable: z.boolean().optional(),
|
|
614
|
+
effects: udlEffectsSchema.optional(),
|
|
316
615
|
eventName: z.string().regex(eventNamePattern).optional(),
|
|
317
616
|
examples: z.array(udlExampleSchema).min(1).optional(),
|
|
318
617
|
input: jsonObjectSchema.optional(),
|
|
319
618
|
moves: z.array(udlMoveSchema).default([]),
|
|
320
619
|
payout: udlPayoutSchema.optional(),
|
|
321
620
|
port: udlPortSchema.optional(),
|
|
322
|
-
|
|
621
|
+
quote: udlQuoteSchema.optional(),
|
|
622
|
+
publicAction: udlPublicActionSchema
|
|
323
623
|
.optional()
|
|
324
624
|
.describe(
|
|
325
|
-
"Author-approved public
|
|
625
|
+
"Author-approved public action name; the containing action key remains the lifecycle and execution identity",
|
|
326
626
|
),
|
|
627
|
+
principal: z.literal("user_session").optional(),
|
|
628
|
+
reconcile: z.array(udlReconcileSchema).min(1).optional(),
|
|
629
|
+
remainder: udlRemainderSchema.optional(),
|
|
327
630
|
requiresAggregate: z.array(udlAggregateConditionSchema).min(1).optional(),
|
|
631
|
+
requiresChecks: z.array(udlCheckRequirementSchema).optional(),
|
|
328
632
|
requiresDrainedAccount: z.strictObject({ path: fieldPathSchema }).optional(),
|
|
329
633
|
requiresExposure: z.array(udlExposureRequirementSchema).min(1).optional(),
|
|
330
634
|
requiresRefs: z.array(udlGateSchema).min(1).optional(),
|
|
331
|
-
|
|
635
|
+
sandboxFailurePoint: z.enum(["funding", "release"]).optional(),
|
|
332
636
|
setsAt: udlSetsAtSchema.optional(),
|
|
333
637
|
signedSum: udlSignedSumSchema.optional(),
|
|
334
638
|
steps: z.array(udlStepSchema),
|
|
335
639
|
summary: nonEmptyTextSchema,
|
|
336
|
-
|
|
640
|
+
updates: z.array(udlFieldNameSchema).min(1).optional(),
|
|
641
|
+
};
|
|
642
|
+
const udlActionSchema = z.strictObject(udlActionShape);
|
|
337
643
|
|
|
338
644
|
const udlAggregateBaseShape = {
|
|
339
|
-
|
|
645
|
+
childInstrumentId: udlSnakeCaseSchema,
|
|
340
646
|
childRefField: udlFieldNameSchema,
|
|
341
647
|
childStatuses: z.array(udlSnakeCaseSchema).min(1),
|
|
342
648
|
parentField: udlFieldNameSchema,
|
|
@@ -362,18 +668,25 @@ const udlAggregateSchema = z.union([
|
|
|
362
668
|
}),
|
|
363
669
|
]);
|
|
364
670
|
|
|
365
|
-
const
|
|
671
|
+
const udlInstrumentShape = {
|
|
672
|
+
actionOrder: z.array(udlActionNameSchema).min(1),
|
|
673
|
+
agentDescription: udlAgentDescriptionSchema.optional(),
|
|
366
674
|
aggregateInvariants: z.array(udlAggregateSchema).min(1).optional(),
|
|
367
|
-
|
|
675
|
+
callerParkedStates: z
|
|
676
|
+
.record(udlSnakeCaseSchema, nonEmptyTextSchema)
|
|
677
|
+
.optional(),
|
|
368
678
|
description: nonEmptyTextSchema.optional(),
|
|
679
|
+
dials: z.array(udlDialSchema).optional(),
|
|
369
680
|
distinctParties: z.literal(true).optional(),
|
|
370
681
|
derivedAmounts: z.array(udlDerivedAmountSchema).min(1).max(4).optional(),
|
|
682
|
+
feeRules: z.array(udlFeeRuleSchema).min(1).max(4).optional(),
|
|
371
683
|
fields: z.record(udlFieldNameSchema, jsonObjectSchema),
|
|
372
684
|
id: udlSnakeCaseSchema,
|
|
373
685
|
idPrefix: z
|
|
374
686
|
.string()
|
|
375
687
|
.regex(idPrefixPattern, "must contain 2 to 8 lowercase letters"),
|
|
376
688
|
lifecycle: udlLifecycleSchema,
|
|
689
|
+
nav: z.array(nonEmptyTextSchema).min(1).optional(),
|
|
377
690
|
parties: z
|
|
378
691
|
.strictObject({
|
|
379
692
|
beneficiary: udlFieldNameSchema.optional(),
|
|
@@ -383,16 +696,462 @@ const udlNounSchema = z.strictObject({
|
|
|
383
696
|
.optional(),
|
|
384
697
|
partitions: z.array(udlPartitionSchema).min(1).optional(),
|
|
385
698
|
required: z.array(udlFieldNameSchema),
|
|
386
|
-
subject:
|
|
699
|
+
subject: udlInstrumentSubjectSchema.optional(),
|
|
387
700
|
summary: nonEmptyTextSchema,
|
|
701
|
+
surfaceVisibility: z.enum(["internal", "public", "system"]).optional(),
|
|
702
|
+
templateId: udlSnakeCaseSchema.optional(),
|
|
388
703
|
title: nonEmptyTextSchema,
|
|
389
|
-
unwind: udlUnwindSchema.optional(),
|
|
390
704
|
update: udlUpdatePolicySchema.optional(),
|
|
391
|
-
|
|
392
|
-
}
|
|
705
|
+
actions: z.record(udlActionNameSchema, udlActionSchema),
|
|
706
|
+
};
|
|
707
|
+
const udlInstrumentSchema = z.strictObject(udlInstrumentShape);
|
|
708
|
+
|
|
709
|
+
type UdlActionClauseTarget = keyof typeof udlActionShape;
|
|
710
|
+
type UdlInstrumentClauseTarget = keyof typeof udlInstrumentShape;
|
|
711
|
+
type UdlActionNestedClauseTarget = `effects.${keyof typeof udlEffectsShape}`;
|
|
712
|
+
|
|
713
|
+
export type UdlClauseCardinality = "one" | "many";
|
|
714
|
+
|
|
715
|
+
export interface UdlClauseEffect {
|
|
716
|
+
readonly kind: UdlEffectKind;
|
|
717
|
+
readonly per: "clause" | "element";
|
|
718
|
+
readonly signature:
|
|
719
|
+
| { readonly fixed: string }
|
|
720
|
+
| { readonly fromField: string }
|
|
721
|
+
| { readonly movementClass: true };
|
|
722
|
+
}
|
|
723
|
+
|
|
724
|
+
interface UdlClauseVocabularyMetadata {
|
|
725
|
+
readonly cardinality?: UdlClauseCardinality;
|
|
726
|
+
readonly effects?: readonly UdlClauseEffect[];
|
|
727
|
+
readonly linearOutputs?: readonly string[];
|
|
728
|
+
readonly linearSink?: true;
|
|
729
|
+
readonly spelling: string;
|
|
730
|
+
}
|
|
731
|
+
|
|
732
|
+
export type UdlClauseVocabularyEntry = UdlClauseVocabularyMetadata &
|
|
733
|
+
(
|
|
734
|
+
| {
|
|
735
|
+
readonly scope: "action";
|
|
736
|
+
readonly target: UdlActionClauseTarget | UdlActionNestedClauseTarget;
|
|
737
|
+
}
|
|
738
|
+
| {
|
|
739
|
+
readonly scope: "instrument";
|
|
740
|
+
readonly target: UdlInstrumentClauseTarget;
|
|
741
|
+
}
|
|
742
|
+
);
|
|
743
|
+
|
|
744
|
+
export const udlClauseVocabulary = [
|
|
745
|
+
{
|
|
746
|
+
cardinality: "one",
|
|
747
|
+
scope: "action",
|
|
748
|
+
spelling: "agent description",
|
|
749
|
+
target: "agentDescription",
|
|
750
|
+
},
|
|
751
|
+
{
|
|
752
|
+
cardinality: "one",
|
|
753
|
+
scope: "action",
|
|
754
|
+
spelling: "capture input",
|
|
755
|
+
target: "captureInput",
|
|
756
|
+
},
|
|
757
|
+
{
|
|
758
|
+
cardinality: "one",
|
|
759
|
+
// The committing action consumes the quote through its priced moves.
|
|
760
|
+
// An extra row here would bill the same movement twice.
|
|
761
|
+
effects: [],
|
|
762
|
+
scope: "action",
|
|
763
|
+
spelling: "commit",
|
|
764
|
+
target: "commit",
|
|
765
|
+
},
|
|
766
|
+
{
|
|
767
|
+
cardinality: "one",
|
|
768
|
+
effects: [
|
|
769
|
+
{
|
|
770
|
+
kind: "holds",
|
|
771
|
+
per: "clause",
|
|
772
|
+
signature: { fixed: "quote" },
|
|
773
|
+
},
|
|
774
|
+
{
|
|
775
|
+
kind: "schedules",
|
|
776
|
+
per: "clause",
|
|
777
|
+
signature: { fixed: "expiry" },
|
|
778
|
+
},
|
|
779
|
+
],
|
|
780
|
+
linearOutputs: ["netRef"],
|
|
781
|
+
scope: "action",
|
|
782
|
+
spelling: "quote",
|
|
783
|
+
target: "quote",
|
|
784
|
+
},
|
|
785
|
+
{
|
|
786
|
+
cardinality: "one",
|
|
787
|
+
linearOutputs: ["field"],
|
|
788
|
+
scope: "action",
|
|
789
|
+
spelling: "decided amount",
|
|
790
|
+
target: "decidedAmount",
|
|
791
|
+
},
|
|
792
|
+
{
|
|
793
|
+
cardinality: "one",
|
|
794
|
+
effects: [
|
|
795
|
+
{
|
|
796
|
+
kind: "schedules",
|
|
797
|
+
per: "clause",
|
|
798
|
+
signature: { fixed: "deadline" },
|
|
799
|
+
},
|
|
800
|
+
],
|
|
801
|
+
scope: "action",
|
|
802
|
+
spelling: "deadline",
|
|
803
|
+
target: "deadline",
|
|
804
|
+
},
|
|
805
|
+
{
|
|
806
|
+
cardinality: "one",
|
|
807
|
+
effects: [
|
|
808
|
+
{
|
|
809
|
+
kind: "decides",
|
|
810
|
+
per: "clause",
|
|
811
|
+
signature: { fromField: "capability" },
|
|
812
|
+
},
|
|
813
|
+
],
|
|
814
|
+
scope: "action",
|
|
815
|
+
spelling: "decision",
|
|
816
|
+
target: "decision",
|
|
817
|
+
},
|
|
818
|
+
{
|
|
819
|
+
cardinality: "one",
|
|
820
|
+
linearOutputs: ["amountRef"],
|
|
821
|
+
scope: "action",
|
|
822
|
+
spelling: "computes distribute",
|
|
823
|
+
target: "distribute",
|
|
824
|
+
},
|
|
825
|
+
{
|
|
826
|
+
cardinality: "one",
|
|
827
|
+
scope: "action",
|
|
828
|
+
spelling: "description",
|
|
829
|
+
target: "description",
|
|
830
|
+
},
|
|
831
|
+
{
|
|
832
|
+
cardinality: "one",
|
|
833
|
+
effects: [
|
|
834
|
+
{
|
|
835
|
+
kind: "schedules",
|
|
836
|
+
per: "clause",
|
|
837
|
+
signature: { fixed: "due" },
|
|
838
|
+
},
|
|
839
|
+
],
|
|
840
|
+
scope: "action",
|
|
841
|
+
spelling: "due",
|
|
842
|
+
target: "due",
|
|
843
|
+
},
|
|
844
|
+
{
|
|
845
|
+
cardinality: "one",
|
|
846
|
+
scope: "action",
|
|
847
|
+
spelling: "earnable",
|
|
848
|
+
target: "earnable",
|
|
849
|
+
},
|
|
850
|
+
{
|
|
851
|
+
cardinality: "one",
|
|
852
|
+
scope: "action",
|
|
853
|
+
spelling: "event name",
|
|
854
|
+
target: "eventName",
|
|
855
|
+
},
|
|
856
|
+
{
|
|
857
|
+
cardinality: "many",
|
|
858
|
+
scope: "action",
|
|
859
|
+
spelling: "examples",
|
|
860
|
+
target: "examples",
|
|
861
|
+
},
|
|
862
|
+
{
|
|
863
|
+
cardinality: "one",
|
|
864
|
+
scope: "action",
|
|
865
|
+
spelling: "input",
|
|
866
|
+
target: "input",
|
|
867
|
+
},
|
|
868
|
+
{
|
|
869
|
+
cardinality: "many",
|
|
870
|
+
effects: [
|
|
871
|
+
{
|
|
872
|
+
kind: "moves",
|
|
873
|
+
per: "element",
|
|
874
|
+
signature: { movementClass: true },
|
|
875
|
+
},
|
|
876
|
+
{
|
|
877
|
+
kind: "holds",
|
|
878
|
+
per: "element",
|
|
879
|
+
signature: { fixed: "reserve" },
|
|
880
|
+
},
|
|
881
|
+
],
|
|
882
|
+
linearSink: true,
|
|
883
|
+
scope: "action",
|
|
884
|
+
spelling: "moves",
|
|
885
|
+
target: "moves",
|
|
886
|
+
},
|
|
887
|
+
{
|
|
888
|
+
cardinality: "one",
|
|
889
|
+
effects: [
|
|
890
|
+
{
|
|
891
|
+
kind: "moves",
|
|
892
|
+
per: "clause",
|
|
893
|
+
signature: { fixed: "payout.external" },
|
|
894
|
+
},
|
|
895
|
+
],
|
|
896
|
+
linearSink: true,
|
|
897
|
+
scope: "action",
|
|
898
|
+
spelling: "payout",
|
|
899
|
+
target: "payout",
|
|
900
|
+
},
|
|
901
|
+
{
|
|
902
|
+
cardinality: "one",
|
|
903
|
+
effects: [
|
|
904
|
+
{
|
|
905
|
+
kind: "decides",
|
|
906
|
+
per: "clause",
|
|
907
|
+
signature: { fixed: "tenant_port" },
|
|
908
|
+
},
|
|
909
|
+
],
|
|
910
|
+
scope: "action",
|
|
911
|
+
spelling: "port",
|
|
912
|
+
target: "port",
|
|
913
|
+
},
|
|
914
|
+
{
|
|
915
|
+
cardinality: "one",
|
|
916
|
+
scope: "action",
|
|
917
|
+
spelling: "principal",
|
|
918
|
+
target: "principal",
|
|
919
|
+
},
|
|
920
|
+
{
|
|
921
|
+
cardinality: "one",
|
|
922
|
+
scope: "action",
|
|
923
|
+
spelling: "public action",
|
|
924
|
+
target: "publicAction",
|
|
925
|
+
},
|
|
926
|
+
{
|
|
927
|
+
cardinality: "many",
|
|
928
|
+
effects: [
|
|
929
|
+
{
|
|
930
|
+
kind: "reads",
|
|
931
|
+
per: "element",
|
|
932
|
+
signature: { fixed: "reconcile" },
|
|
933
|
+
},
|
|
934
|
+
],
|
|
935
|
+
scope: "action",
|
|
936
|
+
spelling: "reconcile",
|
|
937
|
+
target: "reconcile",
|
|
938
|
+
},
|
|
939
|
+
{
|
|
940
|
+
cardinality: "one",
|
|
941
|
+
linearOutputs: ["amountRef"],
|
|
942
|
+
scope: "action",
|
|
943
|
+
spelling: "computes remainder",
|
|
944
|
+
target: "remainder",
|
|
945
|
+
},
|
|
946
|
+
{
|
|
947
|
+
cardinality: "many",
|
|
948
|
+
effects: [
|
|
949
|
+
{
|
|
950
|
+
kind: "reads",
|
|
951
|
+
per: "clause",
|
|
952
|
+
signature: { fixed: "requires_aggregate" },
|
|
953
|
+
},
|
|
954
|
+
],
|
|
955
|
+
scope: "action",
|
|
956
|
+
spelling: "requires aggregate",
|
|
957
|
+
target: "requiresAggregate",
|
|
958
|
+
},
|
|
959
|
+
{
|
|
960
|
+
cardinality: "many",
|
|
961
|
+
effects: [
|
|
962
|
+
{
|
|
963
|
+
kind: "reads",
|
|
964
|
+
per: "clause",
|
|
965
|
+
signature: { fixed: "requires_checks" },
|
|
966
|
+
},
|
|
967
|
+
],
|
|
968
|
+
scope: "action",
|
|
969
|
+
spelling: "requires checks",
|
|
970
|
+
target: "requiresChecks",
|
|
971
|
+
},
|
|
972
|
+
{
|
|
973
|
+
cardinality: "one",
|
|
974
|
+
scope: "action",
|
|
975
|
+
spelling: "requires drained",
|
|
976
|
+
target: "requiresDrainedAccount",
|
|
977
|
+
},
|
|
978
|
+
{
|
|
979
|
+
cardinality: "many",
|
|
980
|
+
scope: "action",
|
|
981
|
+
spelling: "requires exposure",
|
|
982
|
+
target: "requiresExposure",
|
|
983
|
+
},
|
|
984
|
+
{
|
|
985
|
+
cardinality: "many",
|
|
986
|
+
effects: [
|
|
987
|
+
{
|
|
988
|
+
kind: "reads",
|
|
989
|
+
per: "clause",
|
|
990
|
+
signature: { fixed: "requires_refs" },
|
|
991
|
+
},
|
|
992
|
+
],
|
|
993
|
+
scope: "action",
|
|
994
|
+
spelling: "requires refs",
|
|
995
|
+
target: "requiresRefs",
|
|
996
|
+
},
|
|
997
|
+
{
|
|
998
|
+
cardinality: "one",
|
|
999
|
+
scope: "action",
|
|
1000
|
+
spelling: "sandbox failure point",
|
|
1001
|
+
target: "sandboxFailurePoint",
|
|
1002
|
+
},
|
|
1003
|
+
{
|
|
1004
|
+
cardinality: "one",
|
|
1005
|
+
scope: "action",
|
|
1006
|
+
spelling: "sets at",
|
|
1007
|
+
target: "setsAt",
|
|
1008
|
+
},
|
|
1009
|
+
{
|
|
1010
|
+
cardinality: "one",
|
|
1011
|
+
linearOutputs: ["amountRef"],
|
|
1012
|
+
scope: "action",
|
|
1013
|
+
spelling: "computes signed_sum",
|
|
1014
|
+
target: "signedSum",
|
|
1015
|
+
},
|
|
1016
|
+
{
|
|
1017
|
+
cardinality: "many",
|
|
1018
|
+
linearSink: true,
|
|
1019
|
+
scope: "action",
|
|
1020
|
+
spelling: "steps",
|
|
1021
|
+
target: "steps",
|
|
1022
|
+
},
|
|
1023
|
+
{
|
|
1024
|
+
cardinality: "one",
|
|
1025
|
+
scope: "action",
|
|
1026
|
+
spelling: "summary",
|
|
1027
|
+
target: "summary",
|
|
1028
|
+
},
|
|
1029
|
+
{
|
|
1030
|
+
cardinality: "many",
|
|
1031
|
+
scope: "action",
|
|
1032
|
+
spelling: "updates",
|
|
1033
|
+
target: "updates",
|
|
1034
|
+
},
|
|
1035
|
+
{
|
|
1036
|
+
cardinality: "many",
|
|
1037
|
+
effects: [
|
|
1038
|
+
{
|
|
1039
|
+
kind: "notifies",
|
|
1040
|
+
per: "element",
|
|
1041
|
+
signature: { fromField: "channel" },
|
|
1042
|
+
},
|
|
1043
|
+
],
|
|
1044
|
+
scope: "action",
|
|
1045
|
+
spelling: "notify",
|
|
1046
|
+
target: "effects.notifies",
|
|
1047
|
+
},
|
|
1048
|
+
{
|
|
1049
|
+
cardinality: "one",
|
|
1050
|
+
scope: "instrument",
|
|
1051
|
+
spelling: "agent description",
|
|
1052
|
+
target: "agentDescription",
|
|
1053
|
+
},
|
|
1054
|
+
{
|
|
1055
|
+
cardinality: "many",
|
|
1056
|
+
scope: "instrument",
|
|
1057
|
+
spelling: "aggregate invariants",
|
|
1058
|
+
target: "aggregateInvariants",
|
|
1059
|
+
},
|
|
1060
|
+
{
|
|
1061
|
+
cardinality: "one",
|
|
1062
|
+
scope: "instrument",
|
|
1063
|
+
spelling: "caller parked states",
|
|
1064
|
+
target: "callerParkedStates",
|
|
1065
|
+
},
|
|
1066
|
+
{
|
|
1067
|
+
cardinality: "one",
|
|
1068
|
+
scope: "instrument",
|
|
1069
|
+
spelling: "description",
|
|
1070
|
+
target: "description",
|
|
1071
|
+
},
|
|
1072
|
+
{
|
|
1073
|
+
cardinality: "many",
|
|
1074
|
+
scope: "instrument",
|
|
1075
|
+
spelling: "dials",
|
|
1076
|
+
target: "dials",
|
|
1077
|
+
},
|
|
1078
|
+
{
|
|
1079
|
+
cardinality: "one",
|
|
1080
|
+
scope: "instrument",
|
|
1081
|
+
spelling: "distinct parties",
|
|
1082
|
+
target: "distinctParties",
|
|
1083
|
+
},
|
|
1084
|
+
{
|
|
1085
|
+
cardinality: "many",
|
|
1086
|
+
scope: "instrument",
|
|
1087
|
+
spelling: "computes derived",
|
|
1088
|
+
target: "derivedAmounts",
|
|
1089
|
+
},
|
|
1090
|
+
{
|
|
1091
|
+
cardinality: "many",
|
|
1092
|
+
scope: "instrument",
|
|
1093
|
+
spelling: "computes fees",
|
|
1094
|
+
target: "feeRules",
|
|
1095
|
+
},
|
|
1096
|
+
{
|
|
1097
|
+
cardinality: "one",
|
|
1098
|
+
scope: "instrument",
|
|
1099
|
+
spelling: "id prefix",
|
|
1100
|
+
target: "idPrefix",
|
|
1101
|
+
},
|
|
1102
|
+
{
|
|
1103
|
+
cardinality: "many",
|
|
1104
|
+
scope: "instrument",
|
|
1105
|
+
spelling: "nav",
|
|
1106
|
+
target: "nav",
|
|
1107
|
+
},
|
|
1108
|
+
{
|
|
1109
|
+
cardinality: "many",
|
|
1110
|
+
scope: "instrument",
|
|
1111
|
+
spelling: "partitions",
|
|
1112
|
+
target: "partitions",
|
|
1113
|
+
},
|
|
1114
|
+
{
|
|
1115
|
+
cardinality: "one",
|
|
1116
|
+
scope: "instrument",
|
|
1117
|
+
spelling: "subject",
|
|
1118
|
+
target: "subject",
|
|
1119
|
+
},
|
|
1120
|
+
{
|
|
1121
|
+
cardinality: "one",
|
|
1122
|
+
scope: "instrument",
|
|
1123
|
+
spelling: "summary",
|
|
1124
|
+
target: "summary",
|
|
1125
|
+
},
|
|
1126
|
+
{
|
|
1127
|
+
cardinality: "one",
|
|
1128
|
+
scope: "instrument",
|
|
1129
|
+
spelling: "surface visibility",
|
|
1130
|
+
target: "surfaceVisibility",
|
|
1131
|
+
},
|
|
1132
|
+
{
|
|
1133
|
+
cardinality: "one",
|
|
1134
|
+
scope: "instrument",
|
|
1135
|
+
spelling: "template id",
|
|
1136
|
+
target: "templateId",
|
|
1137
|
+
},
|
|
1138
|
+
{
|
|
1139
|
+
cardinality: "one",
|
|
1140
|
+
scope: "instrument",
|
|
1141
|
+
spelling: "title",
|
|
1142
|
+
target: "title",
|
|
1143
|
+
},
|
|
1144
|
+
{
|
|
1145
|
+
cardinality: "one",
|
|
1146
|
+
scope: "instrument",
|
|
1147
|
+
spelling: "update",
|
|
1148
|
+
target: "update",
|
|
1149
|
+
},
|
|
1150
|
+
] as const satisfies readonly UdlClauseVocabularyEntry[];
|
|
393
1151
|
|
|
394
1152
|
const udlDocumentShapeSchema = z.strictObject({
|
|
395
|
-
|
|
1153
|
+
dials: z.array(udlCompositionDialSchema).min(1).optional(),
|
|
1154
|
+
instruments: z.array(udlInstrumentSchema).min(1),
|
|
396
1155
|
product: udlSnakeCaseSchema,
|
|
397
1156
|
subjects: z.array(udlSubjectSchema),
|
|
398
1157
|
title: nonEmptyTextSchema,
|
|
@@ -400,7 +1159,7 @@ const udlDocumentShapeSchema = z.strictObject({
|
|
|
400
1159
|
version: z.number().int().positive(),
|
|
401
1160
|
});
|
|
402
1161
|
|
|
403
|
-
type
|
|
1162
|
+
type ParsedInstrument = z.infer<typeof udlInstrumentSchema>;
|
|
404
1163
|
|
|
405
1164
|
const moneyPatterns = new Set(["^[1-9][0-9]{0,17}$", "^(0|[1-9][0-9]{0,17})$"]);
|
|
406
1165
|
|
|
@@ -414,8 +1173,8 @@ function isMoneyField(
|
|
|
414
1173
|
|
|
415
1174
|
function referenceTargets(
|
|
416
1175
|
schema: Readonly<Record<string, unknown>>,
|
|
417
|
-
|
|
418
|
-
): readonly
|
|
1176
|
+
instruments: readonly ParsedInstrument[],
|
|
1177
|
+
): readonly ParsedInstrument[] {
|
|
419
1178
|
if (schema.type !== "string" || typeof schema.pattern !== "string") return [];
|
|
420
1179
|
// Parse the scoped-ID pattern. Executing an author regex here would bypass
|
|
421
1180
|
// the semantic validator's branch and quantifier budgets.
|
|
@@ -433,43 +1192,52 @@ function referenceTargets(
|
|
|
433
1192
|
if (typeof schema.maxLength === "number" && probe.length > schema.maxLength) {
|
|
434
1193
|
return [];
|
|
435
1194
|
}
|
|
436
|
-
return
|
|
1195
|
+
return instruments.filter((instrument) => instrument.idPrefix === prefix);
|
|
437
1196
|
}
|
|
438
1197
|
|
|
439
|
-
function declaredMoneyRefKeys(
|
|
1198
|
+
function declaredMoneyRefKeys(
|
|
1199
|
+
instrument: ParsedInstrument,
|
|
1200
|
+
): ReadonlySet<string> {
|
|
440
1201
|
return new Set([
|
|
441
|
-
...(
|
|
442
|
-
|
|
443
|
-
|
|
1202
|
+
...Object.values(instrument.actions).flatMap((action) => [
|
|
1203
|
+
...(action.remainder
|
|
1204
|
+
? [
|
|
1205
|
+
action.remainder.amountRef,
|
|
1206
|
+
...(action.remainder.accumulateRef
|
|
1207
|
+
? [action.remainder.accumulateRef]
|
|
1208
|
+
: []),
|
|
1209
|
+
]
|
|
1210
|
+
: []),
|
|
1211
|
+
...(action.signedSum
|
|
444
1212
|
? [
|
|
445
|
-
|
|
446
|
-
...
|
|
1213
|
+
action.signedSum.amountRef,
|
|
1214
|
+
...action.signedSum.sources.map((source) => source.subtotalRef),
|
|
447
1215
|
]
|
|
448
1216
|
: []),
|
|
449
|
-
...(
|
|
1217
|
+
...(action.distribute ? [action.distribute.amountRef] : []),
|
|
1218
|
+
...(action.quote ? [action.quote.chargeRef, action.quote.netRef] : []),
|
|
450
1219
|
]),
|
|
451
|
-
...(noun.unwind ? ["unwindRefund", "unwindPenalty"] : []),
|
|
452
1220
|
]);
|
|
453
1221
|
}
|
|
454
1222
|
|
|
455
1223
|
export const udlDocumentSchema = udlDocumentShapeSchema.superRefine(
|
|
456
1224
|
(document, context) => {
|
|
457
|
-
document.
|
|
458
|
-
|
|
1225
|
+
document.instruments.forEach((instrument, instrumentIndex) => {
|
|
1226
|
+
instrument.derivedAmounts?.forEach((amount, amountIndex) => {
|
|
459
1227
|
const base = [
|
|
460
|
-
"
|
|
461
|
-
|
|
1228
|
+
"instruments",
|
|
1229
|
+
instrumentIndex,
|
|
462
1230
|
"derivedAmounts",
|
|
463
1231
|
amountIndex,
|
|
464
1232
|
] as const;
|
|
465
|
-
if (!isMoneyField(
|
|
1233
|
+
if (!isMoneyField(instrument.fields[amount.field])) {
|
|
466
1234
|
context.addIssue({
|
|
467
1235
|
code: "custom",
|
|
468
1236
|
message: `derived amount target ${amount.field} must be a declared money field`,
|
|
469
1237
|
path: [...base, "field"],
|
|
470
1238
|
});
|
|
471
1239
|
}
|
|
472
|
-
if (!isMoneyField(
|
|
1240
|
+
if (!isMoneyField(instrument.fields[amount.sourceField])) {
|
|
473
1241
|
context.addIssue({
|
|
474
1242
|
code: "custom",
|
|
475
1243
|
message: `derived amount source ${amount.sourceField} must be a declared money field`,
|
|
@@ -485,29 +1253,29 @@ export const udlDocumentSchema = udlDocumentShapeSchema.superRefine(
|
|
|
485
1253
|
}
|
|
486
1254
|
});
|
|
487
1255
|
|
|
488
|
-
Object.entries(
|
|
489
|
-
const distribute =
|
|
1256
|
+
Object.entries(instrument.actions).forEach(([actionName, action]) => {
|
|
1257
|
+
const distribute = action.distribute;
|
|
490
1258
|
if (!distribute) return;
|
|
491
1259
|
const base = [
|
|
492
|
-
"
|
|
493
|
-
|
|
494
|
-
"
|
|
495
|
-
|
|
1260
|
+
"instruments",
|
|
1261
|
+
instrumentIndex,
|
|
1262
|
+
"actions",
|
|
1263
|
+
actionName,
|
|
496
1264
|
"distribute",
|
|
497
1265
|
] as const;
|
|
498
|
-
const refSchema =
|
|
1266
|
+
const refSchema = instrument.fields[distribute.refField];
|
|
499
1267
|
const parents = refSchema
|
|
500
|
-
? referenceTargets(refSchema, document.
|
|
1268
|
+
? referenceTargets(refSchema, document.instruments)
|
|
501
1269
|
: [];
|
|
502
1270
|
if (parents.length !== 1) {
|
|
503
1271
|
context.addIssue({
|
|
504
1272
|
code: "custom",
|
|
505
|
-
message: `distribute refField ${distribute.refField} must identify exactly one parent
|
|
1273
|
+
message: `distribute refField ${distribute.refField} must identify exactly one parent instrument`,
|
|
506
1274
|
path: [...base, "refField"],
|
|
507
1275
|
});
|
|
508
1276
|
}
|
|
509
1277
|
|
|
510
|
-
if (!isMoneyField(
|
|
1278
|
+
if (!isMoneyField(instrument.fields[distribute.weightField])) {
|
|
511
1279
|
context.addIssue({
|
|
512
1280
|
code: "custom",
|
|
513
1281
|
message: `distribute weightField ${distribute.weightField} must be a declared money field`,
|
|
@@ -516,10 +1284,10 @@ export const udlDocumentSchema = udlDocumentShapeSchema.superRefine(
|
|
|
516
1284
|
}
|
|
517
1285
|
|
|
518
1286
|
distribute.statuses.forEach((status, statusIndex) => {
|
|
519
|
-
if (
|
|
1287
|
+
if (instrument.lifecycle.states.includes(status)) return;
|
|
520
1288
|
context.addIssue({
|
|
521
1289
|
code: "custom",
|
|
522
|
-
message: `distribute status ${status} is not declared by ${
|
|
1290
|
+
message: `distribute status ${status} is not declared by ${instrument.id}`,
|
|
523
1291
|
path: [...base, "statuses", statusIndex],
|
|
524
1292
|
});
|
|
525
1293
|
});
|
|
@@ -556,8 +1324,11 @@ export type UdlDeclaredValuePolicy = z.infer<
|
|
|
556
1324
|
typeof udlDeclaredValuePolicySchema
|
|
557
1325
|
>;
|
|
558
1326
|
export type UdlDecision = z.infer<typeof udlDecisionSchema>;
|
|
1327
|
+
export type UdlCompositionDial = z.infer<typeof udlCompositionDialSchema>;
|
|
1328
|
+
export type UdlDial = z.infer<typeof udlDialSchema>;
|
|
559
1329
|
export type UdlDocument = z.infer<typeof udlDocumentSchema>;
|
|
560
1330
|
export type UdlDue = z.infer<typeof udlDueSchema>;
|
|
1331
|
+
export type UdlEffects = z.infer<typeof udlEffectsSchema>;
|
|
561
1332
|
export type UdlExample = z.infer<typeof udlExampleSchema>;
|
|
562
1333
|
export type UdlGate = z.infer<typeof udlGateSchema>;
|
|
563
1334
|
export type UdlKernelOperation = z.infer<typeof udlKernelOperationSchema>;
|
|
@@ -565,12 +1336,15 @@ export type UdlLifecycle = z.infer<typeof udlLifecycleSchema>;
|
|
|
565
1336
|
export type UdlLifecycleTransition = z.infer<
|
|
566
1337
|
typeof udlLifecycleTransitionSchema
|
|
567
1338
|
>;
|
|
568
|
-
export type
|
|
569
|
-
export type
|
|
1339
|
+
export type UdlInstrument = z.infer<typeof udlInstrumentSchema>;
|
|
1340
|
+
export type UdlInstrumentSubject = z.infer<typeof udlInstrumentSubjectSchema>;
|
|
570
1341
|
export type UdlMove = z.infer<typeof udlMoveSchema>;
|
|
571
1342
|
export type UdlPayout = z.infer<typeof udlPayoutSchema>;
|
|
572
|
-
export type
|
|
1343
|
+
export type UdlQuote = z.infer<typeof udlQuoteSchema>;
|
|
1344
|
+
export type UdlProviderFamilyId = z.infer<typeof udlProviderFamilyIdSchema>;
|
|
1345
|
+
export type UdlCheckRequirement = z.infer<typeof udlCheckRequirementSchema>;
|
|
1346
|
+
export type UdlReconcile = z.infer<typeof udlReconcileSchema>;
|
|
1347
|
+
export type UdlRemainder = z.infer<typeof udlRemainderSchema>;
|
|
573
1348
|
export type UdlStep = z.infer<typeof udlStepSchema>;
|
|
574
1349
|
export type UdlSubject = z.infer<typeof udlSubjectSchema>;
|
|
575
|
-
export type
|
|
576
|
-
export type UdlVerb = z.infer<typeof udlVerbSchema>;
|
|
1350
|
+
export type UdlAction = z.infer<typeof udlActionSchema>;
|