@ottochain/sdk 2.2.5 → 2.4.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 (222) hide show
  1. package/dist/cjs/apps/contracts/index.js +15 -8
  2. package/dist/cjs/apps/contracts/state-machines/contract-agreement.js +89 -46
  3. package/dist/cjs/apps/contracts/state-machines/contract-escrow.js +152 -45
  4. package/dist/cjs/apps/contracts/state-machines/contract-universal.js +40 -8
  5. package/dist/cjs/apps/corporate/index.js +2 -2
  6. package/dist/cjs/apps/corporate/state-machines/corp-board.js +169 -59
  7. package/dist/cjs/apps/corporate/state-machines/corp-entity.js +245 -47
  8. package/dist/cjs/apps/corporate/state-machines/corp-securities.js +407 -99
  9. package/dist/cjs/apps/corporate/state-machines/corp-shareholders.js +151 -37
  10. package/dist/cjs/apps/governance/index.js +14 -14
  11. package/dist/cjs/apps/governance/state-machines/dao-multisig.js +85 -43
  12. package/dist/cjs/apps/governance/state-machines/dao-reputation.js +73 -43
  13. package/dist/cjs/apps/governance/state-machines/dao-single.js +55 -14
  14. package/dist/cjs/apps/governance/state-machines/dao-token.js +103 -45
  15. package/dist/cjs/apps/governance/state-machines/governance-simple.js +129 -65
  16. package/dist/cjs/apps/governance/state-machines/governance-universal.js +29 -5
  17. package/dist/cjs/apps/identity/constants.js +55 -14
  18. package/dist/cjs/apps/identity/index.js +27 -11
  19. package/dist/cjs/apps/identity/state-machines/identity-agent.js +57 -9
  20. package/dist/cjs/apps/identity/state-machines/identity-oracle.js +70 -27
  21. package/dist/cjs/apps/identity/state-machines/identity-registry.js +288 -0
  22. package/dist/cjs/apps/identity/state-machines/identity-universal.js +30 -6
  23. package/dist/cjs/apps/identity/state-machines/index.js +3 -1
  24. package/dist/cjs/apps/index.js +19 -8
  25. package/dist/cjs/apps/lending/assets.js +223 -0
  26. package/dist/cjs/apps/lending/credit-scoring.js +87 -0
  27. package/dist/cjs/apps/lending/eligibility.js +121 -0
  28. package/dist/cjs/apps/lending/index.js +91 -0
  29. package/dist/cjs/apps/lending/state-machines/index.js +9 -0
  30. package/dist/cjs/apps/lending/state-machines/lending-zk-loan.js +412 -0
  31. package/dist/cjs/apps/markets/index.js +21 -11
  32. package/dist/cjs/apps/markets/state-machines/market-auction.js +44 -19
  33. package/dist/cjs/apps/markets/state-machines/market-crowdfund.js +54 -29
  34. package/dist/cjs/apps/markets/state-machines/market-group-buy.js +53 -31
  35. package/dist/cjs/apps/markets/state-machines/market-prediction.js +120 -61
  36. package/dist/cjs/apps/markets/state-machines/market-universal.js +50 -10
  37. package/dist/cjs/apps/oracles/index.js +2 -2
  38. package/dist/cjs/errors.js +3 -3
  39. package/dist/cjs/generated/google/protobuf/struct.js +4 -4
  40. package/dist/cjs/generated/index.js +11 -7
  41. package/dist/cjs/generated/openapi.js +6 -0
  42. package/dist/cjs/generated/ottochain/apps/contracts/v1/contract.js +50 -50
  43. package/dist/cjs/generated/ottochain/apps/corporate/v1/corporate.js +19 -20
  44. package/dist/cjs/generated/ottochain/apps/governance/v1/governance.js +13 -13
  45. package/dist/cjs/generated/ottochain/apps/identity/v1/attestation.js +4 -4
  46. package/dist/cjs/generated/ottochain/apps/identity/v1/identity.js +124 -130
  47. package/dist/cjs/generated/ottochain/apps/markets/v1/market.js +107 -107
  48. package/dist/cjs/generated/ottochain/v1/common.js +1722 -1
  49. package/dist/cjs/generated/ottochain/v1/fiber.js +355 -5
  50. package/dist/cjs/generated/ottochain/v1/messages.js +775 -3
  51. package/dist/cjs/generated/ottochain/v1/records.js +350 -3
  52. package/dist/cjs/index.js +45 -7
  53. package/dist/cjs/openapi.js +2 -0
  54. package/dist/cjs/ottochain/drop-nulls.js +1 -2
  55. package/dist/cjs/ottochain/genesis-manifest.js +193 -0
  56. package/dist/cjs/ottochain/index.js +27 -13
  57. package/dist/cjs/ottochain/metagraph-client.js +65 -8
  58. package/dist/cjs/ottochain/snapshot.js +11 -12
  59. package/dist/cjs/ottochain/transaction.js +57 -14
  60. package/dist/cjs/ottochain/types.js +19 -1
  61. package/dist/cjs/privacy/index.js +14 -0
  62. package/dist/cjs/privacy/sealed-bid.js +210 -0
  63. package/dist/cjs/privacy/shield-app.js +131 -0
  64. package/dist/cjs/schema/effects.js +40 -0
  65. package/dist/cjs/schema/fiber-app.js +19 -13
  66. package/dist/cjs/schema/guard-lint.js +352 -0
  67. package/dist/cjs/schema/guards.js +246 -0
  68. package/dist/cjs/signing.js +80 -0
  69. package/dist/cjs/types.js +2 -3
  70. package/dist/cjs/validation.js +8 -8
  71. package/dist/cjs/verify.js +9 -4
  72. package/dist/cjs/zk/commit.js +53 -0
  73. package/dist/cjs/zk/guard.js +107 -0
  74. package/dist/cjs/zk/index.js +48 -0
  75. package/dist/cjs/zk/preimage.js +37 -0
  76. package/dist/cjs/zk/prover.js +87 -0
  77. package/dist/cjs/zk/registry.js +62 -0
  78. package/dist/cjs/zk/types.js +28 -0
  79. package/dist/cjs/zk/witness.js +19 -0
  80. package/dist/esm/apps/contracts/index.js +7 -3
  81. package/dist/esm/apps/contracts/state-machines/contract-agreement.js +89 -46
  82. package/dist/esm/apps/contracts/state-machines/contract-escrow.js +152 -45
  83. package/dist/esm/apps/contracts/state-machines/contract-universal.js +40 -8
  84. package/dist/esm/apps/corporate/state-machines/corp-board.js +169 -59
  85. package/dist/esm/apps/corporate/state-machines/corp-entity.js +245 -47
  86. package/dist/esm/apps/corporate/state-machines/corp-securities.js +407 -99
  87. package/dist/esm/apps/corporate/state-machines/corp-shareholders.js +151 -37
  88. package/dist/esm/apps/governance/state-machines/dao-multisig.js +85 -43
  89. package/dist/esm/apps/governance/state-machines/dao-reputation.js +73 -43
  90. package/dist/esm/apps/governance/state-machines/dao-single.js +55 -14
  91. package/dist/esm/apps/governance/state-machines/dao-token.js +103 -45
  92. package/dist/esm/apps/governance/state-machines/governance-simple.js +129 -65
  93. package/dist/esm/apps/governance/state-machines/governance-universal.js +29 -5
  94. package/dist/esm/apps/identity/constants.js +51 -12
  95. package/dist/esm/apps/identity/index.js +12 -7
  96. package/dist/esm/apps/identity/state-machines/identity-agent.js +57 -9
  97. package/dist/esm/apps/identity/state-machines/identity-oracle.js +70 -27
  98. package/dist/esm/apps/identity/state-machines/identity-registry.js +285 -0
  99. package/dist/esm/apps/identity/state-machines/identity-universal.js +30 -6
  100. package/dist/esm/apps/identity/state-machines/index.js +1 -0
  101. package/dist/esm/apps/index.js +1 -0
  102. package/dist/esm/apps/lending/assets.js +207 -0
  103. package/dist/esm/apps/lending/credit-scoring.js +81 -0
  104. package/dist/esm/apps/lending/eligibility.js +115 -0
  105. package/dist/esm/apps/lending/index.js +69 -0
  106. package/dist/esm/apps/lending/state-machines/index.js +5 -0
  107. package/dist/esm/apps/lending/state-machines/lending-zk-loan.js +409 -0
  108. package/dist/esm/apps/markets/index.js +8 -4
  109. package/dist/esm/apps/markets/state-machines/market-auction.js +44 -19
  110. package/dist/esm/apps/markets/state-machines/market-crowdfund.js +54 -29
  111. package/dist/esm/apps/markets/state-machines/market-group-buy.js +53 -31
  112. package/dist/esm/apps/markets/state-machines/market-prediction.js +120 -61
  113. package/dist/esm/apps/markets/state-machines/market-universal.js +50 -10
  114. package/dist/esm/generated/index.js +9 -5
  115. package/dist/esm/generated/openapi.js +5 -0
  116. package/dist/esm/generated/ottochain/apps/contracts/v1/contract.js +46 -46
  117. package/dist/esm/generated/ottochain/apps/identity/v1/identity.js +114 -120
  118. package/dist/esm/generated/ottochain/apps/markets/v1/market.js +100 -100
  119. package/dist/esm/generated/ottochain/v1/common.js +1718 -0
  120. package/dist/esm/generated/ottochain/v1/fiber.js +351 -1
  121. package/dist/esm/generated/ottochain/v1/messages.js +774 -2
  122. package/dist/esm/generated/ottochain/v1/records.js +349 -2
  123. package/dist/esm/index.js +23 -2
  124. package/dist/esm/openapi.js +1 -0
  125. package/dist/esm/ottochain/genesis-manifest.js +189 -0
  126. package/dist/esm/ottochain/index.js +4 -3
  127. package/dist/esm/ottochain/metagraph-client.js +65 -8
  128. package/dist/esm/ottochain/snapshot.js +4 -4
  129. package/dist/esm/ottochain/transaction.js +43 -3
  130. package/dist/esm/ottochain/types.js +18 -0
  131. package/dist/esm/privacy/index.js +6 -0
  132. package/dist/esm/privacy/sealed-bid.js +206 -0
  133. package/dist/esm/privacy/shield-app.js +127 -0
  134. package/dist/esm/schema/effects.js +35 -0
  135. package/dist/esm/schema/fiber-app.js +13 -6
  136. package/dist/esm/schema/guard-lint.js +346 -0
  137. package/dist/esm/schema/guards.js +229 -0
  138. package/dist/esm/signing.js +74 -0
  139. package/dist/esm/verify.js +8 -2
  140. package/dist/esm/zk/commit.js +44 -0
  141. package/dist/esm/zk/guard.js +99 -0
  142. package/dist/esm/zk/index.js +19 -0
  143. package/dist/esm/zk/preimage.js +30 -0
  144. package/dist/esm/zk/prover.js +82 -0
  145. package/dist/esm/zk/registry.js +55 -0
  146. package/dist/esm/zk/types.js +25 -0
  147. package/dist/esm/zk/witness.js +15 -0
  148. package/dist/types/apps/contracts/index.d.ts +159 -227
  149. package/dist/types/apps/contracts/state-machines/contract-agreement.d.ts +50 -101
  150. package/dist/types/apps/contracts/state-machines/contract-escrow.d.ts +86 -120
  151. package/dist/types/apps/contracts/state-machines/contract-universal.d.ts +20 -4
  152. package/dist/types/apps/corporate/index.d.ts +1040 -304
  153. package/dist/types/apps/corporate/state-machines/corp-board.d.ts +188 -52
  154. package/dist/types/apps/corporate/state-machines/corp-entity.d.ts +267 -62
  155. package/dist/types/apps/corporate/state-machines/corp-securities.d.ts +355 -131
  156. package/dist/types/apps/corporate/state-machines/corp-shareholders.d.ts +225 -53
  157. package/dist/types/apps/governance/index.d.ts +396 -417
  158. package/dist/types/apps/governance/state-machines/dao-multisig.d.ts +92 -95
  159. package/dist/types/apps/governance/state-machines/dao-reputation.d.ts +57 -69
  160. package/dist/types/apps/governance/state-machines/dao-single.d.ts +40 -50
  161. package/dist/types/apps/governance/state-machines/dao-token.d.ts +80 -53
  162. package/dist/types/apps/governance/state-machines/governance-simple.d.ts +107 -121
  163. package/dist/types/apps/governance/state-machines/governance-universal.d.ts +17 -5
  164. package/dist/types/apps/identity/constants.d.ts +32 -4
  165. package/dist/types/apps/identity/index.d.ts +449 -100
  166. package/dist/types/apps/identity/state-machines/identity-agent.d.ts +30 -0
  167. package/dist/types/apps/identity/state-machines/identity-oracle.d.ts +41 -87
  168. package/dist/types/apps/identity/state-machines/identity-registry.d.ts +379 -0
  169. package/dist/types/apps/identity/state-machines/identity-universal.d.ts +15 -0
  170. package/dist/types/apps/identity/state-machines/index.d.ts +1 -0
  171. package/dist/types/apps/index.d.ts +1 -0
  172. package/dist/types/apps/lending/assets.d.ts +258 -0
  173. package/dist/types/apps/lending/credit-scoring.d.ts +80 -0
  174. package/dist/types/apps/lending/eligibility.d.ts +83 -0
  175. package/dist/types/apps/lending/index.d.ts +548 -0
  176. package/dist/types/apps/lending/state-machines/index.d.ts +5 -0
  177. package/dist/types/apps/lending/state-machines/lending-zk-loan.d.ts +528 -0
  178. package/dist/types/apps/markets/index.d.ts +184 -204
  179. package/dist/types/apps/markets/state-machines/market-auction.d.ts +25 -37
  180. package/dist/types/apps/markets/state-machines/market-crowdfund.d.ts +26 -34
  181. package/dist/types/apps/markets/state-machines/market-group-buy.d.ts +31 -43
  182. package/dist/types/apps/markets/state-machines/market-prediction.d.ts +67 -72
  183. package/dist/types/apps/markets/state-machines/market-universal.d.ts +30 -10
  184. package/dist/types/generated/index.d.ts +5 -5
  185. package/dist/types/generated/openapi.d.ts +1257 -0
  186. package/dist/types/generated/ottochain/apps/contracts/v1/contract.d.ts +5 -5
  187. package/dist/types/generated/ottochain/apps/identity/v1/identity.d.ts +12 -12
  188. package/dist/types/generated/ottochain/apps/markets/v1/market.d.ts +11 -11
  189. package/dist/types/generated/ottochain/v1/common.d.ts +228 -0
  190. package/dist/types/generated/ottochain/v1/fiber.d.ts +32 -1
  191. package/dist/types/generated/ottochain/v1/messages.d.ts +84 -0
  192. package/dist/types/generated/ottochain/v1/records.d.ts +34 -0
  193. package/dist/types/index.d.ts +8 -2
  194. package/dist/types/openapi.d.ts +22 -0
  195. package/dist/types/ottochain/genesis-manifest.d.ts +130 -0
  196. package/dist/types/ottochain/index.d.ts +6 -5
  197. package/dist/types/ottochain/metagraph-client.d.ts +49 -7
  198. package/dist/types/ottochain/snapshot.d.ts +6 -6
  199. package/dist/types/ottochain/transaction.d.ts +33 -1
  200. package/dist/types/ottochain/types.d.ts +602 -11
  201. package/dist/types/privacy/index.d.ts +6 -0
  202. package/dist/types/privacy/sealed-bid.d.ts +348 -0
  203. package/dist/types/privacy/shield-app.d.ts +48 -0
  204. package/dist/types/schema/effects.d.ts +34 -0
  205. package/dist/types/schema/fiber-app.d.ts +41 -3
  206. package/dist/types/schema/guard-lint.d.ts +111 -0
  207. package/dist/types/schema/guards.d.ts +134 -0
  208. package/dist/types/signing.d.ts +45 -0
  209. package/dist/types/validation.d.ts +22 -217
  210. package/dist/types/verify.d.ts +4 -0
  211. package/dist/types/zk/commit.d.ts +28 -0
  212. package/dist/types/zk/guard.d.ts +46 -0
  213. package/dist/types/zk/index.d.ts +19 -0
  214. package/dist/types/zk/preimage.d.ts +10 -0
  215. package/dist/types/zk/prover.d.ts +34 -0
  216. package/dist/types/zk/registry.d.ts +34 -0
  217. package/dist/types/zk/types.d.ts +33 -0
  218. package/dist/types/zk/witness.d.ts +40 -0
  219. package/package.json +52 -35
  220. package/dist/cjs/ottochain/normalize.js +0 -186
  221. package/dist/esm/ottochain/normalize.js +0 -179
  222. package/dist/types/ottochain/normalize.d.ts +0 -79
