@ibgib/core-gib 0.1.59 → 0.1.61

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 (206) hide show
  1. package/CHANGELOG.md +12 -1
  2. package/dist/common/other/graph-helper.d.mts.map +1 -1
  3. package/dist/common/other/graph-helper.mjs +7 -6
  4. package/dist/common/other/graph-helper.mjs.map +1 -1
  5. package/dist/keystone/keystone-config-builder.d.mts +1 -2
  6. package/dist/keystone/keystone-config-builder.d.mts.map +1 -1
  7. package/dist/keystone/keystone-config-builder.mjs +4 -19
  8. package/dist/keystone/keystone-config-builder.mjs.map +1 -1
  9. package/dist/keystone/keystone-constants.d.mts +2 -0
  10. package/dist/keystone/keystone-constants.d.mts.map +1 -1
  11. package/dist/keystone/keystone-constants.mjs +2 -0
  12. package/dist/keystone/keystone-constants.mjs.map +1 -1
  13. package/dist/keystone/keystone-helpers.d.mts +5 -15
  14. package/dist/keystone/keystone-helpers.d.mts.map +1 -1
  15. package/dist/keystone/keystone-helpers.mjs +59 -73
  16. package/dist/keystone/keystone-helpers.mjs.map +1 -1
  17. package/dist/keystone/keystone-policy-types.d.mts +6 -4
  18. package/dist/keystone/keystone-policy-types.d.mts.map +1 -1
  19. package/dist/keystone/keystone-service-v1.d.mts.map +1 -1
  20. package/dist/keystone/keystone-service-v1.mjs +4 -8
  21. package/dist/keystone/keystone-service-v1.mjs.map +1 -1
  22. package/dist/keystone/keystone-service-v1.respec.mjs +182 -33
  23. package/dist/keystone/keystone-service-v1.respec.mjs.map +1 -1
  24. package/dist/keystone/keystone-types.d.mts +4 -11
  25. package/dist/keystone/keystone-types.d.mts.map +1 -1
  26. package/dist/keystone/policy/keystone-profile-builder.d.mts +25 -0
  27. package/dist/keystone/policy/keystone-profile-builder.d.mts.map +1 -0
  28. package/dist/keystone/policy/keystone-profile-builder.mjs +117 -0
  29. package/dist/keystone/policy/keystone-profile-builder.mjs.map +1 -0
  30. package/dist/keystone/policy/profiles/profile-high.json +84 -0
  31. package/dist/keystone/policy/profiles/profile-low.json +84 -0
  32. package/dist/keystone/policy/profiles/profile-medium.json +84 -0
  33. package/dist/keystone/policy/profiles/profile-session.json +84 -0
  34. package/dist/keystone/policy/profiles/profile-test.json +84 -0
  35. package/dist/keystone/policy/schemas/connect-pool.high.schema.json +23 -0
  36. package/dist/keystone/policy/schemas/connect-pool.low.schema.json +23 -0
  37. package/dist/keystone/policy/schemas/connect-pool.medium.schema.json +23 -0
  38. package/dist/keystone/policy/schemas/keystone.high.schema.json +26 -0
  39. package/dist/keystone/policy/schemas/keystone.low.schema.json +26 -0
  40. package/dist/keystone/policy/schemas/keystone.medium.schema.json +26 -0
  41. package/dist/keystone/policy/schemas/manage-pool.high.schema.json +23 -0
  42. package/dist/keystone/policy/schemas/manage-pool.low.schema.json +23 -0
  43. package/dist/keystone/policy/schemas/manage-pool.medium.schema.json +23 -0
  44. package/dist/keystone/policy/schemas/revoke-pool.high.schema.json +23 -0
  45. package/dist/keystone/policy/schemas/revoke-pool.low.schema.json +23 -0
  46. package/dist/keystone/policy/schemas/revoke-pool.medium.schema.json +23 -0
  47. package/dist/keystone/policy/schemas/sign-pool.high.schema.json +23 -0
  48. package/dist/keystone/policy/schemas/sign-pool.low.schema.json +23 -0
  49. package/dist/keystone/policy/schemas/sign-pool.medium.schema.json +23 -0
  50. package/dist/keystone/policy/schemas/sync-pool.high.schema.json +23 -0
  51. package/dist/keystone/policy/schemas/sync-pool.low.schema.json +23 -0
  52. package/dist/keystone/policy/schemas/sync-pool.medium.schema.json +23 -0
  53. package/dist/sync/sync-conflict-adv-multitimelines.withid.respec.d.mts +8 -0
  54. package/dist/sync/sync-conflict-adv-multitimelines.withid.respec.d.mts.map +1 -0
  55. package/dist/sync/sync-conflict-adv-multitimelines.withid.respec.mjs +582 -0
  56. package/dist/sync/sync-conflict-adv-multitimelines.withid.respec.mjs.map +1 -0
  57. package/dist/sync/sync-conflict-basic-divergence.withid.respec.d.mts +7 -0
  58. package/dist/sync/sync-conflict-basic-divergence.withid.respec.d.mts.map +1 -0
  59. package/dist/sync/sync-conflict-basic-divergence.withid.respec.mjs +274 -0
  60. package/dist/sync/sync-conflict-basic-divergence.withid.respec.mjs.map +1 -0
  61. package/dist/sync/sync-conflict-basic-multitimelines.withid.respec.d.mts +8 -0
  62. package/dist/sync/sync-conflict-basic-multitimelines.withid.respec.d.mts.map +1 -0
  63. package/dist/sync/sync-conflict-basic-multitimelines.withid.respec.mjs +322 -0
  64. package/dist/sync/sync-conflict-basic-multitimelines.withid.respec.mjs.map +1 -0
  65. package/dist/sync/sync-conflict-text-merge.withid.respec.d.mts +7 -0
  66. package/dist/sync/sync-conflict-text-merge.withid.respec.d.mts.map +1 -0
  67. package/dist/sync/sync-conflict-text-merge.withid.respec.mjs +307 -0
  68. package/dist/sync/sync-conflict-text-merge.withid.respec.mjs.map +1 -0
  69. package/dist/sync/sync-innerspace-constants.withid.respec.d.mts +8 -0
  70. package/dist/sync/sync-innerspace-constants.withid.respec.d.mts.map +1 -0
  71. package/dist/sync/sync-innerspace-constants.withid.respec.mjs +233 -0
  72. package/dist/sync/sync-innerspace-constants.withid.respec.mjs.map +1 -0
  73. package/dist/sync/sync-innerspace-deep-updates.withid.respec.d.mts +7 -0
  74. package/dist/sync/sync-innerspace-deep-updates.withid.respec.d.mts.map +1 -0
  75. package/dist/sync/sync-innerspace-deep-updates.withid.respec.mjs +233 -0
  76. package/dist/sync/sync-innerspace-deep-updates.withid.respec.mjs.map +1 -0
  77. package/dist/sync/sync-innerspace-dest-ahead.withid.respec.d.mts +7 -0
  78. package/dist/sync/sync-innerspace-dest-ahead.withid.respec.d.mts.map +1 -0
  79. package/dist/sync/sync-innerspace-dest-ahead.withid.respec.mjs +225 -0
  80. package/dist/sync/sync-innerspace-dest-ahead.withid.respec.mjs.map +1 -0
  81. package/dist/sync/sync-innerspace-multiple-timelines.respec.mjs.map +1 -1
  82. package/dist/sync/sync-innerspace-multiple-timelines.withid.respec.d.mts +7 -0
  83. package/dist/sync/sync-innerspace-multiple-timelines.withid.respec.d.mts.map +1 -0
  84. package/dist/sync/sync-innerspace-multiple-timelines.withid.respec.mjs +235 -0
  85. package/dist/sync/sync-innerspace-multiple-timelines.withid.respec.mjs.map +1 -0
  86. package/dist/sync/sync-innerspace-partial-update.withid.respec.d.mts +7 -0
  87. package/dist/sync/sync-innerspace-partial-update.withid.respec.d.mts.map +1 -0
  88. package/dist/sync/sync-innerspace-partial-update.withid.respec.mjs +211 -0
  89. package/dist/sync/sync-innerspace-partial-update.withid.respec.mjs.map +1 -0
  90. package/dist/sync/sync-innerspace.withid.respec.d.mts +8 -0
  91. package/dist/sync/sync-innerspace.withid.respec.d.mts.map +1 -0
  92. package/dist/sync/sync-innerspace.withid.respec.mjs +260 -0
  93. package/dist/sync/sync-innerspace.withid.respec.mjs.map +1 -0
  94. package/dist/sync/sync-peer/sync-peer-innerspace/sync-peer-innerspace-v1.mjs +1 -1
  95. package/dist/sync/sync-peer/sync-peer-innerspace/sync-peer-innerspace-v1.mjs.map +1 -1
  96. package/dist/sync/sync-peer/sync-peer-types.d.mts +12 -1
  97. package/dist/sync/sync-peer/sync-peer-types.d.mts.map +1 -1
  98. package/dist/sync/sync-peer/sync-peer-v1.d.mts +7 -0
  99. package/dist/sync/sync-peer/sync-peer-v1.d.mts.map +1 -1
  100. package/dist/sync/sync-peer/sync-peer-v1.mjs +43 -1
  101. package/dist/sync/sync-peer/sync-peer-v1.mjs.map +1 -1
  102. package/dist/sync/sync-peer/sync-peer-websocket/sync-peer-websocket-receiver/sync-peer-websocket-receiver-v1.d.mts +2 -0
  103. package/dist/sync/sync-peer/sync-peer-websocket/sync-peer-websocket-receiver/sync-peer-websocket-receiver-v1.d.mts.map +1 -1
  104. package/dist/sync/sync-peer/sync-peer-websocket/sync-peer-websocket-receiver/sync-peer-websocket-receiver-v1.mjs +28 -9
  105. package/dist/sync/sync-peer/sync-peer-websocket/sync-peer-websocket-receiver/sync-peer-websocket-receiver-v1.mjs.map +1 -1
  106. package/dist/sync/sync-peer/sync-peer-websocket/sync-peer-websocket-receiver/sync-websocket-peer-helpers.d.mts +1 -1
  107. package/dist/sync/sync-peer/sync-peer-websocket/sync-peer-websocket-receiver/sync-websocket-peer-helpers.d.mts.map +1 -1
  108. package/dist/sync/sync-peer/sync-peer-websocket/sync-peer-websocket-receiver/sync-websocket-peer-helpers.mjs +5 -3
  109. package/dist/sync/sync-peer/sync-peer-websocket/sync-peer-websocket-receiver/sync-websocket-peer-helpers.mjs.map +1 -1
  110. package/dist/sync/sync-peer/sync-peer-websocket/sync-peer-websocket-sender/sync-peer-websocket-sender-v1.d.mts +16 -0
  111. package/dist/sync/sync-peer/sync-peer-websocket/sync-peer-websocket-sender/sync-peer-websocket-sender-v1.d.mts.map +1 -1
  112. package/dist/sync/sync-peer/sync-peer-websocket/sync-peer-websocket-sender/sync-peer-websocket-sender-v1.mjs +223 -79
  113. package/dist/sync/sync-peer/sync-peer-websocket/sync-peer-websocket-sender/sync-peer-websocket-sender-v1.mjs.map +1 -1
  114. package/dist/sync/sync-saga-context/sync-saga-context-helpers.d.mts.map +1 -1
  115. package/dist/sync/sync-saga-context/sync-saga-context-helpers.mjs +41 -2
  116. package/dist/sync/sync-saga-context/sync-saga-context-helpers.mjs.map +1 -1
  117. package/dist/sync/sync-saga-context/sync-saga-context-types.d.mts +4 -0
  118. package/dist/sync/sync-saga-context/sync-saga-context-types.d.mts.map +1 -1
  119. package/dist/sync/sync-saga-coordinator.d.mts +6 -0
  120. package/dist/sync/sync-saga-coordinator.d.mts.map +1 -1
  121. package/dist/sync/sync-saga-coordinator.mjs +213 -137
  122. package/dist/sync/sync-saga-coordinator.mjs.map +1 -1
  123. package/dist/sync/sync-withid.pingpong.respec.mjs +70 -2
  124. package/dist/sync/sync-withid.pingpong.respec.mjs.map +1 -1
  125. package/dist/timeline/timeline-api.d.mts.map +1 -1
  126. package/dist/timeline/timeline-api.mjs +1 -14
  127. package/dist/timeline/timeline-api.mjs.map +1 -1
  128. package/dist/witness/space/reconciliation-space/reconciliation-space-base.d.mts.map +1 -1
  129. package/dist/witness/space/reconciliation-space/reconciliation-space-base.mjs +0 -40
  130. package/dist/witness/space/reconciliation-space/reconciliation-space-base.mjs.map +1 -1
  131. package/dist/witness/space/reconciliation-space/reconciliation-space-helper.d.mts.map +1 -1
  132. package/dist/witness/space/reconciliation-space/reconciliation-space-helper.mjs +6 -6
  133. package/dist/witness/space/reconciliation-space/reconciliation-space-helper.mjs.map +1 -1
  134. package/ibgib-foundations.md +2 -1
  135. package/package.json +1 -1
  136. package/src/common/other/graph-helper.mts +7 -6
  137. package/src/keystone/README.md +19 -15
  138. package/src/keystone/docs/CRYPTANALYSIS.md +185 -0
  139. package/src/keystone/docs/architecture.md +24 -1
  140. package/src/keystone/docs/profiles.md +124 -0
  141. package/src/keystone/keystone-config-builder.mts +3 -21
  142. package/src/keystone/keystone-constants.mts +2 -0
  143. package/src/keystone/keystone-helpers.mts +74 -77
  144. package/src/keystone/keystone-policy-types.mts +6 -4
  145. package/src/keystone/keystone-service-v1.mts +4 -9
  146. package/src/keystone/keystone-service-v1.respec.mts +214 -32
  147. package/src/keystone/keystone-types.mts +5 -9
  148. package/src/keystone/policy/IMPLEMENTATION.md +60 -0
  149. package/src/keystone/policy/README.md +94 -0
  150. package/src/keystone/policy/keystone-profile-builder.mts +131 -0
  151. package/src/keystone/policy/profiles/profile-high.json +84 -0
  152. package/src/keystone/policy/profiles/profile-low.json +84 -0
  153. package/src/keystone/policy/profiles/profile-medium.json +84 -0
  154. package/src/keystone/policy/profiles/profile-session.json +84 -0
  155. package/src/keystone/policy/profiles/profile-test.json +84 -0
  156. package/src/keystone/policy/schemas/connect-pool.high.schema.json +23 -0
  157. package/src/keystone/policy/schemas/connect-pool.low.schema.json +23 -0
  158. package/src/keystone/policy/schemas/connect-pool.medium.schema.json +23 -0
  159. package/src/keystone/policy/schemas/keystone.high.schema.json +26 -0
  160. package/src/keystone/policy/schemas/keystone.low.schema.json +26 -0
  161. package/src/keystone/policy/schemas/keystone.medium.schema.json +26 -0
  162. package/src/keystone/policy/schemas/manage-pool.high.schema.json +23 -0
  163. package/src/keystone/policy/schemas/manage-pool.low.schema.json +23 -0
  164. package/src/keystone/policy/schemas/manage-pool.medium.schema.json +23 -0
  165. package/src/keystone/policy/schemas/revoke-pool.high.schema.json +23 -0
  166. package/src/keystone/policy/schemas/revoke-pool.low.schema.json +23 -0
  167. package/src/keystone/policy/schemas/revoke-pool.medium.schema.json +23 -0
  168. package/src/keystone/policy/schemas/sign-pool.high.schema.json +23 -0
  169. package/src/keystone/policy/schemas/sign-pool.low.schema.json +23 -0
  170. package/src/keystone/policy/schemas/sign-pool.medium.schema.json +23 -0
  171. package/src/keystone/policy/schemas/sync-pool.high.schema.json +23 -0
  172. package/src/keystone/policy/schemas/sync-pool.low.schema.json +23 -0
  173. package/src/keystone/policy/schemas/sync-pool.medium.schema.json +23 -0
  174. package/src/sync/docs/security-3b.md +92 -0
  175. package/src/sync/docs/security.md +139 -38
  176. package/src/sync/sync-conflict-adv-multitimelines.withid.respec.mts +706 -0
  177. package/src/sync/sync-conflict-basic-divergence.withid.respec.mts +321 -0
  178. package/src/sync/sync-conflict-basic-multitimelines.withid.respec.mts +374 -0
  179. package/src/sync/sync-conflict-text-merge.withid.respec.mts +347 -0
  180. package/src/sync/sync-innerspace-constants.withid.respec.mts +264 -0
  181. package/src/sync/sync-innerspace-deep-updates.withid.respec.mts +272 -0
  182. package/src/sync/sync-innerspace-dest-ahead.withid.respec.mts +266 -0
  183. package/src/sync/sync-innerspace-multiple-timelines.respec.mts +0 -1
  184. package/src/sync/sync-innerspace-multiple-timelines.withid.respec.mts +273 -0
  185. package/src/sync/sync-innerspace-partial-update.withid.respec.mts +249 -0
  186. package/src/sync/sync-innerspace.withid.respec.mts +265 -0
  187. package/src/sync/sync-peer/sync-peer-innerspace/sync-peer-innerspace-v1.mts +1 -1
  188. package/src/sync/sync-peer/sync-peer-types.mts +11 -1
  189. package/src/sync/sync-peer/sync-peer-v1.mts +47 -1
  190. package/src/sync/sync-peer/sync-peer-websocket/README.md +42 -0
  191. package/src/sync/sync-peer/sync-peer-websocket/sync-peer-websocket-receiver/sync-peer-websocket-receiver-v1.mts +26 -9
  192. package/src/sync/sync-peer/sync-peer-websocket/sync-peer-websocket-receiver/sync-websocket-peer-helpers.mts +5 -3
  193. package/src/sync/sync-peer/sync-peer-websocket/sync-peer-websocket-sender/sync-peer-websocket-sender-v1.mts +242 -78
  194. package/src/sync/sync-saga-context/sync-saga-context-helpers.mts +46 -4
  195. package/src/sync/sync-saga-context/sync-saga-context-types.mts +5 -0
  196. package/src/sync/sync-saga-coordinator.mts +221 -137
  197. package/src/sync/sync-withid.pingpong.respec.mts +76 -3
  198. package/src/timeline/timeline-api.mts +1 -15
  199. package/src/timeline/timeline-api.respec.mts +3 -3
  200. package/src/witness/space/reconciliation-space/reconciliation-space-base.mts +0 -46
  201. package/src/witness/space/reconciliation-space/reconciliation-space-helper.mts +6 -5
  202. package/tsconfig.json +6 -1
  203. package/src/keystone/keystone-policy.schema.json +0 -51
  204. package/src/sync/docs/ping_pong_plan.md +0 -147
  205. package/src/witness/space/reconciliation-space/reconciliation-space-base.mts.OLD.md +0 -884
  206. package/src/witness/space/reconciliation-space/reconciliation-space-helper.mts.OLD.md +0 -125
