@ottochain/sdk 1.4.2 → 1.6.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 (80) hide show
  1. package/dist/cjs/apps/contracts/index.js +6 -10
  2. package/dist/cjs/apps/{governance/state-machines/governance-legislature.json → contracts/state-machines/index.js} +381 -330
  3. package/dist/cjs/apps/corporate/index.js +12 -24
  4. package/dist/cjs/apps/corporate/state-machines/index.js +10246 -0
  5. package/dist/cjs/apps/governance/index.js +11 -22
  6. package/dist/cjs/apps/governance/state-machines/index.js +4755 -0
  7. package/dist/cjs/apps/identity/index.js +3 -6
  8. package/dist/{esm/apps/identity/state-machines/agent-identity.json → cjs/apps/identity/state-machines/index.js} +9 -2
  9. package/dist/cjs/apps/markets/index.js +2 -5
  10. package/dist/{esm/apps/markets/state-machines/market-universal.json → cjs/apps/markets/state-machines/index.js} +9 -2
  11. package/dist/cjs/apps/oracles/index.js +2 -5
  12. package/dist/{esm/apps/oracles/state-machines/oracle.json → cjs/apps/oracles/state-machines/index.js} +9 -2
  13. package/dist/cjs/ottochain/index.js +4 -1
  14. package/dist/cjs/ottochain/normalize.js +40 -15
  15. package/dist/cjs/ottochain/types.js +12 -0
  16. package/dist/esm/apps/contracts/index.js +2 -3
  17. package/dist/esm/apps/{governance/state-machines/governance-legislature.json → contracts/state-machines/index.js} +378 -330
  18. package/dist/esm/apps/corporate/index.js +2 -11
  19. package/dist/esm/apps/corporate/state-machines/index.js +10243 -0
  20. package/dist/esm/apps/governance/index.js +2 -10
  21. package/dist/esm/apps/governance/state-machines/index.js +4752 -0
  22. package/dist/esm/apps/identity/index.js +2 -2
  23. package/dist/{cjs/apps/identity/state-machines/agent-identity.json → esm/apps/identity/state-machines/index.js} +6 -2
  24. package/dist/esm/apps/markets/index.js +1 -1
  25. package/dist/{cjs/apps/markets/state-machines/market-universal.json → esm/apps/markets/state-machines/index.js} +6 -2
  26. package/dist/esm/apps/oracles/index.js +1 -1
  27. package/dist/{cjs/apps/oracles/state-machines/oracle.json → esm/apps/oracles/state-machines/index.js} +6 -2
  28. package/dist/esm/ottochain/index.js +2 -0
  29. package/dist/esm/ottochain/normalize.js +40 -15
  30. package/dist/esm/ottochain/types.js +11 -1
  31. package/dist/types/apps/contracts/state-machines/index.d.ts +549 -0
  32. package/dist/types/apps/corporate/state-machines/index.d.ts +9121 -0
  33. package/dist/types/apps/governance/state-machines/index.d.ts +3551 -0
  34. package/dist/types/apps/identity/state-machines/index.d.ts +206 -0
  35. package/dist/types/apps/markets/state-machines/index.d.ts +448 -0
  36. package/dist/types/apps/oracles/state-machines/index.d.ts +312 -0
  37. package/dist/types/ottochain/index.d.ts +2 -1
  38. package/dist/types/ottochain/normalize.d.ts +21 -8
  39. package/dist/types/ottochain/types.d.ts +12 -1
  40. package/package.json +10 -9
  41. package/dist/cjs/apps/contracts/state-machines/contract.json +0 -352
  42. package/dist/cjs/apps/contracts/state-machines/escrow.json +0 -354
  43. package/dist/cjs/apps/corporate/state-machines/corporate-board.json +0 -1064
  44. package/dist/cjs/apps/corporate/state-machines/corporate-bylaws.json +0 -751
  45. package/dist/cjs/apps/corporate/state-machines/corporate-committee.json +0 -957
  46. package/dist/cjs/apps/corporate/state-machines/corporate-compliance.json +0 -1293
  47. package/dist/cjs/apps/corporate/state-machines/corporate-entity.json +0 -861
  48. package/dist/cjs/apps/corporate/state-machines/corporate-officers.json +0 -843
  49. package/dist/cjs/apps/corporate/state-machines/corporate-proxy.json +0 -783
  50. package/dist/cjs/apps/corporate/state-machines/corporate-resolution.json +0 -1174
  51. package/dist/cjs/apps/corporate/state-machines/corporate-securities.json +0 -1215
  52. package/dist/cjs/apps/corporate/state-machines/corporate-shareholders.json +0 -1298
  53. package/dist/cjs/apps/governance/state-machines/dao-multisig.json +0 -667
  54. package/dist/cjs/apps/governance/state-machines/dao-single.json +0 -230
  55. package/dist/cjs/apps/governance/state-machines/dao-threshold.json +0 -624
  56. package/dist/cjs/apps/governance/state-machines/dao-token.json +0 -638
  57. package/dist/cjs/apps/governance/state-machines/governance-constitution.json +0 -357
  58. package/dist/cjs/apps/governance/state-machines/governance-executive.json +0 -387
  59. package/dist/cjs/apps/governance/state-machines/governance-judiciary.json +0 -558
  60. package/dist/cjs/apps/governance/state-machines/governance-simple.json +0 -625
  61. package/dist/esm/apps/contracts/state-machines/contract.json +0 -352
  62. package/dist/esm/apps/contracts/state-machines/escrow.json +0 -354
  63. package/dist/esm/apps/corporate/state-machines/corporate-board.json +0 -1064
  64. package/dist/esm/apps/corporate/state-machines/corporate-bylaws.json +0 -751
  65. package/dist/esm/apps/corporate/state-machines/corporate-committee.json +0 -957
  66. package/dist/esm/apps/corporate/state-machines/corporate-compliance.json +0 -1293
  67. package/dist/esm/apps/corporate/state-machines/corporate-entity.json +0 -861
  68. package/dist/esm/apps/corporate/state-machines/corporate-officers.json +0 -843
  69. package/dist/esm/apps/corporate/state-machines/corporate-proxy.json +0 -783
  70. package/dist/esm/apps/corporate/state-machines/corporate-resolution.json +0 -1174
  71. package/dist/esm/apps/corporate/state-machines/corporate-securities.json +0 -1215
  72. package/dist/esm/apps/corporate/state-machines/corporate-shareholders.json +0 -1298
  73. package/dist/esm/apps/governance/state-machines/dao-multisig.json +0 -667
  74. package/dist/esm/apps/governance/state-machines/dao-single.json +0 -230
  75. package/dist/esm/apps/governance/state-machines/dao-threshold.json +0 -624
  76. package/dist/esm/apps/governance/state-machines/dao-token.json +0 -638
  77. package/dist/esm/apps/governance/state-machines/governance-constitution.json +0 -357
  78. package/dist/esm/apps/governance/state-machines/governance-executive.json +0 -387
  79. package/dist/esm/apps/governance/state-machines/governance-judiciary.json +0 -558
  80. package/dist/esm/apps/governance/state-machines/governance-simple.json +0 -625