@@ -1,4 +1,5 @@
1
1
  import { defineFiberApp } from "../../../schema/fiber-app.js";
2
+ import { actorHasEntry, signerHasEntry, signerInSet, signerIsAnyParty, signerIsNotParty, } from "../../../schema/guards.js";
2
3
  /**
3
4
  * Simple org governance: manage members, update rules, resolve disputes.
4
5
  */
@@ -89,11 +90,8 @@ export const govSimpleDef = defineFiberApp({
89
90
  },
90
91
  },
91
92
  finalize: {
92
- description: "Finalize the voting period",
93
- required: ["forCount"],
94
- properties: {
95
- forCount: { type: "number" },
96
- },
93
+ description: "Finalize the voting period (for-count derived from recorded ballots)",
94
+ properties: {},
97
95
  },
98
96
  file_dispute: {
99
97
  description: "File a dispute against a member",
@@ -122,18 +120,47 @@ export const govSimpleDef = defineFiberApp({
122
120
  },
123
121
  },
124
122
  dissolve: {
125
- description: "Dissolve the organization (requires 90% approval)",
126
- required: ["approvalCount"],
127
- properties: {
128
- approvalCount: { type: "number" },
129
- },
123
+ description: "Dissolve the organization (requires every member to sign this op — verified unanimity)",
124
+ properties: {},
130
125
  },
131
126
  },
