@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.
Files changed (179) hide show
  1. package/CHANGELOG.md +78 -25
  2. package/README.md +37 -99
  3. package/conformance/README.md +44 -41
  4. package/conformance/evolution/action-contract.expected.json +10 -0
  5. package/conformance/evolution/action-contract.live.udl +44 -0
  6. package/conformance/evolution/action-contract.next.udl +45 -0
  7. package/conformance/evolution/product-identity.expected.json +10 -0
  8. package/conformance/evolution/product-identity.live.udl +55 -0
  9. package/conformance/evolution/product-identity.next.udl +55 -0
  10. package/conformance/evolution/version-required.expected.json +10 -0
  11. package/conformance/evolution/version-required.live.udl +55 -0
  12. package/conformance/evolution/version-required.next.udl +58 -0
  13. package/conformance/invalid/action-without-transition.expected.json +10 -0
  14. package/conformance/invalid/{verb-without-transition.udl → action-without-transition.udl} +7 -2
  15. package/conformance/invalid/agent-description-too-long.expected.json +10 -0
  16. package/conformance/invalid/agent-description-too-long.udl +57 -0
  17. package/conformance/invalid/blank-title.expected.json +1 -1
  18. package/conformance/invalid/blank-title.udl +6 -2
  19. package/conformance/invalid/composition-dial-duplicate-key.expected.json +10 -0
  20. package/conformance/invalid/composition-dial-duplicate-key.udl +73 -0
  21. package/conformance/invalid/depth-budget.expected.json +1 -1
  22. package/conformance/invalid/duplicate-subject.expected.json +10 -0
  23. package/conformance/invalid/duplicate-subject.udl +230 -0
  24. package/conformance/invalid/forged-effects.expected.json +10 -0
  25. package/conformance/invalid/forged-effects.udl +76 -0
  26. package/conformance/invalid/format-version.expected.json +1 -1
  27. package/conformance/invalid/format-version.udl +6 -2
  28. package/conformance/invalid/instrument-id-not-snake-case.expected.json +10 -0
  29. package/conformance/invalid/{noun-id-not-snake-case.udl → instrument-id-not-snake-case.udl} +6 -2
  30. package/conformance/invalid/invalid-aggregate-gate-shape.expected.json +10 -0
  31. package/conformance/invalid/invalid-aggregate-gate-shape.udl +1819 -0
  32. package/conformance/invalid/invalid-check-duration.expected.json +10 -0
  33. package/conformance/invalid/invalid-check-duration.udl +219 -0
  34. package/conformance/invalid/invalid-dial-anchor.expected.json +10 -0
  35. package/conformance/invalid/invalid-dial-anchor.udl +219 -0
  36. package/conformance/invalid/invalid-exception-parent-ref.expected.json +10 -0
  37. package/conformance/invalid/invalid-exception-parent-ref.udl +2487 -0
  38. package/conformance/invalid/invalid-exposure-shape.expected.json +10 -0
  39. package/conformance/invalid/invalid-exposure-shape.udl +1819 -0
  40. package/conformance/invalid/invalid-remainder.expected.json +10 -0
  41. package/conformance/invalid/invalid-remainder.udl +220 -0
  42. package/conformance/invalid/invalid-schema-keyword.expected.json +10 -0
  43. package/conformance/invalid/invalid-schema-keyword.udl +220 -0
  44. package/conformance/invalid/invalid-utf8.expected.json +1 -1
  45. package/conformance/invalid/malformed-json.expected.json +1 -1
  46. package/conformance/invalid/missing-create-action.expected.json +10 -0
  47. package/conformance/invalid/{missing-create-verb.udl → missing-create-action.udl} +5 -2
  48. package/conformance/invalid/missing-exception-amount-field.expected.json +10 -0
  49. package/conformance/invalid/missing-exception-amount-field.udl +2487 -0
  50. package/conformance/invalid/missing-exception-contract.expected.json +14 -0
  51. package/conformance/invalid/missing-exception-contract.udl +2523 -0
  52. package/conformance/invalid/missing-exception-reason-field.expected.json +10 -0
  53. package/conformance/invalid/missing-exception-reason-field.udl +2487 -0
  54. package/conformance/invalid/not-an-object.expected.json +1 -1
  55. package/conformance/invalid/payout-reconcile-not-a-bank-debit.expected.json +10 -0
  56. package/conformance/invalid/payout-reconcile-not-a-bank-debit.udl +259 -0
  57. package/conformance/invalid/quote-freeze-set-incomplete.expected.json +10 -0
  58. package/conformance/invalid/quote-freeze-set-incomplete.udl +261 -0
  59. package/conformance/invalid/quote-named-reference-gate.expected.json +10 -0
  60. package/conformance/invalid/quote-named-reference-gate.udl +50 -0
  61. package/conformance/invalid/reconcile-named-reference-gate.expected.json +10 -0
  62. package/conformance/invalid/reconcile-named-reference-gate.udl +50 -0
  63. package/conformance/invalid/unknown-key.expected.json +1 -1
  64. package/conformance/invalid/unknown-key.udl +6 -2
  65. package/conformance/invalid/unknown-reference-gate-field.expected.json +10 -0
  66. package/conformance/invalid/unknown-reference-gate-field.udl +1819 -0
  67. package/conformance/invalid/unknown-required-field.expected.json +10 -0
  68. package/conformance/invalid/unknown-required-field.udl +220 -0
  69. package/conformance/invalid/unreachable-state.expected.json +2 -2
  70. package/conformance/invalid/unreachable-state.udl +6 -2
  71. package/conformance/invalid/wrong-exception-amount-field.expected.json +10 -0
  72. package/conformance/invalid/wrong-exception-amount-field.udl +2487 -0
  73. package/conformance/invalid/wrong-exception-reason-field.expected.json +10 -0
  74. package/conformance/invalid/wrong-exception-reason-field.udl +2487 -0
  75. package/conformance/valid/agent-description.expected.json +6 -0
  76. package/conformance/valid/agent-description.udl +66 -0
  77. package/conformance/valid/cards.expected.json +1 -0
  78. package/conformance/valid/cards.udl +843 -356
  79. package/conformance/valid/commerce-escrow.expected.json +1 -0
  80. package/conformance/valid/commerce-escrow.udl +792 -291
  81. package/conformance/valid/compiled-crowdfunding.expected.json +6 -0
  82. package/conformance/valid/compiled-crowdfunding.udl +1843 -0
  83. package/conformance/valid/compiled-watch-club.expected.json +6 -0
  84. package/conformance/valid/compiled-watch-club.udl +2486 -0
  85. package/conformance/valid/complete-contract.expected.json +6 -0
  86. package/conformance/valid/complete-contract.udl +218 -0
  87. package/conformance/valid/effect-signatures.expected.json +6 -0
  88. package/conformance/valid/effect-signatures.udl +75 -0
  89. package/conformance/valid/hand-edited.expected.json +1 -0
  90. package/conformance/valid/hand-edited.udl +1 -1
  91. package/conformance/valid/insured-car-marketplace.expected.json +1 -0
  92. package/conformance/valid/insured-car-marketplace.udl +534 -315
  93. package/conformance/valid/insured-travel.expected.json +2 -1
  94. package/conformance/valid/insured-travel.udl +1489 -641
  95. package/conformance/valid/minimal.expected.json +1 -0
  96. package/conformance/valid/minimal.udl +18 -14
  97. package/conformance/valid/protection.expected.json +1 -0
  98. package/conformance/valid/protection.udl +719 -304
  99. package/conformance/valid/string-escaping.expected.json +6 -0
  100. package/conformance/valid/string-escaping.udl +54 -0
  101. package/dist/canonical.d.ts +2 -0
  102. package/dist/canonical.d.ts.map +1 -1
  103. package/dist/canonical.js +7 -0
  104. package/dist/canonical.js.map +1 -1
  105. package/dist/check-profiles.d.ts +57 -0
  106. package/dist/check-profiles.d.ts.map +1 -0
  107. package/dist/check-profiles.js +62 -0
  108. package/dist/check-profiles.js.map +1 -0
  109. package/dist/cli.js +48 -4
  110. package/dist/cli.js.map +1 -1
  111. package/dist/diagnostics.d.ts +168 -0
  112. package/dist/diagnostics.d.ts.map +1 -0
  113. package/dist/diagnostics.js +164 -0
  114. package/dist/diagnostics.js.map +1 -0
  115. package/dist/effects.d.ts +41 -0
  116. package/dist/effects.d.ts.map +1 -0
  117. package/dist/effects.js +110 -0
  118. package/dist/effects.js.map +1 -0
  119. package/dist/evolution.d.ts +51 -18
  120. package/dist/evolution.d.ts.map +1 -1
  121. package/dist/evolution.js +244 -102
  122. package/dist/evolution.js.map +1 -1
  123. package/dist/finance.d.ts +17 -13
  124. package/dist/finance.d.ts.map +1 -1
  125. package/dist/finance.js +165 -109
  126. package/dist/finance.js.map +1 -1
  127. package/dist/index.d.ts +12 -8
  128. package/dist/index.d.ts.map +1 -1
  129. package/dist/index.js +8 -5
  130. package/dist/index.js.map +1 -1
  131. package/dist/limits.d.ts +2 -2
  132. package/dist/limits.d.ts.map +1 -1
  133. package/dist/limits.js +4 -3
  134. package/dist/limits.js.map +1 -1
  135. package/dist/parser.d.ts.map +1 -1
  136. package/dist/parser.js +6 -16
  137. package/dist/parser.js.map +1 -1
  138. package/dist/schema.d.ts +2059 -135
  139. package/dist/schema.d.ts.map +1 -1
  140. package/dist/schema.js +759 -73
  141. package/dist/schema.js.map +1 -1
  142. package/dist/validation.d.ts +22 -9
  143. package/dist/validation.d.ts.map +1 -1
  144. package/dist/validation.js +1463 -457
  145. package/dist/validation.js.map +1 -1
  146. package/docs/README.md +14 -0
  147. package/docs/guide/01-a-document.md +37 -0
  148. package/docs/guide/02-money-steps.md +23 -0
  149. package/docs/guide/03-laws.md +18 -0
  150. package/docs/guide/04-fees-and-remainder.md +15 -0
  151. package/docs/guide/05-checks-updates-dials.md +7 -0
  152. package/docs/guide/06-effects.md +11 -0
  153. package/docs/guide/07-evolution.md +11 -0
  154. package/docs/guide/08-implementing.md +13 -0
  155. package/docs/llms-full.txt +1241 -0
  156. package/docs/llms.txt +14 -0
  157. package/docs/reference/canonical.md +16 -0
  158. package/docs/reference/clauses.md +986 -0
  159. package/docs/reference/cli.md +22 -0
  160. package/docs/reference/diagnostics.md +32 -0
  161. package/package.json +6 -2
  162. package/skills/udl/SKILL.md +28 -0
  163. package/spec/README.md +82 -51
  164. package/spec/udl.schema.json +1191 -119
  165. package/src/canonical.ts +11 -0
  166. package/src/check-profiles.ts +80 -0
  167. package/src/cli.ts +49 -3
  168. package/src/diagnostics.ts +221 -0
  169. package/src/effects.ts +163 -0
  170. package/src/evolution.ts +375 -125
  171. package/src/finance.ts +255 -160
  172. package/src/index.ts +50 -14
  173. package/src/limits.ts +4 -3
  174. package/src/parser.ts +15 -18
  175. package/src/schema.ts +855 -81
  176. package/src/validation.ts +2666 -560
  177. package/conformance/invalid/missing-create-verb.expected.json +0 -10
  178. package/conformance/invalid/noun-id-not-snake-case.expected.json +0 -10
  179. package/conformance/invalid/verb-without-transition.expected.json +0 -10