@@ -1,1064 +0,0 @@
1
- {
2
- "$schema": "https://ottochain.dev/schemas/state-machine-v1.json",
3
- "name": "corporate-board",
4
- "version": "1.0.0",
5
- "category": "corporate-governance",
6
- "description": "Board of directors state machine managing director seats, meetings, quorum, and formal board actions. Supports staggered boards with classified directors.",
7
- "context": {
8
- "boardId": {
9
- "type": "string",
10
- "description": "Unique identifier for this board instance"
11
- },
12
- "entityId": {
13
- "type": "string",
14
- "description": "Reference to parent corporate-entity"
15
- },
16
- "directors": {
17
- "type": "array",
18
- "items": {
19
- "type": "object",
20
- "properties": {
21
- "directorId": {
22
- "type": "string"
23
- },
24
- "name": {
25
- "type": "string"
26
- },
27
- "email": {
28
- "type": "string"
29
- },
30
- "termStart": {
31
- "type": "string",
32
- "format": "date"
33
- },
34
- "termEnd": {
35
- "type": "string",
36
- "format": "date"
37
- },
38
- "class": {
39
- "type": "string",
40
- "enum": [
41
- "CLASS_I",
42
- "CLASS_II",
43
- "CLASS_III",
44
- "UNCLASSIFIED"
45
- ],
46
- "description": "For staggered boards"
47
- },
48
- "status": {
49
- "type": "string",
50
- "enum": [
51
- "ACTIVE",
52
- "RESIGNED",
53
- "REMOVED",
54
- "TERM_EXPIRED"
55
- ]
56
- },
57
- "isIndependent": {
58
- "type": "boolean",
59
- "description": "Independence under applicable rules"
60
- },
61
- "isChair": {
62
- "type": "boolean",
63
- "default": false
64
- },
65
- "isLeadIndependent": {
66
- "type": "boolean",
67
- "default": false
68
- },
69
- "committees": {
70
- "type": "array",
71
- "items": {
72
- "type": "string"
73
- },
74
- "description": "Committee memberships by committee ID"
75
- },
76
- "electedBy": {
77
- "type": "string",
78
- "description": "Resolution reference for election"
79
- },
80
- "compensationAgreementRef": {
81
- "type": "string",
82
- "nullable": true
83
- }
84
- }
85
- }
86
- },
87
- "seats": {
88
- "type": "object",
89
- "properties": {
90
- "authorized": {
91
- "type": "integer",
92
- "description": "Number of board seats authorized by bylaws"
93
- },
94
- "filled": {
95
- "type": "integer"
96
- },
97
- "vacant": {
98
- "type": "integer"
99
- }
100
- }
101
- },
102
- "boardStructure": {
103
- "type": "object",
104
- "properties": {
105
- "isClassified": {
106
- "type": "boolean",
107
- "description": "Whether board has staggered terms"
108
- },
109
- "termYears": {
110
- "type": "integer",
111
- "default": 1,
112
- "description": "Director term length"
113
- },
114
- "classTerms": {
115
- "type": "object",
116
- "properties": {
117
- "CLASS_I": {
118
- "type": "integer"
119
- },
120
- "CLASS_II": {
121
- "type": "integer"
122
- },
123
- "CLASS_III": {
124
- "type": "integer"
125
- }
126
- }
127
- }
128
- }
129
- },
130
- "quorumRules": {
131
- "type": "object",
132
- "properties": {
133
- "type": {
134
- "type": "string",
135
- "enum": [
136
- "MAJORITY",
137
- "SUPERMAJORITY",
138
- "FIXED_NUMBER"
139
- ],
140
- "default": "MAJORITY"
141
- },
142
- "threshold": {
143
- "type": "number",
144
- "description": "Fraction for majority/super, or count for fixed"
145
- },
146
- "minimumRequired": {
147
- "type": "integer",
148
- "description": "Absolute minimum regardless of formula"
149
- }
150
- }
151
- },
152
- "votingRules": {
153
- "type": "object",
154
- "properties": {
155
- "standardApproval": {
156
- "type": "string",
157
- "enum": [
158
- "MAJORITY_PRESENT",
159
- "MAJORITY_FULL_BOARD"
160
- ],
161
- "default": "MAJORITY_PRESENT"
162
- },
163
- "supermajorityMatters": {
164
- "type": "array",
165
- "items": {
166
- "type": "string"
167
- },
168
- "description": "Action types requiring supermajority"
169
- },
170
- "supermajorityThreshold": {
171
- "type": "number",
172
- "default": 0.6667
173
- }
174
- }
175
- },
176
- "currentMeeting": {
177
- "type": "object",
178
- "nullable": true,
179
- "properties": {
180
- "meetingId": {
181
- "type": "string"
182
- },
183
- "type": {
184
- "type": "string",
185
- "enum": [
186
- "REGULAR",
187
- "SPECIAL",
188
- "ANNUAL",
189
- "ORGANIZATIONAL"
190
- ]
191
- },
192
- "scheduledDate": {
193
- "type": "string",
194
- "format": "date-time"
195
- },
196
- "location": {
197
- "type": "string"
198
- },
199
- "isVirtual": {
200
- "type": "boolean"
201
- },
202
- "calledBy": {
203
- "type": "string"
204
- },
205
- "noticeDate": {
206
- "type": "string",
207
- "format": "date"
208
- },
209
- "agenda": {
210
- "type": "array",
211
- "items": {
212
- "type": "string"
213
- }
214
- },
215
- "attendees": {
216
- "type": "array",
217
- "items": {
218
- "type": "object",
219
- "properties": {
220
- "directorId": {
221
- "type": "string"
222
- },
223
- "present": {
224
- "type": "boolean"
225
- },
226
- "arrivedAt": {
227
- "type": "string",
228
- "format": "date-time",
229
- "nullable": true
230
- },
231
- "departedAt": {
232
- "type": "string",
233
- "format": "date-time",
234
- "nullable": true
235
- },
236
- "viaProxy": {
237
- "type": "boolean",
238
- "default": false
239
- }
240
- }
241
- }
242
- },
243
- "quorumPresent": {
244
- "type": "boolean"
245
- },
246
- "quorumCount": {
247
- "type": "integer"
248
- },
249
- "openedAt": {
250
- "type": "string",
251
- "format": "date-time",
252
- "nullable": true
253
- },
254
- "closedAt": {
255
- "type": "string",
256
- "format": "date-time",
257
- "nullable": true
258
- },
259
- "minutesRef": {
260
- "type": "string",
261
- "nullable": true
262
- }
263
- }
264
- },
265
- "meetingHistory": {
266
- "type": "array",
267
- "items": {
268
- "type": "object",
269
- "properties": {
270
- "meetingId": {
271
- "type": "string"
272
- },
273
- "type": {
274
- "type": "string"
275
- },
276
- "date": {
277
- "type": "string",
278
- "format": "date"
279
- },
280
- "quorumAchieved": {
281
- "type": "boolean"
282
- },
283
- "attendeeCount": {
284
- "type": "integer"
285
- },
286
- "resolutionsPassed": {
287
- "type": "array",
288
- "items": {
289
- "type": "string"
290
- }
291
- },
292
- "minutesRef": {
293
- "type": "string"
294
- }
295
- }
296
- }
297
- },
298
- "createdAt": {
299
- "type": "string",
300
- "format": "date-time"
301
- },
302
- "updatedAt": {
303
- "type": "string",
304
- "format": "date-time"
305
- }
306
- },
307
- "states": {
308
- "ACTIVE": {
309
- "description": "Board is constituted and able to conduct business. Default state between meetings.",
310
- "metadata": null
311
- },
312
- "IN_MEETING": {
313
- "description": "Board meeting is in session with quorum present. Can take formal actions.",
314
- "metadata": null
315
- },
316
- "QUORUM_LOST": {
317
- "description": "Meeting in progress but quorum lost due to departures. No further action until quorum restored or adjourned.",
318
- "metadata": null
319
- }
320
- },
321
- "initialState": "ACTIVE",
322
- "transitions": {
323
- "elect_director": {
324
- "from": "ACTIVE",
325
- "to": "ACTIVE",
326
- "description": "Add a new director to the board (election typically done at shareholder meeting or by board to fill vacancy)",
327
- "event": {
328
- "name": "elect_director",
329
- "payload": {
330
- "directorId": {
331
- "type": "string",
332
- "required": true
333
- },
334
- "name": {
335
- "type": "string",
336
- "required": true
337
- },
338
- "email": {
339
- "type": "string"
340
- },
341
- "termStart": {
342
- "type": "string",
343
- "format": "date",
344
- "required": true
345
- },
346
- "termEnd": {
347
- "type": "string",
348
- "format": "date",
349
- "required": true
350
- },
351
- "class": {
352
- "type": "string",
353
- "enum": [
354
- "CLASS_I",
355
- "CLASS_II",
356
- "CLASS_III",
357
- "UNCLASSIFIED"
358
- ]
359
- },
360
- "isIndependent": {
361
- "type": "boolean",
362
- "required": true
363
- },
364
- "electionResolutionRef": {
365
- "type": "string",
366
- "required": true,
367
- "description": "Shareholder or board resolution"
368
- },
369
- "isFillingVacancy": {
370
- "type": "boolean",
371
- "default": false
372
- }
373
- }
374
- },
375
- "guards": [
376
- {
377
- "name": "hasAvailableSeat",
378
- "description": "Must have vacant seat or be filling expired term",
379
- "expression": "context.seats.vacant > 0 || event.isFillingVacancy"
380
- },
381
- {
382
- "name": "hasElectionResolution",
383
- "description": "Must have valid election resolution (shareholder for annual, board for vacancy fill)",
384
- "expression": "event.electionResolutionRef != null"
385
- },
386
- {
387
- "name": "notAlreadyDirector",
388
- "description": "Person not already serving on board",
389
- "expression": "!context.directors.some(d => d.directorId === event.directorId && d.status === 'ACTIVE')"
390
- }
391
- ],
392
- "effects": [
393
- {
394
- "type": "APPEND_ARRAY",
395
- "path": "directors",
396
- "value": {
397
- "directorId": "{{ event.directorId }}",
398
- "name": "{{ event.name }}",
399
- "email": "{{ event.email }}",
400
- "termStart": "{{ event.termStart }}",
401
- "termEnd": "{{ event.termEnd }}",
402
- "class": "{{ event.class }}",
403
- "status": "ACTIVE",
404
- "isIndependent": "{{ event.isIndependent }}",
405
- "isChair": false,
406
- "isLeadIndependent": false,
407
- "committees": [],
408
- "electedBy": "{{ event.electionResolutionRef }}"
409
- }
410
- },
411
- {
412
- "type": "INCREMENT",
413
- "path": "seats.filled",
414
- "amount": 1
415
- },
416
- {
417
- "type": "DECREMENT",
418
- "path": "seats.vacant",
419
- "amount": 1
420
- },
421
- {
422
- "type": "EMIT_EVENT",
423
- "eventType": "DIRECTOR_ELECTED",
424
- "payload": {
425
- "boardId": "{{ context.boardId }}",
426
- "directorId": "{{ event.directorId }}",
427
- "name": "{{ event.name }}",
428
- "termEnd": "{{ event.termEnd }}"
429
- }
430
- }
431
- ]
432
- },
433
- "resign_director": {
434
- "from": [
435
- "ACTIVE",
436
- "IN_MEETING"
437
- ],
438
- "to": "ACTIVE",
439
- "description": "Director resigns from the board",
440
- "event": {
441
- "name": "resign_director",
442
- "payload": {
443
- "directorId": {
444
- "type": "string",
445
- "required": true
446
- },
447
- "effectiveDate": {
448
- "type": "string",
449
- "format": "date",
450
- "required": true
451
- },
452
- "reason": {
453
- "type": "string"
454
- },
455
- "resignationLetter": {
456
- "type": "string",
457
- "description": "Document reference"
458
- }
459
- }
460
- },
461
- "guards": [
462
- {
463
- "name": "isActiveDirector",
464
- "expression": "context.directors.some(d => d.directorId === event.directorId && d.status === 'ACTIVE')"
465
- }
466
- ],
467
- "effects": [
468
- {
469
- "type": "UPDATE_ARRAY_ITEM",
470
- "path": "directors",
471
- "matchKey": "directorId",
472
- "matchValue": "{{ event.directorId }}",
473
- "updates": {
474
- "status": "RESIGNED",
475
- "termEnd": "{{ event.effectiveDate }}"
476
- }
477
- },
478
- {
479
- "type": "DECREMENT",
480
- "path": "seats.filled",
481
- "amount": 1
482
- },
483
- {
484
- "type": "INCREMENT",
485
- "path": "seats.vacant",
486
- "amount": 1
487
- },
488
- {
489
- "type": "EMIT_EVENT",
490
- "eventType": "DIRECTOR_RESIGNED",
491
- "payload": {
492
- "boardId": "{{ context.boardId }}",
493
- "directorId": "{{ event.directorId }}",
494
- "effectiveDate": "{{ event.effectiveDate }}"
495
- }
496
- }
497
- ]
498
- },
499
- "remove_for_cause": {
500
- "from": "ACTIVE",
501
- "to": "ACTIVE",
502
- "description": "Remove a director for cause (requires board or shareholder action depending on bylaws)",
503
- "event": {
504
- "name": "remove_for_cause",
505
- "payload": {
506
- "directorId": {
507
- "type": "string",
508
- "required": true
509
- },
510
- "cause": {
511
- "type": "string",
512
- "required": true
513
- },
514
- "removalResolutionRef": {
515
- "type": "string",
516
- "required": true
517
- },
518
- "effectiveDate": {
519
- "type": "string",
520
- "format": "date",
521
- "required": true
522
- }
523
- }
524
- },
525
- "guards": [
526
- {
527
- "name": "isActiveDirector",
528
- "expression": "context.directors.some(d => d.directorId === event.directorId && d.status === 'ACTIVE')"
529
- },
530
- {
531
- "name": "hasRemovalResolution",
532
- "crossMachine": {
533
- "machine": "corporate-resolution",
534
- "instanceRef": "{{ event.removalResolutionRef }}",
535
- "requiredState": "EXECUTED"
536
- }
537
- }
538
- ],
539
- "effects": [
540
- {
541
- "type": "UPDATE_ARRAY_ITEM",
542
- "path": "directors",
543
- "matchKey": "directorId",
544
- "matchValue": "{{ event.directorId }}",
545
- "updates": {
546
- "status": "REMOVED",
547
- "termEnd": "{{ event.effectiveDate }}"
548
- }
549
- },
550
- {
551
- "type": "DECREMENT",
552
- "path": "seats.filled",
553
- "amount": 1
554
- },
555
- {
556
- "type": "INCREMENT",
557
- "path": "seats.vacant",
558
- "amount": 1
559
- },
560
- {
561
- "type": "EMIT_EVENT",
562
- "eventType": "DIRECTOR_REMOVED",
563
- "payload": {
564
- "boardId": "{{ context.boardId }}",
565
- "directorId": "{{ event.directorId }}",
566
- "cause": "{{ event.cause }}"
567
- }
568
- }
569
- ]
570
- },
571
- "designate_chair": {
572
- "from": "ACTIVE",
573
- "to": "ACTIVE",
574
- "description": "Designate a director as board chair",
575
- "event": {
576
- "name": "designate_chair",
577
- "payload": {
578
- "directorId": {
579
- "type": "string",
580
- "required": true
581
- },
582
- "resolutionRef": {
583
- "type": "string",
584
- "required": true
585
- }
586
- }
587
- },
588
- "guards": [
589
- {
590
- "name": "isActiveDirector",
591
- "expression": "context.directors.some(d => d.directorId === event.directorId && d.status === 'ACTIVE')"
592
- }
593
- ],
594
- "effects": [
595
- {
596
- "type": "UPDATE_ARRAY_ALL",
597
- "path": "directors",
598
- "updates": {
599
- "isChair": false
600
- }
601
- },
602
- {
603
- "type": "UPDATE_ARRAY_ITEM",
604
- "path": "directors",
605
- "matchKey": "directorId",
606
- "matchValue": "{{ event.directorId }}",
607
- "updates": {
608
- "isChair": true
609
- }
610
- }
611
- ]
612
- },
613
- "call_meeting": {
614
- "from": "ACTIVE",
615
- "to": "ACTIVE",
616
- "description": "Schedule a board meeting (can be called by chair, CEO, or directors per bylaws)",
617
- "event": {
618
- "name": "call_meeting",
619
- "payload": {
620
- "meetingId": {
621
- "type": "string",
622
- "required": true
623
- },
624
- "type": {
625
- "type": "string",
626
- "enum": [
627
- "REGULAR",
628
- "SPECIAL",
629
- "ANNUAL",
630
- "ORGANIZATIONAL"
631
- ],
632
- "required": true
633
- },
634
- "scheduledDate": {
635
- "type": "string",
636
- "format": "date-time",
637
- "required": true
638
- },
639
- "location": {
640
- "type": "string"
641
- },
642
- "isVirtual": {
643
- "type": "boolean",
644
- "default": false
645
- },
646
- "calledBy": {
647
- "type": "string",
648
- "required": true,
649
- "description": "Director ID or officer title"
650
- },
651
- "noticeDate": {
652
- "type": "string",
653
- "format": "date",
654
- "required": true
655
- },
656
- "agenda": {
657
- "type": "array",
658
- "items": {
659
- "type": "string"
660
- }
661
- },
662
- "waiverOfNotice": {
663
- "type": "boolean",
664
- "default": false,
665
- "description": "If all directors waive notice"
666
- }
667
- }
668
- },
669
- "guards": [
670
- {
671
- "name": "sufficientNotice",
672
- "description": "Must provide notice per bylaws (typically 2-10 days for special, less for regular)",
673
- "expression": "event.waiverOfNotice || (new Date(event.scheduledDate) - new Date(event.noticeDate)) >= 2 * 24 * 60 * 60 * 1000"
674
- },
675
- {
676
- "name": "noConflictingMeeting",
677
- "description": "No other meeting currently scheduled/in progress",
678
- "expression": "context.currentMeeting == null || context.currentMeeting.closedAt != null"
679
- }
680
- ],
681
- "effects": [
682
- {
683
- "type": "SET_CONTEXT",
684
- "path": "currentMeeting",
685
- "value": {
686
- "meetingId": "{{ event.meetingId }}",
687
- "type": "{{ event.type }}",
688
- "scheduledDate": "{{ event.scheduledDate }}",
689
- "location": "{{ event.location }}",
690
- "isVirtual": "{{ event.isVirtual }}",
691
- "calledBy": "{{ event.calledBy }}",
692
- "noticeDate": "{{ event.noticeDate }}",
693
- "agenda": "{{ event.agenda }}",
694
- "attendees": [],
695
- "quorumPresent": false,
696
- "quorumCount": 0
697
- }
698
- },
699
- {
700
- "type": "EMIT_EVENT",
701
- "eventType": "BOARD_MEETING_SCHEDULED",
702
- "payload": {
703
- "boardId": "{{ context.boardId }}",
704
- "meetingId": "{{ event.meetingId }}",
705
- "scheduledDate": "{{ event.scheduledDate }}"
706
- }
707
- }
708
- ]
709
- },
710
- "record_attendance": {
711
- "from": "ACTIVE",
712
- "to": "ACTIVE",
713
- "description": "Record a director's attendance before meeting opens",
714
- "event": {
715
- "name": "record_attendance",
716
- "payload": {
717
- "directorId": {
718
- "type": "string",
719
- "required": true
720
- },
721
- "present": {
722
- "type": "boolean",
723
- "required": true
724
- },
725
- "arrivedAt": {
726
- "type": "string",
727
- "format": "date-time"
728
- }
729
- }
730
- },
731
- "guards": [
732
- {
733
- "name": "hasPendingMeeting",
734
- "expression": "context.currentMeeting != null && context.currentMeeting.openedAt == null"
735
- },
736
- {
737
- "name": "isActiveDirector",
738
- "expression": "context.directors.some(d => d.directorId === event.directorId && d.status === 'ACTIVE')"
739
- }
740
- ],
741
- "effects": [
742
- {
743
- "type": "APPEND_ARRAY",
744
- "path": "currentMeeting.attendees",
745
- "value": {
746
- "directorId": "{{ event.directorId }}",
747
- "present": "{{ event.present }}",
748
- "arrivedAt": "{{ event.arrivedAt }}",
749
- "viaProxy": false
750
- }
751
- },
752
- {
753
- "type": "COMPUTE",
754
- "path": "currentMeeting.quorumCount",
755
- "expression": "context.currentMeeting.attendees.filter(a => a.present).length"
756
- },
757
- {
758
- "type": "COMPUTE",
759
- "path": "currentMeeting.quorumPresent",
760
- "expression": "context.currentMeeting.attendees.filter(a => a.present).length >= Math.ceil(context.seats.filled * 0.5)"
761
- }
762
- ]
763
- },
764
- "open_meeting": {
765
- "from": "ACTIVE",
766
- "to": "IN_MEETING",
767
- "description": "Officially open the board meeting once quorum is established",
768
- "event": {
769
- "name": "open_meeting",
770
- "payload": {
771
- "openedAt": {
772
- "type": "string",
773
- "format": "date-time",
774
- "required": true
775
- },
776
- "chairPresiding": {
777
- "type": "string",
778
- "description": "Director ID presiding"
779
- }
780
- }
781
- },
782
- "guards": [
783
- {
784
- "name": "hasPendingMeeting",
785
- "expression": "context.currentMeeting != null && context.currentMeeting.openedAt == null"
786
- },
787
- {
788
- "name": "quorumPresent",
789
- "description": "Cannot open meeting without quorum",
790
- "expression": "context.currentMeeting.quorumPresent === true"
791
- }
792
- ],
793
- "effects": [
794
- {
795
- "type": "SET_CONTEXT",
796
- "path": "currentMeeting.openedAt",
797
- "value": "{{ event.openedAt }}"
798
- },
799
- {
800
- "type": "EMIT_EVENT",
801
- "eventType": "BOARD_MEETING_OPENED",
802
- "payload": {
803
- "boardId": "{{ context.boardId }}",
804
- "meetingId": "{{ context.currentMeeting.meetingId }}",
805
- "quorumCount": "{{ context.currentMeeting.quorumCount }}"
806
- }
807
- }
808
- ]
809
- },
810
- "director_departs": {
811
- "from": "IN_MEETING",
812
- "to": "IN_MEETING",
813
- "description": "Record a director leaving the meeting (may affect quorum)",
814
- "event": {
815
- "name": "director_departs",
816
- "payload": {
817
- "directorId": {
818
- "type": "string",
819
- "required": true
820
- },
821
- "departedAt": {
822
- "type": "string",
823
- "format": "date-time",
824
- "required": true
825
- }
826
- }
827
- },
828
- "effects": [
829
- {
830
- "type": "UPDATE_ARRAY_ITEM",
831
- "path": "currentMeeting.attendees",
832
- "matchKey": "directorId",
833
- "matchValue": "{{ event.directorId }}",
834
- "updates": {
835
- "present": false,
836
- "departedAt": "{{ event.departedAt }}"
837
- }
838
- },
839
- {
840
- "type": "COMPUTE",
841
- "path": "currentMeeting.quorumCount",
842
- "expression": "context.currentMeeting.attendees.filter(a => a.present).length"
843
- },
844
- {
845
- "type": "COMPUTE",
846
- "path": "currentMeeting.quorumPresent",
847
- "expression": "context.currentMeeting.attendees.filter(a => a.present).length >= Math.ceil(context.seats.filled * 0.5)"
848
- }
849
- ]
850
- },
851
- "quorum_lost": {
852
- "from": "IN_MEETING",
853
- "to": "QUORUM_LOST",
854
- "description": "Automatic transition when quorum is lost during meeting",
855
- "event": {
856
- "name": "quorum_lost",
857
- "payload": {
858
- "lostAt": {
859
- "type": "string",
860
- "format": "date-time",
861
- "required": true
862
- }
863
- }
864
- },
865
- "guards": [
866
- {
867
- "name": "noLongerQuorate",
868
- "expression": "context.currentMeeting.quorumPresent === false"
869
- }
870
- ],
871
- "effects": [
872
- {
873
- "type": "EMIT_EVENT",
874
- "eventType": "BOARD_QUORUM_LOST",
875
- "payload": {
876
- "boardId": "{{ context.boardId }}",
877
- "meetingId": "{{ context.currentMeeting.meetingId }}",
878
- "remainingDirectors": "{{ context.currentMeeting.quorumCount }}"
879
- }
880
- }
881
- ]
882
- },
883
- "quorum_restored": {
884
- "from": "QUORUM_LOST",
885
- "to": "IN_MEETING",
886
- "description": "Quorum restored after additional director(s) join",
887
- "event": {
888
- "name": "quorum_restored",
889
- "payload": {
890
- "restoredAt": {
891
- "type": "string",
892
- "format": "date-time",
893
- "required": true
894
- },
895
- "directorId": {
896
- "type": "string",
897
- "required": true,
898
- "description": "Joining director"
899
- }
900
- }
901
- },
902
- "guards": [
903
- {
904
- "name": "nowQuorate",
905
- "expression": "context.currentMeeting.quorumPresent === true"
906
- }
907
- ],
908
- "effects": [
909
- {
910
- "type": "EMIT_EVENT",
911
- "eventType": "BOARD_QUORUM_RESTORED",
912
- "payload": {
913
- "boardId": "{{ context.boardId }}",
914
- "meetingId": "{{ context.currentMeeting.meetingId }}"
915
- }
916
- }
917
- ]
918
- },
919
- "adjourn": {
920
- "from": [
921
- "IN_MEETING",
922
- "QUORUM_LOST"
923
- ],
924
- "to": "ACTIVE",
925
- "description": "Adjourn the board meeting",
926
- "event": {
927
- "name": "adjourn",
928
- "payload": {
929
- "closedAt": {
930
- "type": "string",
931
- "format": "date-time",
932
- "required": true
933
- },
934
- "minutesRef": {
935
- "type": "string",
936
- "description": "Reference to meeting minutes document"
937
- },
938
- "resolutionsPassed": {
939
- "type": "array",
940
- "items": {
941
- "type": "string"
942
- }
943
- },
944
- "adjournedTo": {
945
- "type": "string",
946
- "format": "date-time",
947
- "nullable": true,
948
- "description": "If adjourning to later date"
949
- }
950
- }
951
- },
952
- "effects": [
953
- {
954
- "type": "SET_CONTEXT",
955
- "path": "currentMeeting.closedAt",
956
- "value": "{{ event.closedAt }}"
957
- },
958
- {
959
- "type": "SET_CONTEXT",
960
- "path": "currentMeeting.minutesRef",
961
- "value": "{{ event.minutesRef }}"
962
- },
963
- {
964
- "type": "APPEND_ARRAY",
965
- "path": "meetingHistory",
966
- "value": {
967
- "meetingId": "{{ context.currentMeeting.meetingId }}",
968
- "type": "{{ context.currentMeeting.type }}",
969
- "date": "{{ context.currentMeeting.scheduledDate }}",
970
- "quorumAchieved": "{{ context.currentMeeting.quorumPresent }}",
971
- "attendeeCount": "{{ context.currentMeeting.attendees.filter(a => a.present).length }}",
972
- "resolutionsPassed": "{{ event.resolutionsPassed }}",
973
- "minutesRef": "{{ event.minutesRef }}"
974
- }
975
- },
976
- {
977
- "type": "SET_CONTEXT",
978
- "path": "currentMeeting",
979
- "value": null
980
- },
981
- {
982
- "type": "EMIT_EVENT",
983
- "eventType": "BOARD_MEETING_ADJOURNED",
984
- "payload": {
985
- "boardId": "{{ context.boardId }}",
986
- "meetingId": "{{ context.currentMeeting.meetingId }}",
987
- "resolutionsPassed": "{{ event.resolutionsPassed }}"
988
- }
989
- }
990
- ]
991
- },
992
- "update_seats": {
993
- "from": "ACTIVE",
994
- "to": "ACTIVE",
995
- "description": "Change the number of authorized board seats (requires bylaw amendment)",
996
- "event": {
997
- "name": "update_seats",
998
- "payload": {
999
- "newAuthorizedSeats": {
1000
- "type": "integer",
1001
- "required": true
1002
- },
1003
- "bylawAmendmentRef": {
1004
- "type": "string",
1005
- "required": true
1006
- }
1007
- }
1008
- },
1009
- "guards": [
1010
- {
1011
- "name": "seatsNotLessThanFilled",
1012
- "description": "Cannot reduce below current filled seats",
1013
- "expression": "event.newAuthorizedSeats >= context.seats.filled"
1014
- }
1015
- ],
1016
- "effects": [
1017
- {
1018
- "type": "SET_CONTEXT",
1019
- "path": "seats.authorized",
1020
- "value": "{{ event.newAuthorizedSeats }}"
1021
- },
1022
- {
1023
- "type": "COMPUTE",
1024
- "path": "seats.vacant",
1025
- "expression": "event.newAuthorizedSeats - context.seats.filled"
1026
- }
1027
- ]
1028
- }
1029
- },
1030
- "crossMachineRefs": {
1031
- "entity": {
1032
- "machine": "corporate-entity",
1033
- "description": "Parent corporate entity",
1034
- "foreignKey": "entityId"
1035
- },
1036
- "resolutions": {
1037
- "machine": "corporate-resolution",
1038
- "description": "Board resolutions",
1039
- "foreignKey": "boardId"
1040
- },
1041
- "committees": {
1042
- "machine": "corporate-committee",
1043
- "description": "Board committees",
1044
- "foreignKey": "boardId"
1045
- },
1046
- "officers": {
1047
- "machine": "corporate-officers",
1048
- "description": "Officers appointed by board",
1049
- "foreignKey": "entityId"
1050
- }
1051
- },
1052
- "metadata": {
1053
- "author": "OttoChain",
1054
- "license": "MIT",
1055
- "tags": [
1056
- "corporate",
1057
- "governance",
1058
- "board",
1059
- "directors",
1060
- "meetings"
1061
- ],
1062
- "documentation": "https://ottochain.dev/docs/corporate/board"
1063
- }
1064
- }