132
127
  states: {
133
- ACTIVE: { id: "ACTIVE", isFinal: false, metadata: null },
134
- VOTING: { id: "VOTING", isFinal: false, metadata: null },
135
- DISPUTE: { id: "DISPUTE", isFinal: false, metadata: null },
136
- DISSOLVED: { id: "DISSOLVED", isFinal: true, metadata: null },
128
+ ACTIVE: {
129
+ id: "ACTIVE",
130
+ isFinal: false,
131
+ metadata: {
132
+ label: "Active",
133
+ description: "Governance is idle and ready to accept a proposal",
134
+ category: "initial",
135
+ },
136
+ },
137
+ VOTING: {
138
+ id: "VOTING",
139
+ isFinal: false,
140
+ metadata: {
141
+ label: "Voting",
142
+ description: "A proposal is open for voting",
143
+ category: "pending",
144
+ },
145
+ },
146
+ DISPUTE: {
147
+ id: "DISPUTE",
148
+ isFinal: false,
149
+ metadata: {
150
+ label: "Dispute",
151
+ description: "A proposal outcome is being disputed",
152
+ category: "pending",
153
+ },
154
+ },
155
+ DISSOLVED: {
156
+ id: "DISSOLVED",
157
+ isFinal: true,
158
+ metadata: {
159
+ label: "Dissolved",
160
+ description: "Governance entity dissolved (terminal)",
161
+ category: "terminal",
162
+ },
163
+ },
137
164
  },