@@ -0,0 +1,1241 @@
1
+ <!-- Generated by scripts/docs/build.ts from @hyperscale0/udl 1.0.0. Edit the source, not llms-full.txt. -->
2
+
3
+ # UDL complete reference
4
+
5
+ <!-- source: README.md -->
6
+
7
+ # UDL documentation
8
+
9
+ UDL is the versioned JSON contract between a product definition and an engine that executes it. Start with the document guide, then read the guides in order. Validator authors should also read the canonical bytes law and run the conformance corpus.
10
+
11
+ 1. [A document](guide/01-a-document.md)
12
+ 2. [Money steps](guide/02-money-steps.md)
13
+ 3. [The ten laws](guide/03-laws.md)
14
+ 4. [Fees and remainder](guide/04-fees-and-remainder.md)
15
+ 5. [Checks, updates, and dials](guide/05-checks-updates-dials.md)
16
+ 6. [Effects](guide/06-effects.md)
17
+ 7. [Evolution](guide/07-evolution.md)
18
+ 8. [Implementing UDL](guide/08-implementing.md)
19
+
20
+ The [clause reference](reference/clauses.md) and [diagnostic reference](reference/diagnostics.md) come from the package tables. The [command reference](reference/cli.md) comes from the CLI usage text. Do not edit those generated files by hand.
21
+
22
+ <!-- source: guide/01-a-document.md -->
23
+
24
+ # A document
25
+
26
+ A UDL document names one product and contains its subjects and instruments. Each instrument declares stored fields, required fields, a lifecycle, and the actions that create or change an instance.
27
+
28
+ This is the smallest admitted document. `create` starts at `open`. `close` follows the matching lifecycle transition and ends at `closed`.
29
+
30
+ ```json
31
+ {
32
+ "instruments": [
33
+ {
34
+ "actionOrder": ["close", "create"],
35
+ "fields": { "reference": { "type": "string" } },
36
+ "id": "note",
37
+ "idPrefix": "note",
38
+ "lifecycle": {
39
+ "initial": "open",
40
+ "states": ["open", "closed"],
41
+ "transitions": { "close": { "from": ["open"], "to": "closed" } }
42
+ },
43
+ "required": ["reference"],
44
+ "summary": "A note a tenant files and later closes.",
45
+ "title": "Note",
46
+ "actions": {
47
+ "close": { "moves": [], "steps": [], "summary": "Close the note." },
48
+ "create": { "moves": [], "steps": [], "summary": "File the note." }
49
+ }
50
+ }
51
+ ],
52
+ "product": "minimal",
53
+ "subjects": [],
54
+ "title": "Minimal",
55
+ "udl": 1,
56
+ "version": 1
57
+ }
58
+ ```
59
+
60
+ The JSON Schema checks the written shape. `validateUdl` then checks names, references, lifecycle reachability, and the money graph. A document has no canonical form until both checks pass.
61
+
62
+ <!-- source: guide/02-money-steps.md -->
63
+
64
+ # Money steps
65
+
66
+ UDL seals internal ledger work to seven kernel operations. Four instructions create, reserve, post, or void an internal transfer. Three account instructions provision an escrow account, freeze an account, or unfreeze it.
67
+
68
+ A step names an operation and binds its inputs from action input, constants, or instance fields and refs. `capture` writes selected operation output into durable refs. A later step can read those refs.
69
+
70
+ ```jsonc
71
+ {
72
+ "operation": "internal_transfer.reserve",
73
+ "bind": {
74
+ "sourceAccountId": { "from": "instance", "path": "fields.payerAccountId" },
75
+ "destinationAccountId": {
76
+ "from": "instance",
77
+ "path": "refs.escrowAccountId",
78
+ },
79
+ "amount": { "from": "instance", "path": "fields.amount" },
80
+ "currency": { "from": "const", "value": "SAR" },
81
+ },
82
+ "capture": { "transferId": "reservationId" },
83
+ }
84
+ ```
85
+
86
+ `payout` is an execution intent, not an eighth kernel operation. It reads stored money and beneficiary data, then captures a durable payout reference. A later system action can reconcile that payout against settlement evidence.
87
+
88
+ <!-- source: guide/03-laws.md -->
89
+
90
+ # The ten laws
91
+
92
+ The schema defines shape. These laws define meaning.
93
+
94
+ 1. Every UDL concept fits in one sentence.
95
+ 2. Provider formats and operating machinery stay below UDL. `reconcile` names settlement evidence against a declared provider-side row. It does not model the provider file or transport.
96
+ 3. Every state change emits an event.
97
+ 4. Internal ledger money uses the seven sealed operations.
98
+ 5. Every instance has the same identity, status, timestamp, and metadata frame. Money uses integer minor-unit strings plus a currency.
99
+ 6. Requirements such as due time, checks, references, quote commitment, and reconciliation are data.
100
+ 7. A stored definition evolves by additive change only.
101
+ 8. Instruments, actions, operations, and fields follow their declared naming patterns.
102
+ 9. Real delays appear as statuses and timestamps.
103
+ 10. Every state, reference, gate, and funded path closes inside the document.
104
+
105
+ A reconcile exception names the child fields that receive the unmatched amount and its reason. `exception.amountField` must be a required money field on the child. `exception.reasonField` must be a required plain text field. A plain text field has `type: "string"` and no `pattern`, `format`, or `enum`. Admission rejects a missing or optional field, the wrong type, or a child that does not belong to the declaring instrument.
106
+
107
+ The [diagnostic reference](reference/diagnostics.md) lists every stable `UDL####` refusal code. The [specification](../spec/README.md) carries the normative prose for each law.
108
+
109
+ <!-- source: guide/04-fees-and-remainder.md -->
110
+
111
+ # Fees and remainder
112
+
113
+ Fee rules derive named amounts from a stored base amount. Partitions state how cancellation or reversal divides held money. A remainder clause computes one amount after named deductions and captures it under `amountRef`.
114
+
115
+ ```jsonc
116
+ {
117
+ "remainder": {
118
+ "amountRef": "sellerNet",
119
+ "from": "fields.amount",
120
+ "subtract": ["refs.platformFee"],
121
+ },
122
+ }
123
+ ```
124
+
125
+ Computed money has one author. A remainder, signed sum, distribution, quote, or derived amount must not compete with another clause for the same field or ref. A money move consumes the computed value once. The validator rejects missing sources, duplicate outputs, and terminal paths that strand funded value.
126
+
127
+ <!-- source: guide/05-checks-updates-dials.md -->
128
+
129
+ # Checks, updates, and dials
130
+
131
+ `requiresChecks` asks for current evidence from a declared provider family. The row names the check kind, acceptable statuses, subject field, and optional maximum age. Callers cannot replace the evidence with a boolean.
132
+
133
+ `update` declares which stored fields an update operation may change. Action-level `updates` assign admitted values. Required creation fields, derived amounts, immutable bindings, and quote-frozen fields remain protected.
134
+
135
+ Dials are named policy values with bounds. Clauses refer to a dial by id instead of copying a threshold into several actions. The document therefore exposes one reviewable setting for limits such as reconciliation tolerance.
136
+
137
+ <!-- source: guide/06-effects.md -->
138
+
139
+ # Effects
140
+
141
+ Effects are derived ABI rows. Authors declare clauses such as moves, decisions, schedules, reads, and notifications. The compiler derives the `effects` object from those clauses in vocabulary order.
142
+
143
+ Each row records its source and a stable signature. Movement signatures include their cost class. Schedule signatures identify a deadline or due trigger. Read signatures identify the gate family. Notification rows retain channel and role.
144
+
145
+ The validator derives the rows again and compares the complete object, including row order. A missing, extra, changed, or reordered row is a refusal. Derived effect subtrees do not count toward the authored node budget, but they still pass JSON, depth, and string limits.
146
+
147
+ Cost tooling reads the same movement and hold signatures. Runtime hints may read the effect rows, but they cannot change the clauses that produced them.
148
+
149
+ `quote` derives `holds.quote` and `schedules.expiry`. `reconcile` derives one `reads.reconcile` row per expectation. `commit` has no separate effect row. The committing action consumes the held quote through its `moves.*` row, so another consumption row would count the same work twice.
150
+
151
+ <!-- source: guide/07-evolution.md -->
152
+
153
+ # Evolution
154
+
155
+ `diffValidatedUdlEvolution(live, next)` compares two admitted documents. The CLI exposes the same check as `udl diff live.udl next.udl`.
156
+
157
+ Once instances exist, a new version may add optional fields, states, transitions, and actions. It may not remove or rename stored structure, tighten an admitted schema, change a money step, or reuse an existing version number for different executable meaning. The diff returns `UDL7xxx` issues with JSON paths.
158
+
159
+ A migration is work outside the format. It reads stored instances under their original document, writes data required by a new document, and changes the pinned definition only after that work succeeds. Editing the document does not migrate data.
160
+
161
+ Keep old canonical documents with stored instances. A format bump changes the literal `udl` value. A reader must keep explicit decoders for supported older formats rather than silently treating old bytes as the newest grammar.
162
+
163
+ Evolution does not invent defaults for executable clause fields. In particular, it does not guess `reconcile.exception.amountField` or `reasonField` for an older snapshot. A candidate must name both fields and pass the current validator before the diff can judge it.
164
+
165
+ <!-- source: guide/08-implementing.md -->
166
+
167
+ # Implementing UDL
168
+
169
+ A second implementation needs three independent checks.
170
+
171
+ 1. Validate JSON shape against `spec/udl.schema.json`.
172
+ 2. Enforce the whole-document laws and report the matching `UDL####` code and JSON path.
173
+ 3. Serialize admitted documents under the canonical bytes law.
174
+
175
+ Run every conformance level. Valid cases must admit and match their canonical bytes and SHA-256 digest. Invalid cases must report every listed code and path. Evolution pairs must produce the listed `UDL7xxx` issues. An implementation may report more issues, but it may not omit a listed issue.
176
+
177
+ Do not key behavior on diagnostic messages. Titles, details, and fixes can become clearer. Codes cannot change once published.
178
+
179
+ Keep parsing, validation, canonicalization, and evolution comparison separate. That split prevents a diff from judging a candidate that the validator would refuse on its own.
180
+
181
+ <!-- source: reference/canonical.md -->
182
+
183
+ # Canonical bytes
184
+
185
+ An admitted UDL document has one canonical byte sequence.
186
+
187
+ - Encode JSON as UTF-8 without a byte-order mark.
188
+ - Sort every object's keys by ascending UTF-16 code unit. Compare code units, not locale order or Unicode collation order.
189
+ - Preserve array order exactly as authored. Never sort an array.
190
+ - Indent nested values with two ASCII spaces. Write one ASCII space after each colon.
191
+ - Write empty objects as `{}` and empty arrays as `[]`.
192
+ - Serialize JSON numbers with JavaScript `JSON.stringify` semantics. An admitted integer uses base-10 digits with an optional leading minus and no leading zeros. Negative zero serializes as `0`. UDL money is not a JSON number. It is a base-10 integer minor-unit string paired with a currency code.
193
+ - Apply ECMAScript well-formed `JSON.stringify` string escaping. Escape U+0000 through U+001F. Escape every lone surrogate as `\uXXXX`. Write every other code point literally, including U+007F and U+2028.
194
+ - End the document with exactly one line feed byte, `0A`. Write no other trailing whitespace.
195
+
196
+ `serializeUdl(document)` validates and writes these bytes. `canonicalizeUdl(input)` parses, validates, and writes them. Canonicalizing canonical bytes returns the same bytes.
197
+
198
+ `canonicalDigest(document)` computes SHA-256 over the canonical UTF-8 bytes and returns a promise for the lowercase hexadecimal digest. `udl canon file.udl --digest` prints that digest. It does not hash the source bytes before canonicalization.
199
+
200
+ <!-- source: reference/clauses.md -->
201
+
202
+ # Clause reference
203
+
204
+ This page lists every entry in `udlClauseVocabulary`. The examples are copied from admitted documents under `conformance/valid`.
205
+
206
+ ## agent description
207
+
208
+ - Scope: action
209
+ - UDL target: `agentDescription`
210
+ - Cardinality: one
211
+ - Linear outputs: none
212
+ - Effects: none
213
+ - Law: Requirements-as-data law and closure law
214
+ - Conformance source: `agent-description.udl`
215
+
216
+ ```json
217
+ "Close a note that has already been filed. Takes the note id and nothing else, and moves no money."
218
+ ```
219
+
220
+ ## capture input
221
+
222
+ - Scope: action
223
+ - UDL target: `captureInput`
224
+ - Cardinality: one
225
+ - Linear outputs: none
226
+ - Effects: none
227
+ - Law: Requirements-as-data law and closure law
228
+ - Conformance source: `compiled-crowdfunding.udl`
229
+
230
+ ```json
231
+ {
232
+ "snapshotEvidenceReference": "evidenceReference"
233
+ }
234
+ ```
235
+
236
+ ## commit
237
+
238
+ - Scope: action
239
+ - UDL target: `commit`
240
+ - Cardinality: one
241
+ - Linear outputs: none
242
+ - Effects: none
243
+ - Law: Requirements-as-data law and closure law
244
+ - Conformance source: `commerce-escrow.udl`
245
+
246
+ A commit has no separate effect row. The committing action consumes the quote through its `moves.*` row.
247
+
248
+ ```json
249
+ "quote"
250
+ ```
251
+
252
+ ## quote
253
+
254
+ - Scope: action
255
+ - UDL target: `quote`
256
+ - Cardinality: one
257
+ - Linear outputs: `netRef`
258
+ - Effects: holds.quote per clause; schedules.expiry per clause
259
+ - Law: Requirements-as-data law and closure law
260
+ - Conformance source: `commerce-escrow.udl`
261
+
262
+ ```json
263
+ {
264
+ "baseField": "amount",
265
+ "chargeRef": "unwindPenalty",
266
+ "charges": [
267
+ {
268
+ "bps": 0
269
+ }
270
+ ],
271
+ "expires": {
272
+ "offset": "PT15M"
273
+ },
274
+ "fixes": ["amount", "buyerAccountId"],
275
+ "netDestinationField": "buyerAccountId",
276
+ "netRef": "unwindRefund"
277
+ }
278
+ ```
279
+
280
+ ## decided amount
281
+
282
+ - Scope: action
283
+ - UDL target: `decidedAmount`
284
+ - Cardinality: one
285
+ - Linear outputs: `field`
286
+ - Effects: none
287
+ - Law: Requirements-as-data law and closure law
288
+ - Conformance source: `compiled-watch-club.udl`
289
+
290
+ ```json
291
+ {
292
+ "boundField": "depositAmount",
293
+ "field": "damageAmount",
294
+ "remainderAction": "return_deposit"
295
+ }
296
+ ```
297
+
298
+ ## deadline
299
+
300
+ - Scope: action
301
+ - UDL target: `deadline`
302
+ - Cardinality: one
303
+ - Linear outputs: none
304
+ - Effects: schedules.deadline per clause
305
+ - Law: Time law and closure law
306
+ - Conformance source: `compiled-watch-club.udl`
307
+
308
+ ```json
309
+ {
310
+ "field": "clawbackAt"
311
+ }
312
+ ```
313
+
314
+ ## decision
315
+
316
+ - Scope: action
317
+ - UDL target: `decision`
318
+ - Cardinality: one
319
+ - Linear outputs: none
320
+ - Effects: decides.value from capability per clause
321
+ - Law: Requirements-as-data law and closure law
322
+ - Conformance source: `cards.udl`
323
+
324
+ ```json
325
+ {
326
+ "capability": "banking_or_card_issuing",
327
+ "deadlineMs": 1500,
328
+ "onTimeout": "decline"
329
+ }
330
+ ```
331
+
332
+ ## computes distribute
333
+
334
+ - Scope: action
335
+ - UDL target: `distribute`
336
+ - Cardinality: one
337
+ - Linear outputs: `amountRef`
338
+ - Effects: none
339
+ - Law: Requirements-as-data law and closure law
340
+ - Conformance source: `compiled-crowdfunding.udl`
341
+
342
+ ```json
343
+ {
344
+ "amountRef": "payoutShare",
345
+ "onZero": "skip_steps",
346
+ "pool": {
347
+ "from": "parent",
348
+ "path": "fields.distributableAmount"
349
+ },
350
+ "refField": "repaymentDistributionId",
351
+ "statuses": ["recorded", "paid"],
352
+ "weightField": "committedWeight"
353
+ }
354
+ ```
355
+
356
+ ## description
357
+
358
+ - Scope: action
359
+ - UDL target: `description`
360
+ - Cardinality: one
361
+ - Linear outputs: none
362
+ - Effects: none
363
+ - Law: One-sentence law, uniform object law, and naming law
364
+ - Conformance source: `cards.udl`
365
+
366
+ ```json
367
+ "Approves the customer to hold and use cards."
368
+ ```
369
+
370
+ ## due
371
+
372
+ - Scope: action
373
+ - UDL target: `due`
374
+ - Cardinality: one
375
+ - Linear outputs: none
376
+ - Effects: schedules.due per clause
377
+ - Law: Time law and closure law
378
+ - Conformance source: `cards.udl`
379
+
380
+ ```json
381
+ {
382
+ "field": "expiresAt"
383
+ }
384
+ ```
385
+
386
+ ## earnable
387
+
388
+ - Scope: action
389
+ - UDL target: `earnable`
390
+ - Cardinality: one
391
+ - Linear outputs: none
392
+ - Effects: none
393
+ - Law: Requirements-as-data law and closure law
394
+ - Conformance source: `cards.udl`
395
+
396
+ ```json
397
+ true
398
+ ```
399
+
400
+ ## event name
401
+
402
+ - Scope: action
403
+ - UDL target: `eventName`
404
+ - Cardinality: one
405
+ - Linear outputs: none
406
+ - Effects: none
407
+ - Law: Event law and naming law
408
+ - Conformance source: `cards.udl`
409
+
410
+ ```json
411
+ "card.issued"
412
+ ```
413
+
414
+ ## examples
415
+
416
+ - Scope: action
417
+ - UDL target: `examples`
418
+ - Cardinality: many
419
+ - Linear outputs: none
420
+ - Effects: none
421
+ - Law: Requirements-as-data law and closure law
422
+ - Conformance source: `cards.udl`
423
+
424
+ ```json
425
+ [
426
+ {
427
+ "input": {
428
+ "cardholderId": "chd_sandbox_customer0001",
429
+ "tenantId": "ten_sandbox_cards000001"
430
+ },
431
+ "name": "activate_approved_cardholder"
432
+ }
433
+ ]
434
+ ```
435
+
436
+ ## input
437
+
438
+ - Scope: action
439
+ - UDL target: `input`
440
+ - Cardinality: one
441
+ - Linear outputs: none
442
+ - Effects: none
443
+ - Law: Requirements-as-data law and closure law
444
+ - Conformance source: `cards.udl`
445
+
446
+ ```json
447
+ {
448
+ "additionalProperties": false,
449
+ "properties": {
450
+ "reason": {
451
+ "maxLength": 180,
452
+ "minLength": 1,
453
+ "type": "string"
454
+ }
455
+ },
456
+ "required": ["reason"],
457
+ "type": "object"
458
+ }
459
+ ```
460
+
461
+ ## moves
462
+
463
+ - Scope: action
464
+ - UDL target: `moves`
465
+ - Cardinality: many
466
+ - Linear outputs: none
467
+ - Effects: moves.movement class per element; holds.reserve per element
468
+ - Law: One-spine law and closure law
469
+ - Conformance source: `agent-description.udl`
470
+
471
+ ```json
472
+ []
473
+ ```
474
+
475
+ ## payout
476
+
477
+ - Scope: action
478
+ - UDL target: `payout`
479
+ - Cardinality: one
480
+ - Linear outputs: none
481
+ - Effects: moves.payout.external per clause
482
+ - Law: One-spine law and closure law
483
+ - Conformance source: `compiled-watch-club.udl`
484
+
485
+ ```json
486
+ {
487
+ "amount": "refs.netPayable",
488
+ "beneficiaryField": "payoutBeneficiaryId",
489
+ "beneficiaryPartyField": "payoutDestinationAccountId",
490
+ "capture": "payoutId",
491
+ "currencyField": "currency",
492
+ "sourceAccountField": "clubAccountId",
493
+ "speed": "standard"
494
+ }
495
+ ```
496
+
497
+ ## port
498
+
499
+ - Scope: action
500
+ - UDL target: `port`
501
+ - Cardinality: one
502
+ - Linear outputs: none
503
+ - Effects: decides.tenant_port per clause
504
+ - Law: Requirements-as-data law and closure law
505
+ - Conformance source: `compiled-crowdfunding.udl`
506
+
507
+ ```json
508
+ {
509
+ "allowedParties": ["beneficiary"]
510
+ }
511
+ ```
512
+
513
+ ## principal
514
+
515
+ - Scope: action
516
+ - UDL target: `principal`
517
+ - Cardinality: one
518
+ - Linear outputs: none
519
+ - Effects: none
520
+ - Law: Requirements-as-data law and closure law
521
+ - Conformance source: `complete-contract.udl`
522
+
523
+ ```json
524
+ "user_session"
525
+ ```
526
+
527
+ ## public action
528
+
529
+ - Scope: action
530
+ - UDL target: `publicAction`
531
+ - Cardinality: one
532
+ - Linear outputs: none
533
+ - Effects: none
534
+ - Law: Event law and naming law
535
+ - Conformance source: `compiled-crowdfunding.udl`
536
+
537
+ ```json
538
+ "abandonLenderCommitment"
539
+ ```
540
+
541
+ ## reconcile
542
+
543
+ - Scope: action
544
+ - UDL target: `reconcile`
545
+ - Cardinality: many
546
+ - Linear outputs: none
547
+ - Effects: reads.reconcile per element
548
+ - Law: Requirements-as-data law and closure law
549
+ - Conformance source: `compiled-watch-club.udl`
550
+
551
+ `exception.amountField` must name a required money field on the exception child. `exception.reasonField` must name a required text field on that child. UDL evolution supplies no default for either name.
552
+
553
+ ```json
554
+ [
555
+ {
556
+ "amount": "refs.netPayable",
557
+ "capture": "settlementEvidenceId",
558
+ "counterpartyRef": "payoutId",
559
+ "currencyField": "currency",
560
+ "direction": "debit",
561
+ "evidence": "statement_line",
562
+ "exception": {
563
+ "amountField": "amount",
564
+ "childInstrumentId": "seller_payout_debit_adjustment",
565
+ "maxOpen": 1,
566
+ "reasonField": "adjustmentReference",
567
+ "refField": "sellerPayoutId"
568
+ },
569
+ "match": {
570
+ "law": "exact"
571
+ },
572
+ "within": {
573
+ "offset": "P30D"
574
+ }
575
+ }
576
+ ]
577
+ ```
578
+
579
+ ## computes remainder
580
+
581
+ - Scope: action
582
+ - UDL target: `remainder`
583
+ - Cardinality: one
584
+ - Linear outputs: `amountRef`
585
+ - Effects: none
586
+ - Law: Requirements-as-data law and closure law
587
+ - Conformance source: `complete-contract.udl`
588
+
589
+ ```json
590
+ {
591
+ "amountRef": "remainingAmount",
592
+ "onZero": "refuse",
593
+ "totalPath": "fields.amount"
594
+ }
595
+ ```
596
+
597
+ ## requires aggregate
598
+
599
+ - Scope: action
600
+ - UDL target: `requiresAggregate`
601
+ - Cardinality: many
602
+ - Linear outputs: none
603
+ - Effects: reads.requires_aggregate per clause
604
+ - Law: Requirements-as-data law and closure law
605
+ - Conformance source: `compiled-crowdfunding.udl`
606
+
607
+ ```json
608
+ [
609
+ {
610
+ "check": {
611
+ "amountField": "amount",
612
+ "kind": "sum_exactly",
613
+ "targetField": "installment1Amount"
614
+ },
615
+ "instrumentId": "borrower_loan_installment_1_payment",
616
+ "over": "children",
617
+ "refField": "borrowerLoanId",
618
+ "statuses": ["paid"]
619
+ }
620
+ ]
621
+ ```
622
+
623
+ ## requires checks
624
+
625
+ - Scope: action
626
+ - UDL target: `requiresChecks`
627
+ - Cardinality: many
628
+ - Linear outputs: none
629
+ - Effects: reads.requires_checks per clause
630
+ - Law: Requirements-as-data law and closure law
631
+ - Conformance source: `complete-contract.udl`
632
+
633
+ ```json
634
+ [
635
+ {
636
+ "checkKind": "identity_verification",
637
+ "family": "national_identity",
638
+ "maxAge": "P30D",
639
+ "statuses": ["completed"],
640
+ "subjectField": "subjectId"
641
+ }
642
+ ]
643
+ ```
644
+
645
+ ## requires drained
646
+
647
+ - Scope: action
648
+ - UDL target: `requiresDrainedAccount`
649
+ - Cardinality: one
650
+ - Linear outputs: none
651
+ - Effects: none
652
+ - Law: Requirements-as-data law and closure law
653
+ - Conformance source: `commerce-escrow.udl`
654
+
655
+ ```json
656
+ {
657
+ "path": "refs.escrowAccountId"
658
+ }
659
+ ```
660
+
661
+ ## requires exposure
662
+
663
+ - Scope: action
664
+ - UDL target: `requiresExposure`
665
+ - Cardinality: many
666
+ - Linear outputs: none
667
+ - Effects: none
668
+ - Law: Requirements-as-data law and closure law
669
+ - Conformance source: `compiled-crowdfunding.udl`
670
+
671
+ ```json
672
+ [
673
+ {
674
+ "amountField": "amount",
675
+ "anchorField": "borrowerLoanId",
676
+ "capField": "installment1Amount",
677
+ "capOnAnchor": true,
678
+ "childInstrumentId": "borrower_loan_installment_1_payment",
679
+ "statuses": ["paid"]
680
+ }
681
+ ]
682
+ ```
683
+
684
+ ## requires refs
685
+
686
+ - Scope: action
687
+ - UDL target: `requiresRefs`
688
+ - Cardinality: many
689
+ - Linear outputs: none
690
+ - Effects: reads.requires_refs per clause
691
+ - Law: Requirements-as-data law and closure law
692
+ - Conformance source: `cards.udl`
693
+
694
+ ```json
695
+ [
696
+ {
697
+ "field": "cardholderId",
698
+ "statuses": ["active"]
699
+ }
700
+ ]
701
+ ```
702
+
703
+ ## sandbox failure point
704
+
705
+ - Scope: action
706
+ - UDL target: `sandboxFailurePoint`
707
+ - Cardinality: one
708
+ - Linear outputs: none
709
+ - Effects: none
710
+ - Law: Requirements-as-data law and closure law
711
+ - Conformance source: `commerce-escrow.udl`
712
+
713
+ ```json
714
+ "funding"
715
+ ```
716
+
717
+ ## sets at
718
+
719
+ - Scope: action
720
+ - UDL target: `setsAt`
721
+ - Cardinality: one
722
+ - Linear outputs: none
723
+ - Effects: none
724
+ - Law: Time law and closure law
725
+ - Conformance source: `compiled-crowdfunding.udl`
726
+
727
+ ```json
728
+ {
729
+ "field": "installment1DelinquentAfter",
730
+ "marker": true,
731
+ "offset": "PT1S"
732
+ }
733
+ ```
734
+
735
+ ## computes signed_sum
736
+
737
+ - Scope: action
738
+ - UDL target: `signedSum`
739
+ - Cardinality: one
740
+ - Linear outputs: `amountRef`
741
+ - Effects: none
742
+ - Law: Requirements-as-data law and closure law
743
+ - Conformance source: `compiled-watch-club.udl`
744
+
745
+ ```json
746
+ {
747
+ "amountRef": "netPayable",
748
+ "onNegative": "refuse",
749
+ "onZero": "refuse",
750
+ "sources": [
751
+ {
752
+ "amountField": "amount",
753
+ "instrumentId": "seller_payout_capture_entry",
754
+ "refField": "sellerPayoutId",
755
+ "sign": "add",
756
+ "statuses": ["accrued"],
757
+ "subtotalRef": "grossCaptureAmount"
758
+ },
759
+ {
760
+ "amountField": "amount",
761
+ "instrumentId": "seller_payout_credit_adjustment",
762
+ "refField": "sellerPayoutId",
763
+ "sign": "add",
764
+ "statuses": ["applied"],
765
+ "subtotalRef": "creditAdjustmentAmount"
766
+ },
767
+ {
768
+ "amountField": "amount",
769
+ "instrumentId": "seller_payout_debit_adjustment",
770
+ "refField": "sellerPayoutId",
771
+ "sign": "subtract",
772
+ "statuses": ["applied"],
773
+ "subtotalRef": "debitAdjustmentAmount"
774
+ }
775
+ ]
776
+ }
777
+ ```
778
+
779
+ ## steps
780
+
781
+ - Scope: action
782
+ - UDL target: `steps`
783
+ - Cardinality: many
784
+ - Linear outputs: none
785
+ - Effects: none
786
+ - Law: One-spine law and closure law
787
+ - Conformance source: `agent-description.udl`
788
+
789
+ ```json
790
+ []
791
+ ```
792
+
793
+ ## summary
794
+
795
+ - Scope: action
796
+ - UDL target: `summary`
797
+ - Cardinality: one
798
+ - Linear outputs: none
799
+ - Effects: none
800
+ - Law: One-sentence law, uniform object law, and naming law
801
+ - Conformance source: `agent-description.udl`
802
+
803
+ ```json
804
+ "Close the note."
805
+ ```
806
+
807
+ ## updates
808
+
809
+ - Scope: action
810
+ - UDL target: `updates`
811
+ - Cardinality: many
812
+ - Linear outputs: none
813
+ - Effects: none
814
+ - Law: Requirements-as-data law and closure law
815
+ - Conformance source: `commerce-escrow.udl`
816
+
817
+ ```json
818
+ ["escrowOrderId"]
819
+ ```
820
+
821
+ ## notify
822
+
823
+ - Scope: action
824
+ - UDL target: `effects.notifies`
825
+ - Cardinality: many
826
+ - Linear outputs: none
827
+ - Effects: notifies.value from channel per element
828
+ - Law: Requirements-as-data law and closure law
829
+ - Conformance source: `effect-signatures.udl`
830
+
831
+ ```json
832
+ [
833
+ {
834
+ "channel": "email",
835
+ "role": "beneficiary",
836
+ "signature": "notifies.email",
837
+ "source": "effects.notifies[0]"
838
+ }
839
+ ]
840
+ ```
841
+
842
+ ## agent description
843
+
844
+ - Scope: instrument
845
+ - UDL target: `agentDescription`
846
+ - Cardinality: one
847
+ - Linear outputs: none
848
+ - Effects: none
849
+ - Law: Requirements-as-data law and closure law
850
+ - Conformance source: `agent-description.udl`
851
+
852
+ ```json
853
+ "Close a note that has already been filed. Takes the note id and nothing else, and moves no money."
854
+ ```
855
+
856
+ ## aggregate invariants
857
+
858
+ - Scope: instrument
859
+ - UDL target: `aggregateInvariants`
860
+ - Cardinality: many
861
+ - Linear outputs: none
862
+ - Effects: none
863
+ - Law: Closure law
864
+ - Conformance source: `compiled-crowdfunding.udl`
865
+
866
+ ```json
867
+ [
868
+ {
869
+ "childField": "amount",
870
+ "childInstrumentId": "borrower_loan_installment_1_payment",
871
+ "childRefField": "borrowerLoanId",
872
+ "childStatuses": ["paid"],
873
+ "parentField": "installment1Amount"
874
+ },
875
+ {
876
+ "childField": "amount",
877
+ "childInstrumentId": "borrower_loan_installment_2_payment",
878
+ "childRefField": "borrowerLoanId",
879
+ "childStatuses": ["paid"],
880
+ "parentField": "installment2Amount"
881
+ }
882
+ ]
883
+ ```
884
+
885
+ ## caller parked states
886
+
887
+ - Scope: instrument
888
+ - UDL target: `callerParkedStates`
889
+ - Cardinality: one
890
+ - Linear outputs: none
891
+ - Effects: none
892
+ - Law: Time law and closure law
893
+ - Conformance source: `cards.udl`
894
+
895
+ ```json
896
+ {
897
+ "active": "a cardholder in good standing stays active until the issuer or holder acts",
898
+ "pending": "activation follows the issuer's verification outcome",
899
+ "suspended": "reinstatement or closure is an issuer decision"
900
+ }
901
+ ```
902
+
903
+ ## description
904
+
905
+ - Scope: instrument
906
+ - UDL target: `description`
907
+ - Cardinality: one
908
+ - Linear outputs: none
909
+ - Effects: none
910
+ - Law: One-sentence law, uniform object law, and naming law
911
+ - Conformance source: `cards.udl`
912
+
913
+ ```json
914
+ "Approves the customer to hold and use cards."
915
+ ```
916
+
917
+ ## dials
918
+
919
+ - Scope: instrument
920
+ - UDL target: `dials`
921
+ - Cardinality: many
922
+ - Linear outputs: none
923
+ - Effects: none
924
+ - Law: Requirements-as-data law and closure law
925
+ - Conformance source: `cards.udl`
926
+
927
+ ```json
928
+ [
929
+ {
930
+ "field": "expiresAt",
931
+ "key": "authorization_window",
932
+ "kind": "window",
933
+ "maxOffset": "P30D",
934
+ "summary": "Grace beyond the authorization expiry timestamp before an uncaptured hold expires.",
935
+ "title": "Authorization window"
936
+ },
937
+ {
938
+ "action": "approve",
939
+ "key": "policy_decision_deadline_ms",
940
+ "kind": "decision_deadline_ms",
941
+ "maxMs": 5000,
942
+ "minMs": 500,
943
+ "summary": "How long approve waits for the card policy's just-in-time decision before the timeout default declines.",
944
+ "title": "Policy decision deadline"
945
+ }
946
+ ]
947
+ ```
948
+
949
+ ## distinct parties
950
+
951
+ - Scope: instrument
952
+ - UDL target: `distinctParties`
953
+ - Cardinality: one
954
+ - Linear outputs: none
955
+ - Effects: none
956
+ - Law: Closure law
957
+ - Conformance source: `compiled-watch-club.udl`
958
+
959
+ ```json
960
+ true
961
+ ```
962
+
963
+ ## computes derived
964
+
965
+ - Scope: instrument
966
+ - UDL target: `derivedAmounts`
967
+ - Cardinality: many
968
+ - Linear outputs: none
969
+ - Effects: none
970
+ - Law: One-spine law and closure law
971
+ - Conformance source: `compiled-crowdfunding.udl`
972
+
973
+ ```json
974
+ [
975
+ {
976
+ "field": "platformFee",
977
+ "rounding": "floor",
978
+ "rule": {
979
+ "bps": 200,
980
+ "kind": "percentage_of"
981
+ },
982
+ "sourceField": "principalAmount"
983
+ }
984
+ ]
985
+ ```
986
+
987
+ ## computes fees
988
+
989
+ - Scope: instrument
990
+ - UDL target: `feeRules`
991
+ - Cardinality: many
992
+ - Linear outputs: none
993
+ - Effects: none
994
+ - Law: One-spine law and closure law
995
+ - Conformance source: `compiled-watch-club.udl`
996
+
997
+ ```json
998
+ [
999
+ {
1000
+ "amountField": "checkoutFee",
1001
+ "baseField": "purchasePrice",
1002
+ "bearerField": "memberAccountId",
1003
+ "position": "on_top",
1004
+ "rule": {
1005
+ "currencyField": "currency",
1006
+ "field": "checkoutFee",
1007
+ "kind": "exact"
1008
+ }
1009
+ },
1010
+ {
1011
+ "amountField": "carvedFeeAmount",
1012
+ "baseField": "purchasePrice",
1013
+ "bearerField": "sellerAccountId",
1014
+ "position": "carved",
1015
+ "rule": {
1016
+ "kind": "tiered",
1017
+ "tiers": [
1018
+ {
1019
+ "fromInclusive": "0",
1020
+ "rule": {
1021
+ "bps": 100,
1022
+ "kind": "bps"
1023
+ },
1024
+ "toExclusive": "10000"
1025
+ },
1026
+ {
1027
+ "fromInclusive": "10000",
1028
+ "rule": {
1029
+ "currencyField": "currency",
1030
+ "field": "highValueFee",
1031
+ "kind": "exact"
1032
+ }
1033
+ }
1034
+ ]
1035
+ }
1036
+ }
1037
+ ]
1038
+ ```
1039
+
1040
+ ## id prefix
1041
+
1042
+ - Scope: instrument
1043
+ - UDL target: `idPrefix`
1044
+ - Cardinality: one
1045
+ - Linear outputs: none
1046
+ - Effects: none
1047
+ - Law: One-sentence law, uniform object law, and naming law
1048
+ - Conformance source: `agent-description.udl`
1049
+
1050
+ ```json
1051
+ "note"
1052
+ ```
1053
+
1054
+ ## nav
1055
+
1056
+ - Scope: instrument
1057
+ - UDL target: `nav`
1058
+ - Cardinality: many
1059
+ - Linear outputs: none
1060
+ - Effects: none
1061
+ - Law: One-sentence law, uniform object law, and naming law
1062
+ - Conformance source: `cards.udl`
1063
+
1064
+ ```json
1065
+ ["Blueprints", "Cardholders"]
1066
+ ```
1067
+
1068
+ ## partitions
1069
+
1070
+ - Scope: instrument
1071
+ - UDL target: `partitions`
1072
+ - Cardinality: many
1073
+ - Linear outputs: none
1074
+ - Effects: none
1075
+ - Law: One-spine law and closure law
1076
+ - Conformance source: `compiled-crowdfunding.udl`
1077
+
1078
+ ```json
1079
+ [
1080
+ {
1081
+ "pieceFields": ["installment1Amount", "installment2Amount"],
1082
+ "totalField": "principalAmount"
1083
+ }
1084
+ ]
1085
+ ```
1086
+
1087
+ ## subject
1088
+
1089
+ - Scope: instrument
1090
+ - UDL target: `subject`
1091
+ - Cardinality: one
1092
+ - Linear outputs: none
1093
+ - Effects: none
1094
+ - Law: Closure law
1095
+ - Conformance source: `commerce-escrow.udl`
1096
+
1097
+ ```json
1098
+ {
1099
+ "kinds": ["vehicle", "merchandise"]
1100
+ }
1101
+ ```
1102
+
1103
+ ## summary
1104
+
1105
+ - Scope: instrument
1106
+ - UDL target: `summary`
1107
+ - Cardinality: one
1108
+ - Linear outputs: none
1109
+ - Effects: none
1110
+ - Law: One-sentence law, uniform object law, and naming law
1111
+ - Conformance source: `agent-description.udl`
1112
+
1113
+ ```json
1114
+ "Close the note."
1115
+ ```
1116
+
1117
+ ## surface visibility
1118
+
1119
+ - Scope: instrument
1120
+ - UDL target: `surfaceVisibility`
1121
+ - Cardinality: one
1122
+ - Linear outputs: none
1123
+ - Effects: none
1124
+ - Law: One-sentence law, uniform object law, and naming law
1125
+ - Conformance source: `complete-contract.udl`
1126
+
1127
+ ```json
1128
+ "public"
1129
+ ```
1130
+
1131
+ ## template id
1132
+
1133
+ - Scope: instrument
1134
+ - UDL target: `templateId`
1135
+ - Cardinality: one
1136
+ - Linear outputs: none
1137
+ - Effects: none
1138
+ - Law: One-sentence law, uniform object law, and naming law
1139
+ - Conformance source: `cards.udl`
1140
+
1141
+ ```json
1142
+ "wallet_cards"
1143
+ ```
1144
+
1145
+ ## title
1146
+
1147
+ - Scope: instrument
1148
+ - UDL target: `title`
1149
+ - Cardinality: one
1150
+ - Linear outputs: none
1151
+ - Effects: none
1152
+ - Law: One-sentence law, uniform object law, and naming law
1153
+ - Conformance source: `agent-description.udl`
1154
+
1155
+ ```json
1156
+ "Note"
1157
+ ```
1158
+
1159
+ ## update
1160
+
1161
+ - Scope: instrument
1162
+ - UDL target: `update`
1163
+ - Cardinality: one
1164
+ - Linear outputs: none
1165
+ - Effects: none
1166
+ - Law: Closure law
1167
+ - Conformance source: `cards.udl`
1168
+
1169
+ ```json
1170
+ {
1171
+ "examples": [
1172
+ {
1173
+ "input": {
1174
+ "cardholderId": "chd_sandbox_customer0001",
1175
+ "displayName": "Noura Al Saud",
1176
+ "email": "noura@example.test",
1177
+ "tenantId": "ten_sandbox_cards000001"
1178
+ },
1179
+ "name": "update_cardholder_contact"
1180
+ }
1181
+ ],
1182
+ "fields": ["displayName", "email", "phoneNumber"],
1183
+ "states": ["pending", "active", "suspended"]
1184
+ }
1185
+ ```
1186
+
1187
+ <!-- source: reference/diagnostics.md -->
1188
+
1189
+ # Diagnostic reference
1190
+
1191
+ Codes are stable. Titles and messages may become clearer without changing the code. Apply the listed fix, then validate the whole document again.
1192
+
1193
+ | Code | Family | Category | Title | Fix |
1194
+ | --------- | --------- | ----------------- | ------------------------------------------------------- | ------------------------------------------------------------------------------------------------------ |
1195
+ | `UDL1001` | admission | invalid_utf8 | Invalid UTF-8 | Encode the document as valid UTF-8. |
1196
+ | `UDL1002` | admission | invalid_json | Invalid JSON | Repair the JSON syntax before validation. |
1197
+ | `UDL1003` | admission | invalid_shape | Invalid document shape | Match the published UDL JSON Schema. |
1198
+ | `UDL1004` | admission | resource_limit | Resource limit exceeded | Reduce the source size, nesting, values, strings, references, or financial paths named by the message. |
1199
+ | `UDL2001` | document | invalid_semantics | Duplicate declaration | Give each declaration a unique name. |
1200
+ | `UDL2002` | document | invalid_semantics | Document law violation | Repair the declaration, subject contract, or derived effects named by the message. |
1201
+ | `UDL2005` | document | invalid_semantics | Derived effects mismatch | Regenerate the action effects from its clauses. |
1202
+ | `UDL3001` | lifecycle | invalid_semantics | Lifecycle is not closed | Declare every state and action transition, and make every state reachable. |
1203
+ | `UDL4001` | finance | invalid_semantics | Money graph violation | Balance every funded amount and close every hold on each lifecycle path. |
1204
+ | `UDL5001` | gates | invalid_semantics | Reference gate violation | Point the gate at a declared instrument, action, state, field, and reference. |
1205
+ | `UDL5002` | gates | invalid_semantics | Check requirement violation | Use a declared check with compatible evidence and recurrence. |
1206
+ | `UDL5003` | gates | invalid_semantics | Exposure gate violation | Use declared account and money fields for the exposure gate. |
1207
+ | `UDL5004` | gates | invalid_semantics | Aggregate law violation | Point the aggregate at compatible parent and child fields. |
1208
+ | `UDL5005` | gates | invalid_semantics | Settlement or payout violation | Use a declared settlement account and a compatible payout statement line. |
1209
+ | `UDL5006` | gates | invalid_semantics | Quote and commit violation | Declare one complete quote freeze set and one matching commit action. |
1210
+ | `UDL5007` | gates | invalid_semantics | Reconcile exception child violation | Name a declared child whose reference points back to this instrument. |
1211
+ | `UDL5008` | gates | invalid_semantics | Action clause violation | Repair the clause fields and keep incompatible clauses separate. |
1212
+ | `UDL5009` | gates | invalid_semantics | Reconcile exception amount field is missing or optional | Name the exception child's required money field in amountField. |
1213
+ | `UDL5010` | gates | invalid_semantics | Reconcile exception amount field has the wrong type | Point amountField at a money field declared by the exception child. |
1214
+ | `UDL5011` | gates | invalid_semantics | Reconcile exception reason field is missing or optional | Name the exception child's required text field in reasonField. |
1215
+ | `UDL5012` | gates | invalid_semantics | Reconcile exception reason field has the wrong type | Point reasonField at a required plain text field declared by the exception child. |
1216
+ | `UDL6001` | schema | invalid_semantics | Unsupported JSON Schema | Use only the sealed UDL JSON Schema subset. |
1217
+ | `UDL7001` | evolution | invalid_evolution | Stored contract changed | Keep stored identities and contracts unchanged, and add only allowed optional declarations. |
1218
+ | `UDL7002` | evolution | invalid_evolution | Version was not increased | Increase the product version for every semantic change. |
1219
+
1220
+ <!-- source: reference/cli.md -->
1221
+
1222
+ # Command reference
1223
+
1224
+ The installed `udl` binary exposes the following commands and exit codes.
1225
+
1226
+ ```text
1227
+ udl - the Universal Domain Language toolchain
1228
+
1229
+ usage:
1230
+ udl validate <file> parse <file> and report every issue found
1231
+ udl fmt <file> [--write] print the canonical form, or rewrite the file
1232
+ udl canon <file> [--digest] print canonical bytes, or their SHA-256 digest
1233
+ udl diff <live> <next> check <next> against the append-only law
1234
+ udl explain UDL#### explain one stable diagnostic code
1235
+ udl help print this
1236
+
1237
+ exit codes:
1238
+ 0 the document is admissible, or the change is additive
1239
+ 1 the document was refused, or the change breaks the append-only law
1240
+ 2 the command line was wrong, or a file could not be read
1241
+ ```