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