138
165
  initialState: "ACTIVE",
139
166
  transitions: [
@@ -142,16 +169,16 @@ export const govSimpleDef = defineFiberApp({
142
169
  from: "ACTIVE",
143
170
  to: "ACTIVE",
144
171
  eventName: "add_member",
145
- guard: { in: [{ var: "event.agent" }, { var: "state.admins" }] },
172
+ guard: signerInSet("state.admins"),
146
173
  effect: {
147
174
  merge: [
148
175
  { var: "state" },
149
176
  {
150
177
  members: {
151
- setKey: [
178
+ set: [
152
179
  { var: "state.members" },
153
180
  { var: "event.member" },
154
- { role: { var: "event.role" }, addedAt: { var: "$timestamp" } },
181
+ { role: { var: "event.role" }, addedAt: { var: "$ordinal" } },
155
182
  ],
156
183
  },
157
184
  },
@@ -164,13 +191,13 @@ export const govSimpleDef = defineFiberApp({
164
191
  from: "ACTIVE",
165
192
  to: "ACTIVE",
166
193
  eventName: "remove_member",
167
- guard: { in: [{ var: "event.agent" }, { var: "state.admins" }] },
194
+ guard: signerInSet("state.admins"),
168
195
  effect: {
169
196
  merge: [
170
197
  { var: "state" },
171
198
  {
172
199
  members: {
173
- deleteKey: [{ var: "state.members" }, { var: "event.member" }],
200
+ unset: [{ var: "state.members" }, { var: "event.member" }],
174
201
  },
175
202
  },
176
203
  ],
@@ -182,7 +209,9 @@ export const govSimpleDef = defineFiberApp({
182
209
  from: "ACTIVE",
183
210
  to: "VOTING",
184
211
  eventName: "propose",
185
- guard: { getKey: [{ var: "state.members" }, { var: "event.agent" }] },
212
+ // S1/A2 coupled fix: a CHAIN-VERIFIED signer must be a member (getKey is not a
213
+ // JLVM opcode; signerHasEntry checks signer ∈ keys(state.members) via `has`).
214
+ guard: signerHasEntry("state.members"),
186
215
  effect: {
187
216
  merge: [
188
217
  { var: "state" },
@@ -192,9 +221,9 @@ export const govSimpleDef = defineFiberApp({
192
221
  type: { var: "event.type" },
193
222
  changes: { var: "event.changes" },
194
223
  proposer: { var: "event.agent" },
195
- proposedAt: { var: "$timestamp" },
224
+ proposedAt: { var: "$ordinal" },
196
225
  deadline: {
197
- "+": [{ var: "$timestamp" }, { var: "state.votingPeriodMs" }],
226
+ "+": [{ var: "$ordinal" }, { var: "state.votingPeriodMs" }],
198
227
  },
199
228
  },
200
229
  votes: {},
@@ -208,12 +237,14 @@ export const govSimpleDef = defineFiberApp({
208
237
  from: "VOTING",
209
238
  to: "VOTING",
210
239
  eventName: "vote",
240
+ // S1/A2 coupled fix: bind event.agent to a verified signer who is a member (actorHasEntry),
241
+ // and block a re-vote by that SAME bound actor — so the ballot is recorded under, and deduped
242
+ // on, the chain-verified voter. Without the binding, signerHasEntry only proves SOME signer is a
243
+ // member, letting one member stuff votes under arbitrary keys (set is the rc.5 map-write opcode).
211
244
  guard: {
212
245
  and: [
213
- { getKey: [{ var: "state.members" }, { var: "event.agent" }] },
214
- {
215
- "!": [{ getKey: [{ var: "state.votes" }, { var: "event.agent" }] }],
216
- },
246
+ actorHasEntry("state.members"),
247
+ { "!": [{ has: [{ var: "state.votes" }, { var: "event.agent" }] }] },
217
248
  ],
218
249
  },
219
250
  effect: {
@@ -221,10 +252,10 @@ export const govSimpleDef = defineFiberApp({
221
252
  { var: "state" },
222
253
  {
223
254
  votes: {
224
- setKey: [
255
+ set: [
225
256
  { var: "state.votes" },
226
257
  { var: "event.agent" },
227
- { vote: { var: "event.vote" }, votedAt: { var: "$timestamp" } },
258
+ { vote: { var: "event.vote" }, votedAt: { var: "$ordinal" } },
228
259
  ],
229
260
  },
230
261
  },
@@ -237,12 +268,24 @@ export const govSimpleDef = defineFiberApp({
237
268
  from: "VOTING",
238
269
  to: "ACTIVE",
239
270
  eventName: "finalize",
271
+ // S2/A2 coupled fix: the for-count is DERIVED from recorded ballots in
272
+ // state.votes (length of the "for" entries), never read from the attacker's
273
+ // event.forCount. members is a Map so its count is length(keys(members)).
240
274
  guard: {
241
275
  ">=": [
242
- { var: "event.forCount" },
276
+ {
277
+ length: [
278
+ {
279
+ filter: [
280
+ { values: [{ var: "state.votes" }] },
281
+ { "===": [{ var: "vote" }, "for"] },
282
+ ],
283
+ },
284
+ ],
285
+ },
243
286
  {
244
287
  "*": [
245
- { size: { var: "state.members" } },
288
+ { length: [{ keys: [{ var: "state.members" }] }] },
246
289
  { var: "state.passingThreshold" },
247
290
  ],
248
291
  },
@@ -266,7 +309,7 @@ export const govSimpleDef = defineFiberApp({
266
309
  type: "rule_change",
267
310
  proposal: { var: "state.proposal" },
268
311
  outcome: "passed",
269
- finalizedAt: { var: "$timestamp" },
312
+ finalizedAt: { var: "$ordinal" },
270
313
  },
271
314
  ],
272
315
  ],
@@ -283,12 +326,23 @@ export const govSimpleDef = defineFiberApp({
283
326
  from: "VOTING",
284
327
  to: "ACTIVE",
285
328
  eventName: "finalize",
329
+ // S2/A2 coupled fix (failed arm): derive the for-count from recorded ballots in
330
+ // state.votes; never from event.forCount. members count = length(keys(members)).
286
331
  guard: {
287
332
  "<": [
288
- { var: "event.forCount" },
333
+ {
334
+ length: [
335
+ {
336
+ filter: [
337
+ { values: [{ var: "state.votes" }] },
338
+ { "===": [{ var: "vote" }, "for"] },
339
+ ],
340
+ },
341
+ ],
342
+ },
289
343
  {
290
344
  "*": [
291
- { size: { var: "state.members" } },
345
+ { length: [{ keys: [{ var: "state.members" }] }] },
292
346
  { var: "state.passingThreshold" },
293
347
  ],
294
348
  },
@@ -306,7 +360,7 @@ export const govSimpleDef = defineFiberApp({
306
360
  type: "rule_change",
307
361
  proposal: { var: "state.proposal" },
308
362
  outcome: "failed",
309
- finalizedAt: { var: "$timestamp" },
363
+ finalizedAt: { var: "$ordinal" },
310
364
  },
311
365
  ],
312
366
  ],
@@ -323,7 +377,9 @@ export const govSimpleDef = defineFiberApp({
323
377
  from: "ACTIVE",
324
378
  to: "DISPUTE",
325
379
  eventName: "file_dispute",
326
- guard: { getKey: [{ var: "state.members" }, { var: "event.agent" }] },
380
+ // S1/A2 coupled fix: only a CHAIN-VERIFIED member may file (getKey is not a JLVM
381
+ // opcode; signerHasEntry checks signer ∈ keys(state.members) via `has`).
382
+ guard: signerHasEntry("state.members"),
327
383
  effect: {
328
384
  merge: [
329
385
  { var: "state" },
@@ -333,7 +389,7 @@ export const govSimpleDef = defineFiberApp({
333
389
  plaintiff: { var: "event.agent" },
334
390
  defendant: { var: "event.defendant" },
335
391
  claim: { var: "event.claim" },
336
- filedAt: { var: "$timestamp" },
392
+ filedAt: { var: "$ordinal" },
337
393
  evidence: [],
338
394
  },
339
395
  votes: {},
@@ -347,16 +403,10 @@ export const govSimpleDef = defineFiberApp({
347
403
  from: "DISPUTE",
348
404
  to: "DISPUTE",
349
405
  eventName: "submit_evidence",
350
- guard: {
351
- or: [
352
- {
353
- "===": [{ var: "event.agent" }, { var: "state.dispute.plaintiff" }],
354
- },
355
- {
356
- "===": [{ var: "event.agent" }, { var: "state.dispute.defendant" }],
357
- },
358
- ],
359
- },
406
+ guard: signerIsAnyParty([
407
+ "state.dispute.plaintiff",
408
+ "state.dispute.defendant",
409
+ ]),
360
410
  effect: {
361
411
  merge: [
362
412
  { var: "state" },
@@ -372,7 +422,7 @@ export const govSimpleDef = defineFiberApp({
372
422
  {
373
423
  from: { var: "event.agent" },
374
424
  content: { var: "event.content" },
375
- at: { var: "$timestamp" },
425
+ at: { var: "$ordinal" },
376
426
  },
377
427
  ],
378
428
  ],
@@ -390,18 +440,16 @@ export const govSimpleDef = defineFiberApp({
390
440
  from: "DISPUTE",
391
441
  to: "DISPUTE",
392
442
  eventName: "vote",
443
+ // S1/A2 coupled fix: bind event.agent to a verified member (actorHasEntry), exclude the parties,
444
+ // and block a re-vote by that SAME bound actor — so the dispute ballot is recorded under, and
445
+ // deduped on, the chain-verified voter (set is the rc.5 map-write opcode; signerIsNotParty still
446
+ // excludes any signer who is a party, which covers the bound actor).
393
447
  guard: {
394
448
  and: [
395
- { getKey: [{ var: "state.members" }, { var: "event.agent" }] },
396
- {
397
- "!==": [{ var: "event.agent" }, { var: "state.dispute.plaintiff" }],
398
- },
399
- {
400
- "!==": [{ var: "event.agent" }, { var: "state.dispute.defendant" }],
401
- },
402
- {
403
- "!": [{ getKey: [{ var: "state.votes" }, { var: "event.agent" }] }],
404
- },
449
+ actorHasEntry("state.members"),
450
+ signerIsNotParty("state.dispute.plaintiff"),
451
+ signerIsNotParty("state.dispute.defendant"),
452
+ { "!": [{ has: [{ var: "state.votes" }, { var: "event.agent" }] }] },
405
453
  ],
406
454
  },
407
455
  effect: {
@@ -409,12 +457,12 @@ export const govSimpleDef = defineFiberApp({
409
457
  { var: "state" },
410
458
  {
411
459
  votes: {
412
- setKey: [
460
+ set: [
413
461
  { var: "state.votes" },
414
462
  { var: "event.agent" },
415
463
  {
416
464
  ruling: { var: "event.ruling" },
417
- votedAt: { var: "$timestamp" },
465
+ votedAt: { var: "$ordinal" },
418
466
  },
419
467
  ],
420
468
  },
@@ -428,9 +476,11 @@ export const govSimpleDef = defineFiberApp({
428
476
  from: "DISPUTE",
429
477
  to: "ACTIVE",
430
478
  eventName: "resolve",
479
+ // A2 fix: count recorded ballots. votes is a Map, and `length` rejects Maps, so
480
+ // count its keys: length(keys(state.votes)). (size is not a JLVM opcode.)
431
481
  guard: {
432
482
  ">=": [
433
- { size: { var: "state.votes" } },
483
+ { length: [{ keys: [{ var: "state.votes" }] }] },
434
484
  { var: "state.disputeQuorum" },
435
485
  ],
436
486
  },
@@ -447,7 +497,7 @@ export const govSimpleDef = defineFiberApp({
447
497
  dispute: { var: "state.dispute" },
448
498
  ruling: { var: "event.ruling" },
449
499
  remedy: { var: "event.remedy" },
450
- resolvedAt: { var: "$timestamp" },
500
+ resolvedAt: { var: "$ordinal" },
451
501
  },
452
502
  ],
453
503
  ],
@@ -464,14 +514,28 @@ export const govSimpleDef = defineFiberApp({
464
514
  from: "ACTIVE",
465
515
  to: "DISSOLVED",
466
516
  eventName: "dissolve",
517
+ // S2/A2 coupled fix: dissolution must not trust an attacker-supplied
518
+ // approvalCount. Derive consent from the CHAIN-VERIFIED signers — every member
519
+ // (a key in state.members) must be among proofs[].address, with a non-empty
520
+ // belt. members is a Map, so iterate keys(members); size is not a JLVM opcode.
467
521
  guard: {
468
- ">=": [
469
- { var: "event.approvalCount" },
470
- { "*": [{ size: { var: "state.members" } }, 0.9] },
522
+ and: [
523
+ { ">": [{ length: [{ keys: [{ var: "state.members" }] }] }, 0] },
524
+ {
525
+ all: [
526
+ { keys: [{ var: "state.members" }] },
527
+ {
528
+ in: [
529
+ { var: "" },
530
+ { map: [{ var: "proofs" }, { var: "address" }] },
531
+ ],
532
+ },
533
+ ],
534
+ },
471
535
  ],
472
536
  },
473
537
  effect: {
474
- merge: [{ var: "state" }, { dissolvedAt: { var: "$timestamp" } }],
538
+ merge: [{ var: "state" }, { dissolvedAt: { var: "$ordinal" } }],
475
539
  },
476
540
  dependencies: [],
477
541
  },
@@ -49,9 +49,33 @@ export const govUniversalDef = defineFiberApp({
49
49
  },
50
50
  },
51
51
  states: {
52
- ACTIVE: { id: "ACTIVE", isFinal: false, metadata: null },
53
- VOTING: { id: "VOTING", isFinal: false, metadata: null },
54
- DISSOLVED: { id: "DISSOLVED", isFinal: true, metadata: null },
52
+ ACTIVE: {
53
+ id: "ACTIVE",
54
+ isFinal: false,
55
+ metadata: {
56
+ label: "Active",
57
+ description: "Governance is idle and ready to accept a proposal",
58
+ category: "initial",
59
+ },
60
+ },
61
+ VOTING: {
62
+ id: "VOTING",
63
+ isFinal: false,
64
+ metadata: {
65
+ label: "Voting",
66
+ description: "A proposal is open for voting",
67
+ category: "pending",
68
+ },
69
+ },
70
+ DISSOLVED: {
71
+ id: "DISSOLVED",
72
+ isFinal: true,
73
+ metadata: {
74
+ label: "Dissolved",
75
+ description: "Governance entity dissolved (terminal)",
76
+ category: "terminal",
77
+ },
78
+ },
55
79
  },
56
80
  initialState: "ACTIVE",
57
81
  transitions: [
@@ -66,7 +90,7 @@ export const govUniversalDef = defineFiberApp({
66
90
  {
67
91
  status: "VOTING",
68
92
  proposal: { var: "event.proposal" },
69
- proposedAt: { var: "$timestamp" },
93
+ proposedAt: { var: "$ordinal" },
70
94
  votes: {},
71
95
  },
72
96
  ],
@@ -125,7 +149,7 @@ export const govUniversalDef = defineFiberApp({
125
149
  { var: "state" },
126
150
  {
127
151
  status: "DISSOLVED",
128
- dissolvedAt: { var: "$timestamp" },
152
+ dissolvedAt: { var: "$ordinal" },
129
153
  },
130
154
  ],
131
155
  },
@@ -5,7 +5,7 @@
5
5
  *
6
6
  * @packageDocumentation
7
7
  */
8
- import { IdentityState } from "../../generated/ottochain/apps/identity/v1/identity.js";
8
+ import { State } from "../../generated/ottochain/apps/identity/v1/identity.js";
9
9
  import { AttestationType } from "../../generated/ottochain/apps/identity/v1/attestation.js";
10
10
  // ---------------------------------------------------------------------------
11
11
  // State Machine Transitions
@@ -16,25 +16,25 @@ import { AttestationType } from "../../generated/ottochain/apps/identity/v1/atte
16
16
  * Note: Some transitions are type-specific (agent vs oracle)
17
17
  */
18
18
  export const IDENTITY_TRANSITIONS = {
19
- [IdentityState.IDENTITY_STATE_UNSPECIFIED]: [],
20
- [IdentityState.IDENTITY_STATE_UNREGISTERED]: ["register"],
21
- [IdentityState.IDENTITY_STATE_REGISTERED]: ["activate", "withdraw"],
22
- [IdentityState.IDENTITY_STATE_ACTIVE]: [
19
+ [State.IDENTITY_STATE_UNSPECIFIED]: [],
20
+ [State.IDENTITY_STATE_UNREGISTERED]: ["register"],
21
+ [State.IDENTITY_STATE_REGISTERED]: ["activate", "withdraw"],
22
+ [State.IDENTITY_STATE_ACTIVE]: [
23
23
  "challenge",
24
24
  "slash",
25
25
  "deactivate",
26
26
  "withdraw",
27
27
  ],
28
- [IdentityState.IDENTITY_STATE_CHALLENGED]: [
28
+ [State.IDENTITY_STATE_CHALLENGED]: [
29
29
  "uphold_challenge",
30
30
  "dismiss_challenge",
31
31
  ],
32
- [IdentityState.IDENTITY_STATE_SUSPENDED]: ["begin_probation"],
33
- [IdentityState.IDENTITY_STATE_PROBATION]: ["complete_probation"],
34
- [IdentityState.IDENTITY_STATE_SLASHED]: ["reactivate", "withdraw"],
35
- [IdentityState.IDENTITY_STATE_INACTIVE]: ["activate", "withdraw"],
36
- [IdentityState.IDENTITY_STATE_WITHDRAWN]: [], // Terminal state
37
- [IdentityState.UNRECOGNIZED]: [],
32
+ [State.IDENTITY_STATE_SUSPENDED]: ["begin_probation"],
33
+ [State.IDENTITY_STATE_PROBATION]: ["complete_probation"],
34
+ [State.IDENTITY_STATE_SLASHED]: ["reactivate", "withdraw"],
35
+ [State.IDENTITY_STATE_INACTIVE]: ["activate", "withdraw"],
36
+ [State.IDENTITY_STATE_WITHDRAWN]: [], // Terminal state
37
+ [State.UNRECOGNIZED]: [],
38
38
  };
39
39
  // Legacy alias
40
40
  export const AGENT_TRANSITIONS = IDENTITY_TRANSITIONS;
@@ -53,6 +53,45 @@ export const ATTESTATION_DELTAS = {
53
53
  [AttestationType.ATTESTATION_TYPE_BEHAVIORAL]: 3,
54
54
  [AttestationType.UNRECOGNIZED]: 0,
55
55
  };
56
+ // ---------------------------------------------------------------------------
57
+ // Identity Registry — role attestations
58
+ // ---------------------------------------------------------------------------
59
+ /**
60
+ * Role-attestation types issued by the identity registry (identity-registry fiber).
61
+ * These are the ecosystem-wide authority roles consumer apps gate on via the registry
62
+ * dependency + `signerHasRole` (see docs/design/app-hardening-identity-integration.md §4.2).
63
+ */
64
+ export const REGISTRY_ROLES = {
65
+ ARBITER: "ARBITER",
66
+ SLASHER: "SLASHER",
67
+ ISSUER: "ISSUER",
68
+ BOARD_MEMBER: "BOARD_MEMBER",
69
+ };
70
+ /**
71
+ * Maps each role to the registry's flat per-role state-map field. A consumer app reads
72
+ * `machines.<registryDep>.state.<field>` (a `{ <address>: true }` map) and binds membership to a
73
+ * verified signer with `signerHasRole`. Kept in lock-step with the identity-registry stateSchema.
74
+ */
75
+ export const REGISTRY_ROLE_MAP = {
76
+ ARBITER: "arbiters",
77
+ SLASHER: "slashers",
78
+ ISSUER: "issuers",
79
+ BOARD_MEMBER: "boardMembers",
80
+ };
81
+ /**
82
+ * Build the `machines.<registryDep>.state.<roleMap>` var path a consumer guard reads to check a role,
83
+ * e.g. `registryRolePath("reg-uuid", "ARBITER")` → `"machines.reg-uuid.state.arbiters"`.
84
+ */
85
+ export function registryRolePath(registryDep, role) {
86
+ return `machines.${registryDep}.state.${REGISTRY_ROLE_MAP[role]}`;
87
+ }
88
+ /**
89
+ * Build the `machines.<registryDep>.state.reputations` var path a consumer guard reads for a
90
+ * reputation gate (`signerHasReputation`).
91
+ */
92
+ export function registryReputationPath(registryDep) {
93
+ return `machines.${registryDep}.state.reputations`;
94
+ }
56
95
  /**
57
96
  * Check if a transition is valid for the given state.
58
97
  */
@@ -16,13 +16,17 @@
16
16
  *
17
17
  * @packageDocumentation
18
18
  */
19
- // Re-export generated protobuf types (source of truth)
20
- export { IdentityType, IdentityState, Platform, PlatformLink, Reputation, PenaltyEvent, Identity, RegisterIdentityRequest, ActivateIdentityRequest, LinkPlatformRequest, ChallengeIdentityRequest, AddStakeRequest, WithdrawIdentityRequest, IdentityDefinition, identityTypeFromJSON, identityTypeToJSON, identityStateFromJSON, identityStateToJSON, platformFromJSON, platformToJSON, } from "../../generated/ottochain/apps/identity/v1/identity.js";
19
+ // Re-export generated protobuf types (source of truth).
20
+ // The nested lifecycle/kind enums dropped their app prefix in the proto; under
21
+ // this app-scoped entrypoint they are unambiguously Type / State.
22
+ export { Type, State, Platform, PlatformLink, Reputation, PenaltyEvent, Identity, RegisterIdentityRequest, ActivateIdentityRequest, LinkPlatformRequest, ChallengeIdentityRequest, AddStakeRequest, WithdrawIdentityRequest, IdentityDefinition, typeFromJSON, typeToJSON, stateFromJSON, stateToJSON, platformFromJSON, platformToJSON, } from "../../generated/ottochain/apps/identity/v1/identity.js";
21
23
  // Legacy aliases for backward compatibility
22
- export { IdentityState as AgentState } from "../../generated/ottochain/apps/identity/v1/identity.js";
24
+ export { State as AgentState } from "../../generated/ottochain/apps/identity/v1/identity.js";
25
+ // Deprecated app-prefixed aliases (renamed to Type / State); kept for compat.
26
+ export { Type as IdentityType, State as IdentityState, typeFromJSON as identityTypeFromJSON, typeToJSON as identityTypeToJSON, stateFromJSON as identityStateFromJSON, stateToJSON as identityStateToJSON, } from "../../generated/ottochain/apps/identity/v1/identity.js";
23
27
  export { AttestationType, ReputationDelta, Attestation, VouchRequest, ChallengeRequest, ReputationConfig, attestationTypeFromJSON, attestationTypeToJSON, } from "../../generated/ottochain/apps/identity/v1/attestation.js";
24
28
  // Re-export constants and utilities
25
- export { IDENTITY_TRANSITIONS, AGENT_TRANSITIONS, ATTESTATION_DELTAS, canTransition, getReputationDelta, } from "./constants.js";
29
+ export { IDENTITY_TRANSITIONS, AGENT_TRANSITIONS, ATTESTATION_DELTAS, REGISTRY_ROLES, REGISTRY_ROLE_MAP, registryRolePath, registryReputationPath, canTransition, getReputationDelta, } from "./constants.js";
26
30
  // ---------------------------------------------------------------------------
27
31
  // Configuration Defaults
28
32
  // ---------------------------------------------------------------------------
@@ -41,17 +45,18 @@ export const DEFAULT_REPUTATION_CONFIG = {
41
45
  // ---------------------------------------------------------------------------
42
46
  // State Machine Definitions (generated from JSON at build time)
43
47
  // ---------------------------------------------------------------------------
44
- import { identityUniversalDef, identityAgentDef, identityOracleDef, } from "./state-machines/index.js";
45
- export { identityUniversalDef, identityAgentDef, identityOracleDef };
48
+ import { identityUniversalDef, identityAgentDef, identityOracleDef, identityRegistryDef, } from "./state-machines/index.js";
49
+ export { identityUniversalDef, identityAgentDef, identityOracleDef, identityRegistryDef, };
46
50
  /** All identity state machine definitions */
47
51
  export const IDENTITY_DEFINITIONS = {
48
52
  universal: identityUniversalDef,
49
53
  agent: identityAgentDef,
50
54
  oracle: identityOracleDef,
55
+ registry: identityRegistryDef,
51
56
  };
52
57
  /**
53
58
  * Get an identity state machine definition by type.
54
- * @param type - 'universal' | 'agent' | 'oracle' (default: 'agent')
59
+ * @param type - 'universal' | 'agent' | 'oracle' | 'registry' (default: 'agent')
55
60
  */
56
61
  export function getIdentityDefinition(type = "agent") {
57
62
  return IDENTITY_DEFINITIONS[type];
@@ -129,12 +129,60 @@ export const identityAgentDef = defineFiberApp({
129
129
  },
130
130
  },
131
131
  states: {
132
- REGISTERED: { id: "REGISTERED", isFinal: false },
133
- ACTIVE: { id: "ACTIVE", isFinal: false },
134
- CHALLENGED: { id: "CHALLENGED", isFinal: false },
135
- SUSPENDED: { id: "SUSPENDED", isFinal: false },
136
- PROBATION: { id: "PROBATION", isFinal: false },
137
- WITHDRAWN: { id: "WITHDRAWN", isFinal: true },
132
+ REGISTERED: {
133
+ id: "REGISTERED",
134
+ isFinal: false,
135
+ metadata: {
136
+ label: "Registered",
137
+ description: "Agent registered but not yet activated",
138
+ category: "initial",
139
+ },
140
+ },
141
+ ACTIVE: {
142
+ id: "ACTIVE",
143
+ isFinal: false,
144
+ metadata: {
145
+ label: "Active",
146
+ description: "Agent is active and accruing reputation",
147
+ category: "active",
148
+ },
149
+ },
150
+ CHALLENGED: {
151
+ id: "CHALLENGED",
152
+ isFinal: false,
153
+ metadata: {
154
+ label: "Challenged",
155
+ description: "A challenge has been raised; awaiting resolution",
156
+ category: "pending",
157
+ },
158
+ },
159
+ SUSPENDED: {
160
+ id: "SUSPENDED",
161
+ isFinal: false,
162
+ metadata: {
163
+ label: "Suspended",
164
+ description: "Agent suspended after an upheld challenge",
165
+ category: "pending",
166
+ },
167
+ },
168
+ PROBATION: {
169
+ id: "PROBATION",
170
+ isFinal: false,
171
+ metadata: {
172
+ label: "Probation",
173
+ description: "Conditional reinstatement under monitoring",
174
+ category: "active",
175
+ },
176
+ },
177
+ WITHDRAWN: {
178
+ id: "WITHDRAWN",
179
+ isFinal: true,
180
+ metadata: {
181
+ label: "Withdrawn",
182
+ description: "Agent withdrawn from the registry (terminal)",
183
+ category: "terminal",
184
+ },
185
+ },
138
186
  },
139
187
  initialState: "REGISTERED",
140
188
  transitions: [
@@ -146,7 +194,7 @@ export const identityAgentDef = defineFiberApp({
146
194
  effect: {
147
195
  merge: [
148
196
  { var: "state" },
149
- { status: "ACTIVE", activatedAt: { var: "$timestamp" } },
197
+ { status: "ACTIVE", activatedAt: { var: "$ordinal" } },
150
198
  ],
151
199
  },
152
200
  },
@@ -203,7 +251,7 @@ export const identityAgentDef = defineFiberApp({
203
251
  effect: {
204
252
  merge: [
205
253
  { var: "state" },
206
- { status: "SUSPENDED", suspendedAt: { var: "$timestamp" } },
254
+ { status: "SUSPENDED", suspendedAt: { var: "$ordinal" } },
207
255
  ],
208
256
  },
209
257
  },
@@ -215,7 +263,7 @@ export const identityAgentDef = defineFiberApp({
215
263
  effect: {
216
264
  merge: [
217
265
  { var: "state" },
218
- { status: "PROBATION", probationStartedAt: { var: "$timestamp" } },
266
+ { status: "PROBATION", probationStartedAt: { var: "$ordinal" } },
219
267
  ],
220
268
  },
221
269
  },