@hyperscale0/hsx 1.0.0-alpha.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/AUTHORS +8 -0
- package/CHANGELOG.md +59 -0
- package/LICENSE +661 -0
- package/LICENSING.md +52 -0
- package/README.md +170 -0
- package/SECURITY.md +47 -0
- package/TRADEMARKS.md +35 -0
- package/bin/hsx.ts +15 -0
- package/dist/bin/hsx.d.ts +7 -0
- package/dist/bin/hsx.d.ts.map +1 -0
- package/dist/bin/hsx.js +14 -0
- package/dist/bin/hsx.js.map +1 -0
- package/dist/src/ast.d.ts +172 -0
- package/dist/src/ast.d.ts.map +1 -0
- package/dist/src/ast.js +22 -0
- package/dist/src/ast.js.map +1 -0
- package/dist/src/check.d.ts +11 -0
- package/dist/src/check.d.ts.map +1 -0
- package/dist/src/check.js +1214 -0
- package/dist/src/check.js.map +1 -0
- package/dist/src/cli.d.ts +20 -0
- package/dist/src/cli.d.ts.map +1 -0
- package/dist/src/cli.js +137 -0
- package/dist/src/cli.js.map +1 -0
- package/dist/src/compile.d.ts +39 -0
- package/dist/src/compile.d.ts.map +1 -0
- package/dist/src/compile.js +59 -0
- package/dist/src/compile.js.map +1 -0
- package/dist/src/index.d.ts +9 -0
- package/dist/src/index.d.ts.map +1 -0
- package/dist/src/index.js +7 -0
- package/dist/src/index.js.map +1 -0
- package/dist/src/lex.d.ts +23 -0
- package/dist/src/lex.d.ts.map +1 -0
- package/dist/src/lex.js +125 -0
- package/dist/src/lex.js.map +1 -0
- package/dist/src/lower.d.ts +93 -0
- package/dist/src/lower.d.ts.map +1 -0
- package/dist/src/lower.js +2081 -0
- package/dist/src/lower.js.map +1 -0
- package/dist/src/model.d.ts +307 -0
- package/dist/src/model.d.ts.map +1 -0
- package/dist/src/model.js +15 -0
- package/dist/src/model.js.map +1 -0
- package/dist/src/parse.d.ts +19 -0
- package/dist/src/parse.d.ts.map +1 -0
- package/dist/src/parse.js +484 -0
- package/dist/src/parse.js.map +1 -0
- package/dist/src/version.d.ts +16 -0
- package/dist/src/version.d.ts.map +1 -0
- package/dist/src/version.js +16 -0
- package/dist/src/version.js.map +1 -0
- package/package.json +79 -0
- package/spec/hsx-ir.schema.json +522 -0
- package/src/ast.ts +231 -0
- package/src/check.ts +1699 -0
- package/src/cli.ts +173 -0
- package/src/compile.ts +98 -0
- package/src/index.ts +16 -0
- package/src/lex.ts +161 -0
- package/src/lower.ts +2619 -0
- package/src/model.ts +340 -0
- package/src/parse.ts +580 -0
- package/src/version.ts +17 -0
|
@@ -0,0 +1,522 @@
|
|
|
1
|
+
{
|
|
2
|
+
"$schema": "https://json-schema.org/draft/2020-12/schema",
|
|
3
|
+
"$id": "https://github.com/hyperscale0/hyperscale-hsx/spec/hsx-ir.schema.json",
|
|
4
|
+
"title": "HSX compile artifacts",
|
|
5
|
+
"description": "What `compile()` produces when the verdict is `valid` or `warning`, and what `hsx build` writes: the HSX-JSON IR document a runtime executes, plus the congruent Business Frame that describes the same product in business terms. This schema covers what the compiler EMITS. A runtime may accept a wider grammar; nothing the compiler emits may fall outside this file.",
|
|
6
|
+
"type": "object",
|
|
7
|
+
"required": ["document", "frame"],
|
|
8
|
+
"additionalProperties": false,
|
|
9
|
+
"properties": {
|
|
10
|
+
"document": { "$ref": "#/$defs/document" },
|
|
11
|
+
"frame": { "$ref": "#/$defs/frame" }
|
|
12
|
+
},
|
|
13
|
+
|
|
14
|
+
"$defs": {
|
|
15
|
+
"snakeName": {
|
|
16
|
+
"type": "string",
|
|
17
|
+
"minLength": 1,
|
|
18
|
+
"maxLength": 48,
|
|
19
|
+
"pattern": "^[a-z][a-z0-9_]*$"
|
|
20
|
+
},
|
|
21
|
+
"camelName": {
|
|
22
|
+
"type": "string",
|
|
23
|
+
"minLength": 1,
|
|
24
|
+
"maxLength": 48,
|
|
25
|
+
"pattern": "^[a-z][A-Za-z0-9]*$"
|
|
26
|
+
},
|
|
27
|
+
"endpoint": {
|
|
28
|
+
"description": "A party name, or one of the two endpoints every settlement has without declaring them: `platform` and `escrow`.",
|
|
29
|
+
"type": "string",
|
|
30
|
+
"minLength": 1,
|
|
31
|
+
"maxLength": 48
|
|
32
|
+
},
|
|
33
|
+
"isoDuration": {
|
|
34
|
+
"description": "A fixed ISO-8601 duration. Calendar months never appear: they drift, so they cannot anchor an exact money deadline.",
|
|
35
|
+
"type": "string",
|
|
36
|
+
"minLength": 1,
|
|
37
|
+
"maxLength": 24,
|
|
38
|
+
"pattern": "^P([0-9]+[WDHMS]|T[0-9]+[HMS])"
|
|
39
|
+
},
|
|
40
|
+
"prose": { "type": "string", "minLength": 1, "maxLength": 400 },
|
|
41
|
+
|
|
42
|
+
"document": {
|
|
43
|
+
"title": "HSX-JSON IR document",
|
|
44
|
+
"description": "One compiled program. Every settlement in the source becomes one noun; every noun carries its money fields, its conservation partitions, and one verb per admissible lifecycle step.",
|
|
45
|
+
"type": "object",
|
|
46
|
+
"required": ["hsx", "nouns", "product", "title"],
|
|
47
|
+
"additionalProperties": false,
|
|
48
|
+
"properties": {
|
|
49
|
+
"hsx": {
|
|
50
|
+
"description": "The IR format version, exported as `HSX_IR_VERSION`. A consumer reads this integer to decide whether it understands the document.",
|
|
51
|
+
"const": 1
|
|
52
|
+
},
|
|
53
|
+
"product": {
|
|
54
|
+
"description": "The program name from the `program` header.",
|
|
55
|
+
"$ref": "#/$defs/snakeName"
|
|
56
|
+
},
|
|
57
|
+
"title": {
|
|
58
|
+
"description": "The program's human title, from the header string or derived from its name.",
|
|
59
|
+
"type": "string",
|
|
60
|
+
"minLength": 1,
|
|
61
|
+
"maxLength": 80
|
|
62
|
+
},
|
|
63
|
+
"subjects": {
|
|
64
|
+
"description": "One entry per declared asset: the non-money thing the settlements are about.",
|
|
65
|
+
"type": "array",
|
|
66
|
+
"maxItems": 6,
|
|
67
|
+
"items": {
|
|
68
|
+
"type": "object",
|
|
69
|
+
"required": ["kind", "title", "value"],
|
|
70
|
+
"additionalProperties": false,
|
|
71
|
+
"properties": {
|
|
72
|
+
"kind": { "$ref": "#/$defs/snakeName" },
|
|
73
|
+
"title": { "type": "string", "minLength": 1, "maxLength": 60 },
|
|
74
|
+
"value": { "enum": ["none", "optional", "required"] }
|
|
75
|
+
}
|
|
76
|
+
}
|
|
77
|
+
},
|
|
78
|
+
"nouns": {
|
|
79
|
+
"type": "array",
|
|
80
|
+
"maxItems": 8,
|
|
81
|
+
"items": { "$ref": "#/$defs/noun" }
|
|
82
|
+
}
|
|
83
|
+
}
|
|
84
|
+
},
|
|
85
|
+
|
|
86
|
+
"noun": {
|
|
87
|
+
"description": "One lowered settlement.",
|
|
88
|
+
"type": "object",
|
|
89
|
+
"required": ["id", "summary", "title", "verbs"],
|
|
90
|
+
"additionalProperties": false,
|
|
91
|
+
"properties": {
|
|
92
|
+
"id": {
|
|
93
|
+
"description": "The settlement's own name. Settlement names are noun ids; nothing renames them.",
|
|
94
|
+
"$ref": "#/$defs/snakeName"
|
|
95
|
+
},
|
|
96
|
+
"title": { "type": "string", "minLength": 1, "maxLength": 60 },
|
|
97
|
+
"summary": { "type": "string", "minLength": 1, "maxLength": 200 },
|
|
98
|
+
"desc": { "type": "string", "minLength": 1, "maxLength": 400 },
|
|
99
|
+
"escrow": {
|
|
100
|
+
"description": "Present and true when this settlement takes custody of money in its own escrow account.",
|
|
101
|
+
"const": true
|
|
102
|
+
},
|
|
103
|
+
"distinctParties": {
|
|
104
|
+
"description": "Present and true when two of this settlement's roles must be different parties at runtime.",
|
|
105
|
+
"const": true
|
|
106
|
+
},
|
|
107
|
+
"actors": {
|
|
108
|
+
"type": "object",
|
|
109
|
+
"propertyNames": { "$ref": "#/$defs/snakeName" },
|
|
110
|
+
"additionalProperties": { "enum": ["payer", "beneficiary", "party"] }
|
|
111
|
+
},
|
|
112
|
+
"fields": {
|
|
113
|
+
"description": "Every value an instance stores. `money` is a positive minor-unit integer; `date` is required, `date?` optional.",
|
|
114
|
+
"type": "object",
|
|
115
|
+
"propertyNames": { "$ref": "#/$defs/camelName" },
|
|
116
|
+
"additionalProperties": {
|
|
117
|
+
"type": "object",
|
|
118
|
+
"required": ["desc", "type"],
|
|
119
|
+
"additionalProperties": false,
|
|
120
|
+
"properties": {
|
|
121
|
+
"desc": { "type": "string", "minLength": 1, "maxLength": 200 },
|
|
122
|
+
"type": { "enum": ["money", "date", "date?"] }
|
|
123
|
+
}
|
|
124
|
+
}
|
|
125
|
+
},
|
|
126
|
+
"partitions": {
|
|
127
|
+
"description": "Conservation laws over stored amounts: the piece fields sum exactly to the total field, proven at create admission before any money moves.",
|
|
128
|
+
"type": "array",
|
|
129
|
+
"maxItems": 4,
|
|
130
|
+
"items": {
|
|
131
|
+
"type": "object",
|
|
132
|
+
"required": ["pieces", "total"],
|
|
133
|
+
"additionalProperties": false,
|
|
134
|
+
"properties": {
|
|
135
|
+
"pieces": {
|
|
136
|
+
"type": "array",
|
|
137
|
+
"minItems": 2,
|
|
138
|
+
"maxItems": 12,
|
|
139
|
+
"items": { "$ref": "#/$defs/camelName" }
|
|
140
|
+
},
|
|
141
|
+
"total": { "$ref": "#/$defs/camelName" }
|
|
142
|
+
}
|
|
143
|
+
}
|
|
144
|
+
},
|
|
145
|
+
"verbs": {
|
|
146
|
+
"description": "One entry per admissible lifecycle step. `create` is always present and is the only verb with no `from`.",
|
|
147
|
+
"type": "object",
|
|
148
|
+
"minProperties": 1,
|
|
149
|
+
"propertyNames": { "$ref": "#/$defs/snakeName" },
|
|
150
|
+
"additionalProperties": { "$ref": "#/$defs/verb" }
|
|
151
|
+
}
|
|
152
|
+
}
|
|
153
|
+
},
|
|
154
|
+
|
|
155
|
+
"verb": {
|
|
156
|
+
"type": "object",
|
|
157
|
+
"required": ["summary", "to"],
|
|
158
|
+
"additionalProperties": false,
|
|
159
|
+
"properties": {
|
|
160
|
+
"from": {
|
|
161
|
+
"description": "States this verb may run in. Absent on `create`.",
|
|
162
|
+
"type": "array",
|
|
163
|
+
"minItems": 1,
|
|
164
|
+
"maxItems": 6,
|
|
165
|
+
"items": { "$ref": "#/$defs/snakeName" }
|
|
166
|
+
},
|
|
167
|
+
"to": {
|
|
168
|
+
"description": "The state the instance is in once this verb succeeds.",
|
|
169
|
+
"$ref": "#/$defs/snakeName"
|
|
170
|
+
},
|
|
171
|
+
"summary": { "type": "string", "minLength": 1, "maxLength": 200 },
|
|
172
|
+
"moneyEvent": {
|
|
173
|
+
"description": "The Business Frame money event this verb's moves belong to.",
|
|
174
|
+
"$ref": "#/$defs/snakeName"
|
|
175
|
+
},
|
|
176
|
+
"moves": {
|
|
177
|
+
"description": "The ledger operations this verb performs, in order, as one atomic batch.",
|
|
178
|
+
"type": "array",
|
|
179
|
+
"minItems": 1,
|
|
180
|
+
"maxItems": 12,
|
|
181
|
+
"items": { "$ref": "#/$defs/move" }
|
|
182
|
+
},
|
|
183
|
+
"due": {
|
|
184
|
+
"description": "The verb runs when the stored date in `field` (plus `offset`) arrives, under the named rule.",
|
|
185
|
+
"type": "object",
|
|
186
|
+
"required": ["field"],
|
|
187
|
+
"additionalProperties": false,
|
|
188
|
+
"properties": {
|
|
189
|
+
"field": { "$ref": "#/$defs/camelName" },
|
|
190
|
+
"rule": { "$ref": "#/$defs/snakeName" },
|
|
191
|
+
"offset": { "$ref": "#/$defs/isoDuration" }
|
|
192
|
+
}
|
|
193
|
+
},
|
|
194
|
+
"deadline": {
|
|
195
|
+
"description": "The verb stops being admissible once the stored date in `field` (plus `offset`) has passed.",
|
|
196
|
+
"type": "object",
|
|
197
|
+
"required": ["field"],
|
|
198
|
+
"additionalProperties": false,
|
|
199
|
+
"properties": {
|
|
200
|
+
"field": { "$ref": "#/$defs/camelName" },
|
|
201
|
+
"offset": { "$ref": "#/$defs/isoDuration" }
|
|
202
|
+
}
|
|
203
|
+
},
|
|
204
|
+
"setsAt": {
|
|
205
|
+
"description": "Running this verb stamps `field` with now plus `offset`, arming a later deadline.",
|
|
206
|
+
"type": "object",
|
|
207
|
+
"required": ["field", "offset"],
|
|
208
|
+
"additionalProperties": false,
|
|
209
|
+
"properties": {
|
|
210
|
+
"field": { "$ref": "#/$defs/camelName" },
|
|
211
|
+
"offset": { "$ref": "#/$defs/isoDuration" }
|
|
212
|
+
}
|
|
213
|
+
},
|
|
214
|
+
"port": {
|
|
215
|
+
"description": "The verb is a decision port: only these actors may call it, and the answer comes from the tenant's own backend.",
|
|
216
|
+
"type": "object",
|
|
217
|
+
"required": ["allowed"],
|
|
218
|
+
"additionalProperties": false,
|
|
219
|
+
"properties": {
|
|
220
|
+
"allowed": {
|
|
221
|
+
"type": "array",
|
|
222
|
+
"minItems": 1,
|
|
223
|
+
"maxItems": 2,
|
|
224
|
+
"items": { "$ref": "#/$defs/snakeName" }
|
|
225
|
+
}
|
|
226
|
+
}
|
|
227
|
+
},
|
|
228
|
+
"requiresDrainedAccount": {
|
|
229
|
+
"description": "The verb is admissible only when the settlement's escrow account holds nothing, so a terminal state can never strand custody.",
|
|
230
|
+
"type": "object",
|
|
231
|
+
"required": ["path"],
|
|
232
|
+
"additionalProperties": false,
|
|
233
|
+
"properties": {
|
|
234
|
+
"path": { "const": "refs.escrowAccountId" }
|
|
235
|
+
}
|
|
236
|
+
}
|
|
237
|
+
}
|
|
238
|
+
},
|
|
239
|
+
|
|
240
|
+
"move": {
|
|
241
|
+
"description": "One ledger operation. `create` transfers money; `reserve` places a hold; `post` captures a reservation; `void` releases one.",
|
|
242
|
+
"oneOf": [
|
|
243
|
+
{
|
|
244
|
+
"type": "object",
|
|
245
|
+
"required": ["amount", "from", "key", "operation", "to"],
|
|
246
|
+
"additionalProperties": false,
|
|
247
|
+
"properties": {
|
|
248
|
+
"operation": { "const": "create" },
|
|
249
|
+
"key": { "$ref": "#/$defs/snakeName" },
|
|
250
|
+
"amount": { "$ref": "#/$defs/camelName" },
|
|
251
|
+
"from": { "$ref": "#/$defs/endpoint" },
|
|
252
|
+
"to": { "$ref": "#/$defs/endpoint" },
|
|
253
|
+
"moneyEvent": { "$ref": "#/$defs/snakeName" },
|
|
254
|
+
"clawbackOf": {
|
|
255
|
+
"description": "This transfer reverses the named earlier reservation.",
|
|
256
|
+
"$ref": "#/$defs/snakeName"
|
|
257
|
+
}
|
|
258
|
+
}
|
|
259
|
+
},
|
|
260
|
+
{
|
|
261
|
+
"type": "object",
|
|
262
|
+
"required": ["amount", "from", "key", "operation", "to"],
|
|
263
|
+
"additionalProperties": false,
|
|
264
|
+
"properties": {
|
|
265
|
+
"operation": { "const": "reserve" },
|
|
266
|
+
"key": { "$ref": "#/$defs/snakeName" },
|
|
267
|
+
"amount": { "$ref": "#/$defs/camelName" },
|
|
268
|
+
"from": { "$ref": "#/$defs/endpoint" },
|
|
269
|
+
"to": { "$ref": "#/$defs/endpoint" },
|
|
270
|
+
"moneyEvent": { "$ref": "#/$defs/snakeName" }
|
|
271
|
+
}
|
|
272
|
+
},
|
|
273
|
+
{
|
|
274
|
+
"type": "object",
|
|
275
|
+
"required": ["key", "operation", "reservation"],
|
|
276
|
+
"additionalProperties": false,
|
|
277
|
+
"properties": {
|
|
278
|
+
"operation": { "const": "post" },
|
|
279
|
+
"key": { "$ref": "#/$defs/snakeName" },
|
|
280
|
+
"reservation": { "$ref": "#/$defs/snakeName" }
|
|
281
|
+
}
|
|
282
|
+
},
|
|
283
|
+
{
|
|
284
|
+
"type": "object",
|
|
285
|
+
"required": ["key", "operation", "reservation"],
|
|
286
|
+
"additionalProperties": false,
|
|
287
|
+
"properties": {
|
|
288
|
+
"operation": { "const": "void" },
|
|
289
|
+
"key": { "$ref": "#/$defs/snakeName" },
|
|
290
|
+
"reservation": { "$ref": "#/$defs/snakeName" },
|
|
291
|
+
"reason": { "type": "string", "minLength": 1, "maxLength": 120 }
|
|
292
|
+
}
|
|
293
|
+
}
|
|
294
|
+
]
|
|
295
|
+
},
|
|
296
|
+
|
|
297
|
+
"frame": {
|
|
298
|
+
"title": "Business Frame",
|
|
299
|
+
"description": "The same product stated in business terms, congruent with the document by construction: every money movement in the IR is covered by exactly one money event here.",
|
|
300
|
+
"type": "object",
|
|
301
|
+
"required": [
|
|
302
|
+
"actors",
|
|
303
|
+
"confidence",
|
|
304
|
+
"conservationGroups",
|
|
305
|
+
"design",
|
|
306
|
+
"feePolicy",
|
|
307
|
+
"fees",
|
|
308
|
+
"headline",
|
|
309
|
+
"mechanics",
|
|
310
|
+
"moneyEvents",
|
|
311
|
+
"offPlatform",
|
|
312
|
+
"openQuestions",
|
|
313
|
+
"rules",
|
|
314
|
+
"subjects",
|
|
315
|
+
"summary"
|
|
316
|
+
],
|
|
317
|
+
"additionalProperties": false,
|
|
318
|
+
"properties": {
|
|
319
|
+
"headline": { "$ref": "#/$defs/prose" },
|
|
320
|
+
"summary": { "$ref": "#/$defs/prose" },
|
|
321
|
+
"confidence": {
|
|
322
|
+
"description": "Always `high`: a compiled frame is derived, not inferred.",
|
|
323
|
+
"const": "high"
|
|
324
|
+
},
|
|
325
|
+
"mechanics": {
|
|
326
|
+
"description": "The commercial shapes this program's archetypes add up to.",
|
|
327
|
+
"type": "array",
|
|
328
|
+
"minItems": 1,
|
|
329
|
+
"items": {
|
|
330
|
+
"enum": [
|
|
331
|
+
"credit",
|
|
332
|
+
"escrow",
|
|
333
|
+
"insurance",
|
|
334
|
+
"marketplace",
|
|
335
|
+
"recurring_billing"
|
|
336
|
+
]
|
|
337
|
+
}
|
|
338
|
+
},
|
|
339
|
+
"actors": {
|
|
340
|
+
"type": "array",
|
|
341
|
+
"items": {
|
|
342
|
+
"type": "object",
|
|
343
|
+
"required": ["key", "label", "maxCount", "minCount", "role"],
|
|
344
|
+
"additionalProperties": false,
|
|
345
|
+
"properties": {
|
|
346
|
+
"key": { "$ref": "#/$defs/snakeName" },
|
|
347
|
+
"label": { "$ref": "#/$defs/prose" },
|
|
348
|
+
"minCount": { "type": "integer", "minimum": 0 },
|
|
349
|
+
"maxCount": { "type": "integer", "minimum": 1 },
|
|
350
|
+
"role": {
|
|
351
|
+
"enum": [
|
|
352
|
+
"payer",
|
|
353
|
+
"beneficiary",
|
|
354
|
+
"provider",
|
|
355
|
+
"holder",
|
|
356
|
+
"platform"
|
|
357
|
+
]
|
|
358
|
+
}
|
|
359
|
+
}
|
|
360
|
+
}
|
|
361
|
+
},
|
|
362
|
+
"subjects": {
|
|
363
|
+
"type": "array",
|
|
364
|
+
"items": {
|
|
365
|
+
"type": "object",
|
|
366
|
+
"required": ["kind", "title"],
|
|
367
|
+
"additionalProperties": false,
|
|
368
|
+
"properties": {
|
|
369
|
+
"kind": { "$ref": "#/$defs/snakeName" },
|
|
370
|
+
"title": { "$ref": "#/$defs/prose" }
|
|
371
|
+
}
|
|
372
|
+
}
|
|
373
|
+
},
|
|
374
|
+
"moneyEvents": {
|
|
375
|
+
"type": "array",
|
|
376
|
+
"maxItems": 14,
|
|
377
|
+
"items": { "$ref": "#/$defs/moneyEvent" }
|
|
378
|
+
},
|
|
379
|
+
"rules": {
|
|
380
|
+
"type": "array",
|
|
381
|
+
"items": { "$ref": "#/$defs/rule" }
|
|
382
|
+
},
|
|
383
|
+
"fees": {
|
|
384
|
+
"type": "array",
|
|
385
|
+
"items": {
|
|
386
|
+
"type": "object",
|
|
387
|
+
"required": ["label", "on", "structure"],
|
|
388
|
+
"additionalProperties": false,
|
|
389
|
+
"properties": {
|
|
390
|
+
"label": { "$ref": "#/$defs/prose" },
|
|
391
|
+
"on": { "$ref": "#/$defs/prose" },
|
|
392
|
+
"structure": { "$ref": "#/$defs/prose" }
|
|
393
|
+
}
|
|
394
|
+
}
|
|
395
|
+
},
|
|
396
|
+
"feePolicy": { "enum": ["defined", "none"] },
|
|
397
|
+
"design": {
|
|
398
|
+
"description": "One line per lowered settlement, saying what the compiler decided and why.",
|
|
399
|
+
"type": "array",
|
|
400
|
+
"items": { "$ref": "#/$defs/prose" }
|
|
401
|
+
},
|
|
402
|
+
"offPlatform": {
|
|
403
|
+
"description": "What changes hands outside the platform. Money never appears here.",
|
|
404
|
+
"type": "array",
|
|
405
|
+
"items": {
|
|
406
|
+
"type": "object",
|
|
407
|
+
"required": ["label", "why"],
|
|
408
|
+
"additionalProperties": false,
|
|
409
|
+
"properties": {
|
|
410
|
+
"label": { "$ref": "#/$defs/prose" },
|
|
411
|
+
"why": { "$ref": "#/$defs/prose" }
|
|
412
|
+
}
|
|
413
|
+
}
|
|
414
|
+
},
|
|
415
|
+
"conservationGroups": {
|
|
416
|
+
"description": "Always empty from the compiler: conservation is proven on the noun's `partitions`, not restated here.",
|
|
417
|
+
"type": "array",
|
|
418
|
+
"maxItems": 0
|
|
419
|
+
},
|
|
420
|
+
"openQuestions": {
|
|
421
|
+
"description": "Always empty from the compiler: a program that left a question open would not have compiled.",
|
|
422
|
+
"type": "array",
|
|
423
|
+
"maxItems": 0
|
|
424
|
+
}
|
|
425
|
+
}
|
|
426
|
+
},
|
|
427
|
+
|
|
428
|
+
"moneyEvent": {
|
|
429
|
+
"description": "One movement of money, named so a rule can gate it and a person can read it.",
|
|
430
|
+
"type": "object",
|
|
431
|
+
"required": [
|
|
432
|
+
"allocationTotalBps",
|
|
433
|
+
"amount",
|
|
434
|
+
"amountDependencies",
|
|
435
|
+
"amountMode",
|
|
436
|
+
"amountSchedule",
|
|
437
|
+
"distribution",
|
|
438
|
+
"fromActor",
|
|
439
|
+
"key",
|
|
440
|
+
"kind",
|
|
441
|
+
"label",
|
|
442
|
+
"occurrence",
|
|
443
|
+
"timing",
|
|
444
|
+
"toActor",
|
|
445
|
+
"trigger"
|
|
446
|
+
],
|
|
447
|
+
"additionalProperties": false,
|
|
448
|
+
"properties": {
|
|
449
|
+
"key": { "$ref": "#/$defs/snakeName" },
|
|
450
|
+
"kind": {
|
|
451
|
+
"enum": [
|
|
452
|
+
"charge",
|
|
453
|
+
"hold",
|
|
454
|
+
"installment",
|
|
455
|
+
"payout",
|
|
456
|
+
"penalty",
|
|
457
|
+
"premium",
|
|
458
|
+
"refund"
|
|
459
|
+
]
|
|
460
|
+
},
|
|
461
|
+
"label": { "$ref": "#/$defs/prose" },
|
|
462
|
+
"trigger": { "$ref": "#/$defs/prose" },
|
|
463
|
+
"amount": {
|
|
464
|
+
"description": "The amount in words. The exact arithmetic lives on the noun's fields and partitions.",
|
|
465
|
+
"$ref": "#/$defs/prose"
|
|
466
|
+
},
|
|
467
|
+
"fromActor": { "$ref": "#/$defs/endpoint" },
|
|
468
|
+
"toActor": { "$ref": "#/$defs/endpoint" },
|
|
469
|
+
"occurrence": { "enum": ["once", "repeatable"] },
|
|
470
|
+
"timing": { "enum": ["external_schedule", "on_lifecycle"] },
|
|
471
|
+
"amountMode": { "const": "fixed" },
|
|
472
|
+
"distribution": { "const": "single" },
|
|
473
|
+
"allocationTotalBps": { "const": 0 },
|
|
474
|
+
"amountDependencies": { "type": "array", "maxItems": 0 },
|
|
475
|
+
"amountSchedule": { "type": "array", "maxItems": 0 }
|
|
476
|
+
}
|
|
477
|
+
},
|
|
478
|
+
|
|
479
|
+
"rule": {
|
|
480
|
+
"description": "A condition on the product: what must be true before a money event may run.",
|
|
481
|
+
"type": "object",
|
|
482
|
+
"required": [
|
|
483
|
+
"allowedActors",
|
|
484
|
+
"detail",
|
|
485
|
+
"dueDriven",
|
|
486
|
+
"enforcement",
|
|
487
|
+
"gatesEvent",
|
|
488
|
+
"key",
|
|
489
|
+
"kind",
|
|
490
|
+
"label",
|
|
491
|
+
"tenantTunable"
|
|
492
|
+
],
|
|
493
|
+
"additionalProperties": false,
|
|
494
|
+
"properties": {
|
|
495
|
+
"key": { "$ref": "#/$defs/snakeName" },
|
|
496
|
+
"kind": { "enum": ["deadline", "release_condition"] },
|
|
497
|
+
"label": { "$ref": "#/$defs/prose" },
|
|
498
|
+
"detail": { "$ref": "#/$defs/prose" },
|
|
499
|
+
"allowedActors": {
|
|
500
|
+
"type": "array",
|
|
501
|
+
"items": { "$ref": "#/$defs/snakeName" }
|
|
502
|
+
},
|
|
503
|
+
"gatesEvent": {
|
|
504
|
+
"description": "The money event this rule gates, or null when it gates the lifecycle rather than one movement.",
|
|
505
|
+
"anyOf": [{ "$ref": "#/$defs/snakeName" }, { "type": "null" }]
|
|
506
|
+
},
|
|
507
|
+
"dueDriven": {
|
|
508
|
+
"description": "True when a stored date decides the rule, false when a decision port does.",
|
|
509
|
+
"type": "boolean"
|
|
510
|
+
},
|
|
511
|
+
"enforcement": {
|
|
512
|
+
"description": "`tenant_app` means the tenant's own backend answers; `platform` means the runtime decides without asking.",
|
|
513
|
+
"enum": ["platform", "tenant_app"]
|
|
514
|
+
},
|
|
515
|
+
"tenantTunable": {
|
|
516
|
+
"description": "Always false from the compiler: the source is the only place these terms change.",
|
|
517
|
+
"const": false
|
|
518
|
+
}
|
|
519
|
+
}
|
|
520
|
+
}
|
|
521
|
+
}
|
|
522
|
+
}
|