@@ -8,7 +8,7 @@ import { Factory_V1 } from "@ibgib/ts-gib/dist/V1/factory.mjs";
8
8
  import { getGib } from "@ibgib/ts-gib/dist/V1/transforms/transform-helper.mjs";
9
9
 
10
10
  import { GLOBAL_LOG_A_LOT } from "../core-constants.mjs";
11
- import { KEYSTONE_ATOM, KEYSTONE_HASH_MAX_ROUNDS, KEYSTONE_POOL_ID_REGEXP, KEYSTONE_SALT_REGEXP } from "./keystone-constants.mjs";
11
+ import { KEYSTONE_ATOM, KEYSTONE_HASH_MAX_ROUNDS, KEYSTONE_POOL_ID_REGEXP, KEYSTONE_SALT_REGEXP, KEYSTONE_USERNAME_REGEXP, KEYSTONE_DESCRIPTION_REGEXP } from "./keystone-constants.mjs";
12
12
  import {
13
13
  KeystoneData_V1, KeystoneIbGib_V1, KeystoneIb_V1, KeystoneChallengePool,
14
14
  DeterministicResult, KeystoneProof, KeystonePoolConfig,
@@ -95,7 +95,7 @@ export async function parseKeystoneIb({
95
95
  * Calculates exactly which challenges MUST be consumed based on config and demands.
96
96
  * Enforces STRICT DISTINCTNESS (No double-dipping).
97
97
  */
98
- export function getDeterministicRequirements({
98
+ export async function getDeterministicRequirements({
99
99
  pool,
100
100
  requiredChallengeIds,
101
101
  targetAddr
@@ -103,7 +103,7 @@ export function getDeterministicRequirements({
103
103
  pool: KeystoneChallengePool;
104
104
  requiredChallengeIds?: string[];
105
105
  targetAddr?: string;
106
- }): DeterministicResult {
106
+ }): Promise<DeterministicResult> {
107
107
  const behavior = pool.config.behavior;
108
108
  const mandatory = new Set<string>();
109
109
 
@@ -131,31 +131,34 @@ export function getDeterministicRequirements({
131
131
  }
132
132
 
133
133
  // ---------------------------------------------------------
134
- // 2. Target Binding (Explicit Buckets)
134
+ // 2. Target Binding (Drawing Without Replacement)
135
135
  // ---------------------------------------------------------
136
- if (behavior.targetBindingChars > 0 && targetAddr) {
137
- const { gib } = getIbAndGib({ ibGibAddr: targetAddr });
138
- if (gib) {
139
- // Get required hex prefixes (e.g. 'a', 'b', 'c', '1')
140
- const prefixes = gib !== GIB ?
141
- gib.substring(0, behavior.targetBindingChars).toLowerCase() :
142
- 'abc'; // arbitrary for primitive binding target ibgib
143
-
144
- for (const char of prefixes) {
145
- // Look in the Explicit Bucket
146
- const bucket = pool.bindingMap[char] || [];
147
-
148
- // Find the first ID in this bucket that is still in 'available'
149
- const match = bucket.find(id => available.includes(id));
150
-
151
- if (!match) {
152
- throw new Error(`Entropy Exhaustion. Cannot satisfy binding for char '${char}'. (E: 341b95dc3a58be3e083d1d9c4a0c4925)`);
153
- }
136
+ if (behavior.targetBindingCount > 0 && targetAddr) {
137
+ // Sort remaining available IDs alphabetically to ensure stable ordering across platforms
138
+ let sortedAvailable = [...available].sort();
139
+
140
+ // Start hashing path from targetAddr
141
+ let currentHash = await hash({ s: targetAddr });
154
142
 
155
- // Strict: Consume it.
156
- mandatory.add(match);
157
- available = available.filter(id => id !== match);
143
+ for (let i = 0; i < behavior.targetBindingCount; i++) {
144
+ if (sortedAvailable.length === 0) {
145
+ throw new Error(`Entropy Exhaustion. Cannot satisfy target binding. Sorted available pool is empty. (E: 341b95dc3a58be3e083d1d9c4a0c4925)`);
158
146
  }
147
+
148
+ // Parse the entire hash via BigInt to eliminate modulo bias
149
+ const hashBigInt = BigInt("0x" + currentHash);
150
+ const index = Number(hashBigInt % BigInt(sortedAvailable.length));
151
+ const selectedId = sortedAvailable[index];
152
+
153
+ // Consume selected challenge ID
154
+ mandatory.add(selectedId);
155
+ sortedAvailable.splice(index, 1);
156
+
157
+ // Filter out of insertion-ordered available list (for FIFO)
158
+ available = available.filter(id => id !== selectedId);
159
+
160
+ // Hash recursively for the next draw
161
+ currentHash = await hash({ s: currentHash });
159
162
  }
160
163
  }
161
164
 
@@ -179,42 +182,7 @@ export function getDeterministicRequirements({
179
182
  return { mandatoryIds: mandatory, availableIds: available };
180
183
  }
181
184
 
182
- /**
183
- * Helper to update the Binding Map when adding new Challenge IDs.
184
- * Uses "Implicit Bucketing" (ID start char) but can be extended for full coverage.
185
- */
186
- export function addToBindingMap(
187
- map: { [char: string]: string[] },
188
- challengeId: string
189
- ): void {
190
- const firstChar = challengeId.charAt(0).toLowerCase();
191
- // Validate it is hex
192
- if (/[0-9a-f]/.test(firstChar)) {
193
- if (!map[firstChar]) { map[firstChar] = []; }
194
- map[firstChar].push(challengeId);
195
-
196
- // OPTIONAL: Implement Full Coverage Strategy here?
197
- // e.g. map[challengeId[1]].push(challengeId) ...
198
- // For V1, we stick to Native/Implicit bucket (Index 0).
199
- } else {
200
- throw new Error(`invalid challengeId (${challengeId}). Must start with a hex character. (E: c96ed8460de89e28c801370a0f07f826)`);
201
- }
202
- }
203
185
 
204
- /**
205
- * Helper to clean up Binding Map when removing IDs.
206
- */
207
- export function removeFromBindingMap(
208
- map: { [char: string]: string[] },
209
- challengeId: string
210
- ): void {
211
- // Since we don't know exactly which buckets an ID is in (if we did multi-bucket),
212
- // we strictly should scan all. For V1 Native, we check first char.
213
- // SAFE IMPLEMENTATION: Scan all buckets.
214
- for (const key of Object.keys(map)) {
215
- map[key] = map[key].filter(id => id !== challengeId);
216
- }
217
- }
218
186
 
219
187
  /**
220
188
  * Selects the specific pool to use for an operation based on ID, filter criteria, or verb authorization.
@@ -297,7 +265,7 @@ export function resolveTargetPool({
297
265
  *
298
266
  * @returns Array of unique challenge IDs.
299
267
  */
300
- export function selectChallengeIds({
268
+ export async function selectChallengeIds({
301
269
  pool,
302
270
  targetAddr,
303
271
  requiredChallengeIds,
@@ -311,11 +279,11 @@ export function selectChallengeIds({
311
279
  * Explicit demands from a verifier.
312
280
  */
313
281
  requiredChallengeIds?: string[];
314
- }): string[] {
282
+ }): Promise<string[]> {
315
283
  const lc = `[selectChallengeIds]`;
316
284
  try {
317
285
  // 1. Get Deterministic Requirements
318
- const { mandatoryIds, availableIds } = getDeterministicRequirements({
286
+ const { mandatoryIds, availableIds } = await getDeterministicRequirements({
319
287
  pool,
320
288
  requiredChallengeIds,
321
289
  targetAddr
@@ -398,11 +366,6 @@ export async function applyReplenishmentStrategy({
398
366
 
399
367
  const strategyType = config.behavior.replenish;
400
368
 
401
- // Clean up Binding Map for consumed IDs
402
- consumedIds.forEach(id => {
403
- if (pool.bindingMap) { removeFromBindingMap(pool.bindingMap, id); }
404
- });
405
-
406
369
  if (strategyType === KeystoneReplenishStrategy.topUp) {
407
370
  // Remove consumed
408
371
  consumedIds.forEach(id => delete pool.challenges[id]);
@@ -417,14 +380,9 @@ export async function applyReplenishmentStrategy({
417
380
  poolSecret, poolId: pool.id, challengeId: newId
418
381
  });
419
382
  pool.challenges[newId] = await strategy.generateChallenge({ solution });
420
-
421
- // Update Binding Map
422
- if (!pool.bindingMap) { pool.bindingMap = {}; }
423
- addToBindingMap(pool.bindingMap, newId);
424
383
  }
425
384
  } else if (strategyType === KeystoneReplenishStrategy.replaceAll) {
426
385
  pool.challenges = {};
427
- pool.bindingMap = {};
428
386
 
429
387
  for (let i = 0; i < config.behavior.size; i++) {
430
388
  const newId = await generateOpaqueChallengeId({
@@ -434,13 +392,11 @@ export async function applyReplenishmentStrategy({
434
392
  poolSecret, poolId: pool.id, challengeId: newId
435
393
  });
436
394
  pool.challenges[newId] = await strategy.generateChallenge({ solution });
437
- addToBindingMap(pool.bindingMap, newId);
438
395
  }
439
396
  } else if (strategyType === KeystoneReplenishStrategy.consume) {
440
397
  consumedIds.forEach(id => delete pool.challenges[id]);
441
398
  } else if (strategyType === KeystoneReplenishStrategy.deleteAll) {
442
399
  pool.challenges = {};
443
- pool.bindingMap = {};
444
400
  } else {
445
401
  throw new Error(`Unknown replenish strategy: ${strategyType}. Valid list: ${pretty(KEYSTONE_REPLENISH_STRATEGY_VALID_VALUES)} (E: 0acf56f1e1486240080e11e8046d0825)`);
446
402
  }
@@ -599,10 +555,14 @@ export async function validateChallengePool({ pool }: {
599
555
  }
600
556
 
601
557
  if (pool.config.behavior) {
602
- const { size } = pool.config.behavior;
558
+ const { size, selectSequentially, selectRandomly, targetBindingCount } = pool.config.behavior;
603
559
  if (!size || size === 0) {
604
560
  errors.push(`${lc} invalid pool.config.behavior.size (${size}). Must be positive integer. (E: b221e36ec102bdc944552248ce8fe626)`)
605
561
  }
562
+ const totalRequested = (selectSequentially || 0) + (selectRandomly || 0) + (targetBindingCount || 0);
563
+ if (totalRequested >= size) {
564
+ errors.push(`${lc} Total requested challenges (${totalRequested}) cannot equal or exceed pool size (${size}) to prevent full pool exposure and selection exhaustion. (E: 81cb834f826315264bca81c15fca58f1)`);
565
+ }
606
566
  // todo: more behavior checks
607
567
  } else {
608
568
  errors.push(`${lc} pool.config.behavior falsy (E: bede081c066c39732eefe2f92e296326)`)
@@ -632,6 +592,35 @@ export async function validateChallengePool({ pool }: {
632
592
  }
633
593
 
634
594
 
595
+ export function validateKeystoneMetadata({
596
+ data
597
+ }: {
598
+ data: KeystoneData_V1;
599
+ }): string[] {
600
+ const lc = `[validateKeystoneMetadata]`;
601
+ const errors: string[] = [];
602
+
603
+ const checkDetails = (details: any, source: string) => {
604
+ if (!details) return;
605
+ if (details.username !== undefined) {
606
+ if (typeof details.username !== 'string' || !KEYSTONE_USERNAME_REGEXP.test(details.username)) {
607
+ errors.push(`${lc} invalid username in ${source} (${details.username}). Must match ${KEYSTONE_USERNAME_REGEXP}`);
608
+ }
609
+ }
610
+ if (details.description !== undefined) {
611
+ if (typeof details.description !== 'string' || !KEYSTONE_DESCRIPTION_REGEXP.test(details.description)) {
612
+ errors.push(`${lc} invalid description in ${source} (${details.description}). Must match ${KEYSTONE_DESCRIPTION_REGEXP}`);
613
+ }
614
+ }
615
+ };
616
+
617
+ checkDetails(data.frameDetails, 'frameDetails');
618
+ checkDetails(data.checkpointDetails, 'checkpointDetails');
619
+
620
+ return errors;
621
+ }
622
+
623
+
635
624
  export async function validateGenesisKeystone({
636
625
  keystoneIbGib
637
626
  }: {
@@ -645,6 +634,10 @@ export async function validateGenesisKeystone({
645
634
 
646
635
  const { data, rel8ns } = keystoneIbGib;
647
636
 
637
+ // Validate username/description metadata if present
638
+ const metadataErrors = validateKeystoneMetadata({ data });
639
+ metadataErrors.forEach(x => errors.push(x));
640
+
648
641
  // no proofs/solutions yet
649
642
  if (data.proofs && data.proofs.length > 0) {
650
643
  errors.push(`${lc} proofs already exist on genesis keystone. (E: 7a5e15f20918f1bbd8ffb62857dcd526)`);
@@ -707,6 +700,10 @@ export async function validateKeystoneTransition({
707
700
  const currData = currentIbGib.data!;
708
701
  const prevData = prevIbGib.data!;
709
702
 
703
+ // Validate username/description metadata if present
704
+ const metadataErrors = validateKeystoneMetadata({ data: currData });
705
+ metadataErrors.forEach(x => errors.push(x));
706
+
710
707
  // must be sequential data.n values
711
708
  // note: "-2" because we don't want a "valid" sequential data.n if we
712
709
  // have an invalid prev and a valid currDataN of 0
@@ -784,7 +781,7 @@ export async function verifyProofAgainstPool({
784
781
  }
785
782
 
786
783
  // 1. Reconstruct Deterministic Requirements
787
- const { mandatoryIds, availableIds } = getDeterministicRequirements({
784
+ const { mandatoryIds, availableIds } = await getDeterministicRequirements({
788
785
  pool,
789
786
  requiredChallengeIds: proof.requiredChallengeIds,
790
787
  targetAddr: proof.claim.target // Not used extensively in V1 logic yet, mainly for logging/context
@@ -6,20 +6,22 @@ export interface KeystoneBehaviorProfileTemplate {
6
6
  replenish: KeystoneReplenishStrategy;
7
7
  selectSequentially: number;
8
8
  selectRandomly: number;
9
- targetBindingChars: number;
9
+ targetBindingCount: number;
10
10
  }
11
11
 
12
12
  export interface KeystonePoolTemplate {
13
13
  id: string;
14
14
  allowedVerbs: string[];
15
- behaviorProfile?: string; // Reference to a behavior profile key
16
- behaviorInline?: KeystoneBehaviorProfileTemplate; // Or specify behavior inline
15
+ behavior: KeystoneBehaviorProfileTemplate;
17
16
  algo: HashAlgorithm;
18
17
  rounds: number;
19
18
  type?: KeystoneChallengeType;
20
19
  }
21
20
 
22
21
  export interface KeystonePolicyConfigTemplate {
23
- behaviorProfiles?: Record<string, KeystoneBehaviorProfileTemplate>;
22
+ metadata?: {
23
+ name?: string;
24
+ securityLevel?: string;
25
+ };
24
26
  pools: Record<string, KeystonePoolTemplate>;
25
27
  }
@@ -9,7 +9,7 @@ import {
9
9
  import { KeystoneStrategyFactory } from './strategy/keystone-strategy-factory.mjs';
10
10
  import { POOL_ID_REVOKE, KEYSTONE_VERB_REVOKE, KEYSTONE_VERB_MANAGE, KEYSTONE_CHECKPOINT_FREQUENCY } from './keystone-constants.mjs';
11
11
  import {
12
- addToBindingMap, createKeystoneIbGibImpl, evolvePersistAndRegisterKeystone,
12
+ createKeystoneIbGibImpl, evolvePersistAndRegisterKeystone,
13
13
  generateOpaqueChallengeId, resolveTargetPool, selectChallengeIds,
14
14
  solveAndReplenish, validateKeystoneTransition,
15
15
  validateGenesisKeystone, validateKeystoneGraph
@@ -54,7 +54,6 @@ export class KeystoneService_V1 {
54
54
  const strategy = KeystoneStrategyFactory.create({ config });
55
55
  const poolSecret = await strategy.derivePoolSecret({ masterSecret });
56
56
  const challenges: { [id: string]: any } = {};
57
- const bindingMap: { [char: string]: string[] } = {};
58
57
 
59
58
  const targetSize = config.behavior.size;
60
59
  const timestamp = Date.now().toString();
@@ -69,16 +68,12 @@ export class KeystoneService_V1 {
69
68
  });
70
69
  const challenge = await strategy.generateChallenge({ solution });
71
70
  challenges[challengeId] = challenge;
72
-
73
- // Populate Binding Map
74
- addToBindingMap(bindingMap, challengeId);
75
71
  }
76
72
 
77
73
  challengePools.push({
78
74
  id: config.id,
79
75
  config,
80
76
  challenges,
81
- bindingMap
82
77
  });
83
78
  }
84
79
 
@@ -158,7 +153,7 @@ export class KeystoneService_V1 {
158
153
  if (logalot) { console.log(`${lc} Selected pool: ${pool.id} (size: ${Object.keys(pool.challenges).length}) (I: 6b26d6f4aad18380f2b3a0989b592826)`); }
159
154
 
160
155
  // 2. Calculate Costs (Select IDs)
161
- const idsToSolve = selectChallengeIds({
156
+ const idsToSolve = await selectChallengeIds({
162
157
  pool,
163
158
  targetAddr: claim.target,
164
159
  requiredChallengeIds
@@ -384,7 +379,7 @@ export class KeystoneService_V1 {
384
379
  };
385
380
 
386
381
  // 3. Calculate Costs
387
- const idsToSolve = selectChallengeIds({
382
+ const idsToSolve = await selectChallengeIds({
388
383
  pool,
389
384
  targetAddr: claim.target,
390
385
  requiredChallengeIds: []
@@ -515,7 +510,7 @@ export class KeystoneService_V1 {
515
510
  };
516
511
 
517
512
  // 3. Calculate Costs
518
- const idsToSolve = selectChallengeIds({
513
+ const idsToSolve = await selectChallengeIds({
519
514
  pool: adminPool,
520
515
  targetAddr: target
521
516
  });