@ibgib/core-gib 0.1.47 → 0.1.49

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 (136) hide show
  1. package/dist/common/other/ibgib-helper.d.mts +12 -0
  2. package/dist/common/other/ibgib-helper.d.mts.map +1 -1
  3. package/dist/common/other/ibgib-helper.mjs +39 -0
  4. package/dist/common/other/ibgib-helper.mjs.map +1 -1
  5. package/dist/keystone/kdf/kdf-helpers.mjs +2 -2
  6. package/dist/keystone/kdf/kdf-helpers.mjs.map +1 -1
  7. package/dist/keystone/keystone-config-builder.d.mts +2 -1
  8. package/dist/keystone/keystone-config-builder.d.mts.map +1 -1
  9. package/dist/keystone/keystone-config-builder.mjs +8 -2
  10. package/dist/keystone/keystone-config-builder.mjs.map +1 -1
  11. package/dist/keystone/keystone-constants.d.mts +24 -3
  12. package/dist/keystone/keystone-constants.d.mts.map +1 -1
  13. package/dist/keystone/keystone-constants.mjs +22 -1
  14. package/dist/keystone/keystone-constants.mjs.map +1 -1
  15. package/dist/keystone/keystone-helpers.d.mts.map +1 -1
  16. package/dist/keystone/keystone-helpers.mjs +7 -9
  17. package/dist/keystone/keystone-helpers.mjs.map +1 -1
  18. package/dist/keystone/keystone-service-v1.d.mts +4 -1
  19. package/dist/keystone/keystone-service-v1.d.mts.map +1 -1
  20. package/dist/keystone/keystone-service-v1.mjs +6 -1
  21. package/dist/keystone/keystone-service-v1.mjs.map +1 -1
  22. package/dist/keystone/keystone-service-v1.respec.mjs +26 -26
  23. package/dist/keystone/keystone-service-v1.respec.mjs.map +1 -1
  24. package/dist/keystone/keystone-types.d.mts +24 -5
  25. package/dist/keystone/keystone-types.d.mts.map +1 -1
  26. package/dist/keystone/keystone-types.mjs.map +1 -1
  27. package/dist/sync/sync-conflict-adv-multitimelines.respec.mjs +2 -2
  28. package/dist/sync/sync-conflict-adv-multitimelines.respec.mjs.map +1 -1
  29. package/dist/sync/sync-conflict-basic-divergence.respec.mjs +2 -2
  30. package/dist/sync/sync-conflict-basic-divergence.respec.mjs.map +1 -1
  31. package/dist/sync/sync-conflict-basic-multitimelines.respec.mjs +2 -2
  32. package/dist/sync/sync-conflict-basic-multitimelines.respec.mjs.map +1 -1
  33. package/dist/sync/sync-conflict-text-merge.respec.mjs +2 -2
  34. package/dist/sync/sync-conflict-text-merge.respec.mjs.map +1 -1
  35. package/dist/sync/sync-constants.d.mts +47 -1
  36. package/dist/sync/sync-constants.d.mts.map +1 -1
  37. package/dist/sync/sync-constants.mjs +49 -1
  38. package/dist/sync/sync-constants.mjs.map +1 -1
  39. package/dist/sync/sync-innerspace-constants.respec.mjs +2 -2
  40. package/dist/sync/sync-innerspace-constants.respec.mjs.map +1 -1
  41. package/dist/sync/sync-innerspace-deep-updates.respec.mjs +2 -2
  42. package/dist/sync/sync-innerspace-deep-updates.respec.mjs.map +1 -1
  43. package/dist/sync/sync-innerspace-dest-ahead-withid.respec.mjs +22 -8
  44. package/dist/sync/sync-innerspace-dest-ahead-withid.respec.mjs.map +1 -1
  45. package/dist/sync/sync-innerspace-dest-ahead.respec.mjs +2 -2
  46. package/dist/sync/sync-innerspace-dest-ahead.respec.mjs.map +1 -1
  47. package/dist/sync/sync-innerspace-multiple-timelines.respec.mjs +2 -2
  48. package/dist/sync/sync-innerspace-multiple-timelines.respec.mjs.map +1 -1
  49. package/dist/sync/sync-innerspace-partial-update.respec.mjs +2 -2
  50. package/dist/sync/sync-innerspace-partial-update.respec.mjs.map +1 -1
  51. package/dist/sync/sync-innerspace.respec.mjs +2 -2
  52. package/dist/sync/sync-innerspace.respec.mjs.map +1 -1
  53. package/dist/sync/sync-peer/sync-peer-http-receiver/sync-http-node-adapter.d.mts +57 -0
  54. package/dist/sync/sync-peer/sync-peer-http-receiver/sync-http-node-adapter.d.mts.map +1 -0
  55. package/dist/sync/sync-peer/sync-peer-http-receiver/sync-http-node-adapter.mjs +310 -0
  56. package/dist/sync/sync-peer/sync-peer-http-receiver/sync-http-node-adapter.mjs.map +1 -0
  57. package/dist/sync/sync-peer/sync-peer-http-receiver/sync-peer-http-receiver-types.d.mts +27 -0
  58. package/dist/sync/sync-peer/sync-peer-http-receiver/sync-peer-http-receiver-types.d.mts.map +1 -0
  59. package/dist/sync/sync-peer/sync-peer-http-receiver/sync-peer-http-receiver-types.mjs +2 -0
  60. package/dist/sync/sync-peer/sync-peer-http-receiver/sync-peer-http-receiver-types.mjs.map +1 -0
  61. package/dist/sync/sync-peer/sync-peer-http-receiver/sync-peer-http-receiver-v1.d.mts +29 -0
  62. package/dist/sync/sync-peer/sync-peer-http-receiver/sync-peer-http-receiver-v1.d.mts.map +1 -0
  63. package/dist/sync/sync-peer/sync-peer-http-receiver/sync-peer-http-receiver-v1.mjs +122 -0
  64. package/dist/sync/sync-peer/sync-peer-http-receiver/sync-peer-http-receiver-v1.mjs.map +1 -0
  65. package/dist/sync/sync-peer/sync-peer-http-sender/sync-peer-http-sender-types.d.mts +27 -0
  66. package/dist/sync/sync-peer/sync-peer-http-sender/sync-peer-http-sender-types.d.mts.map +1 -0
  67. package/dist/sync/sync-peer/sync-peer-http-sender/sync-peer-http-sender-types.mjs +2 -0
  68. package/dist/sync/sync-peer/sync-peer-http-sender/sync-peer-http-sender-types.mjs.map +1 -0
  69. package/dist/sync/sync-peer/sync-peer-http-sender/sync-peer-http-sender-v1.d.mts +24 -0
  70. package/dist/sync/sync-peer/sync-peer-http-sender/sync-peer-http-sender-v1.d.mts.map +1 -0
  71. package/dist/sync/sync-peer/sync-peer-http-sender/sync-peer-http-sender-v1.mjs +111 -0
  72. package/dist/sync/sync-peer/sync-peer-http-sender/sync-peer-http-sender-v1.mjs.map +1 -0
  73. package/dist/sync/sync-peer/sync-peer-http.respec.d.mts +8 -0
  74. package/dist/sync/sync-peer/sync-peer-http.respec.d.mts.map +1 -0
  75. package/dist/sync/sync-peer/sync-peer-http.respec.mjs +333 -0
  76. package/dist/sync/sync-peer/sync-peer-http.respec.mjs.map +1 -0
  77. package/dist/sync/sync-peer/sync-peer-innerspace/sync-peer-innerspace-v1.d.mts.map +1 -1
  78. package/dist/sync/sync-peer/sync-peer-innerspace/sync-peer-innerspace-v1.mjs +13 -7
  79. package/dist/sync/sync-peer/sync-peer-innerspace/sync-peer-innerspace-v1.mjs.map +1 -1
  80. package/dist/sync/sync-peer/sync-peer-types.d.mts +5 -5
  81. package/dist/sync/sync-peer/sync-peer-types.d.mts.map +1 -1
  82. package/dist/sync/sync-peer/sync-peer-v1.d.mts +6 -3
  83. package/dist/sync/sync-peer/sync-peer-v1.d.mts.map +1 -1
  84. package/dist/sync/sync-peer/sync-peer-v1.mjs +75 -26
  85. package/dist/sync/sync-peer/sync-peer-v1.mjs.map +1 -1
  86. package/dist/sync/sync-saga-context/sync-saga-context-helpers.d.mts +7 -3
  87. package/dist/sync/sync-saga-context/sync-saga-context-helpers.d.mts.map +1 -1
  88. package/dist/sync/sync-saga-context/sync-saga-context-helpers.mjs +32 -3
  89. package/dist/sync/sync-saga-context/sync-saga-context-helpers.mjs.map +1 -1
  90. package/dist/sync/sync-saga-context/sync-saga-context-types.d.mts +16 -0
  91. package/dist/sync/sync-saga-context/sync-saga-context-types.d.mts.map +1 -1
  92. package/dist/sync/sync-saga-coordinator.d.mts +18 -3
  93. package/dist/sync/sync-saga-coordinator.d.mts.map +1 -1
  94. package/dist/sync/sync-saga-coordinator.mjs +241 -56
  95. package/dist/sync/sync-saga-coordinator.mjs.map +1 -1
  96. package/dist/sync/sync-types.d.mts +1 -1
  97. package/dist/sync/sync-types.d.mts.map +1 -1
  98. package/ibgib-foundations.md +109 -89
  99. package/package.json +1 -1
  100. package/src/common/other/ibgib-helper.mts +39 -0
  101. package/src/keystone/kdf/kdf-helpers.mts +2 -2
  102. package/src/keystone/keystone-config-builder.mts +13 -2
  103. package/src/keystone/keystone-constants.mts +24 -2
  104. package/src/keystone/keystone-helpers.mts +5 -10
  105. package/src/keystone/keystone-service-v1.mts +5 -0
  106. package/src/keystone/keystone-service-v1.respec.mts +25 -25
  107. package/src/keystone/keystone-types.mts +27 -7
  108. package/src/sync/sync-conflict-adv-multitimelines.respec.mts +2 -2
  109. package/src/sync/sync-conflict-basic-divergence.respec.mts +2 -2
  110. package/src/sync/sync-conflict-basic-multitimelines.respec.mts +2 -2
  111. package/src/sync/sync-conflict-text-merge.respec.mts +2 -2
  112. package/src/sync/sync-constants.mts +51 -1
  113. package/src/sync/sync-innerspace-constants.respec.mts +2 -2
  114. package/src/sync/sync-innerspace-deep-updates.respec.mts +2 -2
  115. package/src/sync/sync-innerspace-dest-ahead-withid.respec.mts +26 -9
  116. package/src/sync/sync-innerspace-dest-ahead.respec.mts +2 -2
  117. package/src/sync/sync-innerspace-multiple-timelines.respec.mts +2 -2
  118. package/src/sync/sync-innerspace-partial-update.respec.mts +2 -2
  119. package/src/sync/sync-innerspace.respec.mts +2 -2
  120. package/src/sync/sync-peer/sync-peer-http-receiver/sync-http-node-adapter.mts +319 -0
  121. package/src/sync/sync-peer/sync-peer-http-receiver/sync-http-node-adapter.mts.metadata.md +72 -0
  122. package/src/sync/sync-peer/sync-peer-http-receiver/sync-peer-http-receiver-types.mts +30 -0
  123. package/src/sync/sync-peer/sync-peer-http-receiver/sync-peer-http-receiver-v1.mts +146 -0
  124. package/src/sync/sync-peer/sync-peer-http-receiver/sync-peer-http-receiver-v1.mts.metadata.md +71 -0
  125. package/src/sync/sync-peer/sync-peer-http-sender/sync-peer-http-sender-types.mts +32 -0
  126. package/src/sync/sync-peer/sync-peer-http-sender/sync-peer-http-sender-v1.mts +129 -0
  127. package/src/sync/sync-peer/sync-peer-http.respec.mts +364 -0
  128. package/src/sync/sync-peer/sync-peer-innerspace/sync-peer-innerspace-types.mts +8 -8
  129. package/src/sync/sync-peer/sync-peer-innerspace/sync-peer-innerspace-v1.mts +15 -7
  130. package/src/sync/sync-peer/sync-peer-types.mts +11 -11
  131. package/src/sync/sync-peer/sync-peer-v1.mts +66 -30
  132. package/src/sync/sync-saga-context/sync-saga-context-helpers.mts +52 -4
  133. package/src/sync/sync-saga-context/sync-saga-context-types.mts +17 -0
  134. package/src/sync/sync-saga-coordinator.mts +296 -63
  135. package/src/sync/sync-types.mts +1 -1
  136. package/tmp-certs/server.pfx +0 -0
@@ -6,102 +6,120 @@ This document serves as an onboarding guide and technical reference for the **ib
6
6
 
7
7
  At its lowest level, anything in the system is an **ibGib**.
8
8
 
9
- * **ib**: The "Metadata". Often a string like "comment", "pic", or "link". It can be descriptive or functional (e.g., class names).
10
- * **gib**: The "Hash". A cryptographic hash (SHA-256 in V1) of the entire ibGib record.
11
- * **ib^gib**: The content address. Uniquely identifies a record in the universe.
9
+ * **ib**: The "Metadata". Often a string like "comment", "pic", or "link". It can be descriptive or functional (e.g., class names).
10
+ * **gib**: The "Hash". A cryptographic hash (SHA-256 in V1) of the entire ibGib record.
11
+ * **ib^gib**: The content address. Uniquely identifies a record in the universe.
12
12
 
13
13
  ### `gib` Nuances: Punctiliar vs. TJP
14
14
  The `gib` is more than a single hash; it encodes timeline context.
15
- * **Punctiliar Hash**: The hash of *just* the current frame's content. Every ibgib has this.
16
- * **TJP Gib (Timeline ID)**: The `gib` of the **Temporal Junction Point (TJP)**—the very first frame (Genesis/Fork) of the timeline.
17
- * **Composite Address**: Use `ib^[punctiliar_hash].[tjp_gib]`.
18
- * Example: `comment^<CURRENT_HASH>.<GENESIS_HASH>`
19
- * This allows us to identify *which* timeline a frame belongs to simply by looking at its address.
20
- * The `tjp` frame itself has a single hash (since its punctiliar hash IS the tjp gib).
15
+ * **Punctiliar Hash**: The hash of *just* the current frame's content. Every ibgib has this.
16
+ * **TJP Gib (Timeline ID)**: The `gib` of the **Temporal Junction Point (TJP)**—the very first frame (Genesis/Fork) of the timeline.
17
+ * **Composite Address**: Use `ib^[punctiliar_hash].[tjp_gib]`.
18
+ * Example: `comment^<CURRENT_HASH>.<GENESIS_HASH>`
19
+ * This allows us to identify *which* timeline a frame belongs to simply by looking at its address.
20
+ * The `tjp` frame itself has a single hash (since its punctiliar hash IS the tjp gib).
21
21
 
22
22
  ### Structure
23
23
  An `IbGib_V1` object has two primary payload containers:
24
- 1. **data**: Intrinsic, immutable properties. (e.g., text content, configuration flags).
25
- 2. **rel8ns**: Extrinsic, Directed Acyclic Graph (DAG) links to other ibGibs.
26
- * Named edges (e.g., `past`, `ancestor`, `pic`).
27
- * Always stored as an array of addresses (`IbGibAddr[]`).
24
+ 1. **data**: Intrinsic, immutable properties. (e.g., text content, configuration flags).
25
+ 2. **rel8ns**: Extrinsic, Directed Acyclic Graph (DAG) links to other ibGibs.
26
+ * Named edges (e.g., `past`, `ancestor`, `pic`).
27
+ * Always stored as an array of addresses (`IbGibAddr[]`).
28
28
 
29
29
  ### Transforms (The "Verbs")
30
30
  State is never mutated in place; it is evolved via transforms.
31
- * **[fork](file:../libs/ts-gib/src/V1/transforms/fork.mts)**: Creates a new timeline.
32
- * **Crucial**: Appends to `ancestor` but **CLEARS** the `past` rel8n. This is what births a new timeline.
33
- * **[mut8](file:../libs/ts-gib/src/V1/transforms/mut8.mts)** (Mutate): Evolves intrinsic data.
34
- * **Accretive**: By default, it *appends* the new address to the `past` array. It does **not** create a linked list unless `linkedRel8ns` is explicitly used.
35
- * Access the immediate past via `ibgib.rel8ns.past.at(-1)`.
36
- * **[rel8](file:../libs/ts-gib/src/V1/transforms/rel8.mts)** (Relate): Evolves extrinsic relationships.
37
- * Also accretive by default.
31
+ * **[fork](file:../libs/ts-gib/src/V1/transforms/fork.mts)**: Creates a new timeline.
32
+ * **Crucial**: Appends to `ancestor` but **CLEARS** the `past` rel8n. This is what births a new timeline.
33
+ * **[mut8](file:../libs/ts-gib/src/V1/transforms/mut8.mts)** (Mutate): Evolves intrinsic data.
34
+ * **Accretive**: By default, it *appends* the new address to the `past` array. It does **not** create a linked list unless `linkedRel8ns` is explicitly used.
35
+ * Access the immediate past via `ibgib.rel8ns.past.at(-1)`.
36
+ * **[rel8](file:../libs/ts-gib/src/V1/transforms/rel8.mts)** (Relate): Evolves extrinsic relationships.
37
+ * Also accretive by default.
38
38
 
39
39
  ### DNA (The "How")
40
40
  The **`dna`** rel8n is a critical component for distributed consistency.
41
- * **Memoization**: It stores the *arguments* used to create a transform (e.g., the specific `dataToAddOrPatch` in a `mut8`).
42
- * **In-Structure History**: These arguments are embedded directly in the ibGib structure via the `dna` rel8n.
43
- * **Merge Strategy**: When resolving divergent timelines, we don't just compare the final state. We examine the `dna` to understand the *intent* of the divergence.
44
- * *Example*: Two users edit a comment. One fixes a typo, one adds a sentence. By examining the `dna` (the `mut8` args), we can construct a new transform that applies both changes, rather than one overwriting the other.
41
+ * **Memoization**: It stores the *arguments* used to create a transform (e.g., the specific `dataToAddOrPatch` in a `mut8`).
42
+ * **In-Structure History**: These arguments are embedded directly in the ibGib structure via the `dna` rel8n.
43
+ * **Merge Strategy**: When resolving divergent timelines, we don't just compare the final state. We examine the `dna` to understand the *intent* of the divergence.
44
+ * *Example*: Two users edit a comment. One fixes a typo, one adds a sentence. By examining the `dna` (the `mut8` args), we can construct a new transform that applies both changes, rather than one overwriting the other.
45
45
 
46
46
 
47
47
  ## 2. Higher-Level Architecture (`core-gib`)
48
48
 
49
49
  ### Witness Pattern
50
50
  The **[Witness](file:src/witness/witness-types.mts)** is the core functional paradigm.
51
- * **Concept**: An ibGib that "observes" (witnesses) another ibGib and produces a result.
52
- * **Benefits**:
53
- * **Memoization**: Enables memoizing inputs, outputs, and parameters of the witness class itself.
54
- * **Aspect-Oriented Composeability**: Provides a single interaction point for easy composition of behaviors (logging, security, permissions).
55
- * **Interface**: `witness(arg: IbGib) -> Promise<IbGib>`
51
+ * **Concept**: An ibGib that "observes" (witnesses) another ibGib and produces a result.
52
+ * **Benefits**:
53
+ * **Memoization**: Enables memoizing inputs, outputs, and parameters of the witness class itself.
54
+ * **Aspect-Oriented Composeability**: Provides a single interaction point for easy composition of behaviors (logging, security, permissions).
55
+ * **Interface**: `witness(arg: IbGib) -> Promise<IbGib>`
56
56
 
57
57
  ### Space Paradigm & Metaspace
58
58
  **[Space](file:src/witness/space/space-types.mts)** is a specialized Witness responsible for storage and retrieval.
59
- * **Commands**: `put`, `get`, `delete`.
60
- * **Locations**: `local`, `sync`, `innerspace` (memory-only/test).
59
+ * **Commands**: `put`, `get`, `delete`.
60
+ * **Locations**: `local`, `sync`, `innerspace` (memory-only/test).
61
61
 
62
62
  **[Metaspace](file:src/witness/space/metaspace/metaspace-types.mts)**
63
- * **Role**: Currently acts as a **Singleton Facade** for the runtime context.
64
- * Does NOT yet actively route "get from any space" requests (though planned).
65
- * Initializes default local spaces.
66
- * **Persistence vs. Indexing**:
67
- * `metaspace.put`: Persists the ibGib to the underlying space(s).
68
- * `metaspace.registerNewIbGib`: Updates the *index* (e.g., "Latest" pointers for timelines) and broadcasts the event via PubSub.
69
- * *Usage*: Always `put` first, then `register` if it's a new timeline tip.
63
+ * **Role**: Currently acts as a **Singleton Facade** for the runtime context.
64
+ * Does NOT yet actively route "get from any space" requests (though planned).
65
+ * Initializes default local spaces.
66
+ * **Persistence vs. Indexing**:
67
+ * `metaspace.put`: Persists the ibGib to the underlying space(s) via `putInSpace`.
68
+ * `metaspace.registerNewIbGib`: Updates the *index* (e.g., "Latest" pointers for timelines) and broadcasts the event via `registerNewIbGib` with the pre-configured `fnBroadcast` when metaspace is initialized.
69
+ * *Usage*: put first, then register (skipping register only in rare cases).
70
70
 
71
71
  ### Timeline Facade (`timeline-api`)
72
72
  **[Timeline API](file:src/timeline/timeline-api.mts)** acts as a consumer-friendly facade over the raw Witness/Transform calls.
73
- * **Purpose**: Simplifies common operations like "Update this timeline with new data" (`mut8Timeline`).
74
- * **Abstraction**: Hides the complexity of TJP lookup, generic transforms, and graph traversal.
75
-
76
- ### respec-gib Test Framework
77
-
78
- `respec-gib` is a custom, vastly simplified testing framework. Key points:
79
-
80
- - **No CLI arguments**: The test runner does NOT parse command-line arguments like `--testPathPattern` or other Jest-style flags.
81
- - **Focusing tests**: The ONLY way to focus/filter tests is via `ifWeMight(` regex pattern matching in the test runner script.
82
- - Commands: Use `npm run test:agent` to run all tests, or modify the `ifWeMight` regex in `src/respec-gib.node.mts` to focus specific test files. (`respec-gib`)
83
- **[respec-gib](file:src/respec-gib.node.mts)** is the custom BDD-style testing framework.
84
- * **Structure**:
85
- * `respecfully`: Top-level organizational block (must `await`).
86
- * `ifWe`: Leaf-node test block (must `await`).
87
- * `iReckon`: Assertions (synchronous, inside `ifWe`).
88
- * *Note*: The test runner crudely regex-searches for `"ifWeMight("`.
73
+ * **Purpose**: Simplifies common operations like "Update this timeline with new data" (`mut8Timeline`).
74
+ * **Abstraction**: Hides the complexity of TJP lookup, generic transforms, and graph traversal.
75
+
76
+ ### *respec-gib* Test Framework
77
+
78
+ Since `ibgib` has unique execution environment requirements and a high need for custom asynchronous block handling, it uses a custom testing framework located in `@ibgib/helper-gib/dist/respec-gib`. Each lib/app has its own test runner script located in [lib/app]/src/respec-gib.node.mts, e.g., libs/helper-gib/src/respec-gib.node.mts or libs/core-gib/src/respec-gib.node.mts.
79
+
80
+ Key features include:
81
+ * **`respecfully`**: The equivalent of `describe` or an outer test suite block.
82
+ * async call, MUST USE await
83
+ * organizational block
84
+ * YES can be nested
85
+ * **`ifWe`**: The equivalent of `it`, used for defining a specific test case block.
86
+ * async call, MUST USE await
87
+ * can NOT be nested
88
+ * **`ifWeMight`**: A focused test case (equivalent to `fit` or `it.only`). Using this will restrict execution to only the `ifWeMight` block(s) and skip all others.
89
+ * async call, MUST USE await
90
+ * can NOT be nested
91
+ * **`iReckon`**: The assertion fluent API (equivalent to `expect`).
92
+ * sync call, do NOT await
93
+ * Only specific assertion methods are available compared to other bigger (and funded/helped) testing frameworks:
94
+ * *Assertions*:
95
+ * `willEqual(expected)` - Tests deep equality or reference equality.
96
+ * `isGonnaBe(expected)` - Tests equality.
97
+ * `isGonnaBeTruthy()` / `isGonnaBeFalsy()` - Tests truthiness.
98
+ * `isGonnaBeTrue()` / `isGonnaBeFalse()` - Strict equality to true/false.
99
+ * `isGonnaBeUndefined()` - Strict equality to undefined.
100
+ * `includes(expected)` - Tests array or substring inclusion.
101
+ * *Modifiers*:
102
+ * **`.not`**: Can precede any assertion (e.g., `iReckon(sir, x).not.isGonnaBe(true)`).
103
+ * **`.asTo(label)`**: Used to add context to the error message (e.g., `iReckon(sir, x).asTo("Checking user ID").willEqual(5)`).
104
+ * Setup and Teardown methods run dynamically per suite context:
105
+ * `firstOfAll` / `lastOfAll` - Runs once per outer suite.
106
+ * `firstOfEach` / `lastOfEach` - Runs before/after each inner child (`respecfully` or `ifWe/Might`), or modify the `ifWeMight` regex in `src/respec-gib.node.mts` to focus specific test files.
89
107
 
90
108
  ### Timelines & Temporal Junction Points (TJPs)
91
- * **Accretion vs. Linked List**: Timelines are typically **accretive**. We carry the full history of addresses in the `past` array (`past: [h1, h2, h3...]`).
92
- * *Tradeoff*: Increases metadata size but avoids O(N) network fetches required to traverse a linked list history.
93
- * *Optimization*: Future storage engines will compress this redundancy.
94
- * **TJP**: The stable identifier. In code, the TJP's `gib` is often used as the **Lock Scope** to serialize transforms on that timeline.
109
+ * **Accretion vs. Linked List**: Timelines are typically **accretive**. We carry the full history of addresses in the `past` array (`past: [h1, h2, h3...]`).
110
+ * *Tradeoff*: Increases metadata size but avoids O(N) network fetches required to traverse a linked list history.
111
+ * *Optimization*: Future storage engines will compress this redundancy.
112
+ * **TJP**: The stable identifier. In code, the TJP's `gib` is often used as the **Lock Scope** to serialize transforms on that timeline.
95
113
 
96
114
  ### IMPORTANT: Ancestor vs. Previous Frame
97
115
  It is critical to distinguish between these two relationships:
98
- * **Previous Frame (`past`)**: Points to the immediate predecessor in the *same* timeline. This is the "parent" in the Git commit sense.
99
- * *Usage*: `mut8`, `rel8`.
100
- * *Meaning*: "I am the next step in this timeline."
101
- * **Ancestor (`ancestor`)**: Points to the source from which a *new* timeline was spawned.
102
- * *Usage*: **ONLY** `fork`.
103
- * *Meaning*: "I am the beginning of a *new* timeline that came from that timeline."
104
- * *Constraint*: A `fork` transform clears the `past` array and adds the source to `ancestor`.
116
+ * **Previous Frame (`past`)**: Points to the immediate predecessor in the *same* timeline. This is the "parent" in the Git commit sense.
117
+ * *Usage*: `mut8`, `rel8`.
118
+ * *Meaning*: "I am the next step in this timeline."
119
+ * **Ancestor (`ancestor`)**: Points to the source from which a *new* timeline was spawned.
120
+ * *Usage*: **ONLY** `fork`.
121
+ * *Meaning*: "I am the beginning of a *new* timeline that came from that timeline."
122
+ * *Constraint*: A `fork` transform clears the `past` array and adds the source to `ancestor`.
105
123
 
106
124
  > [!IMPORTANT]
107
125
  > Never use "ancestor" to refer to the previous frame in a timeline history. That is the "past". Ancestor implies a fork.
@@ -112,36 +130,38 @@ The Sync Protocol is a **Symmetric, Peer-to-Peer** protocol modeled as a "Saga".
112
130
  See: **[Sync README](file:src/sync/README.md)**
113
131
 
114
132
  ### Core Components
115
- * **[SyncSagaIbGib](file:src/sync/sync-types.mts)**: The timeline tracking the sync session itself. Acts as an audit trail.
116
- * **[SyncSagaCoordinator](file:src/sync/sync-saga-coordinator.mts)**: The State Machine driver. Code is identical on both "Alice" (Source) and "Bob" (Destination) nodes.
117
- * **Message Stones**: Immutable data packets passed between peers (Init, Ack, Delta, Commit).
133
+ * **[SyncSagaIbGib](file:src/sync/sync-types.mts)**: The timeline tracking the sync session itself. Acts as an audit trail.
134
+ * **[SyncSagaCoordinator](file:src/sync/sync-saga-coordinator.mts)**: The State Machine driver. Code is identical on both "Alice" (Source) and "Bob" (Destination) nodes.
135
+ * **Message Stones**: Immutable data packets passed between peers (Init, Ack, Delta, Commit).
118
136
 
119
137
  ### Protocol Flow
120
- 1. **Init**: Sender generates a **Knowledge Vector** (KV) summary.
121
- 2. **Gap Analysis**: Receiver compares KVs.
122
- * Sender behind -> **Push Offer**.
123
- * Sender ahead -> **Delta Request**.
124
- * Diverged -> **Conflict**.
125
- 3. **Ack**: Receiver sends back lists of needs/offers.
126
- 4. **Delta/Push**: Data exchange.
127
- 5. **Commit**: Session finalized.
138
+ 1. **Init**: Sender generates a **Knowledge Vector** (KV) summary.
139
+ 2. **Gap Analysis**: Receiver compares KVs.
140
+ * Sender behind -> **Push Offer**.
141
+ * Sender ahead -> **Delta Request**.
142
+ * Diverged -> **Conflict**.
143
+ 3. **Ack**: Receiver sends back lists of needs/offers.
144
+ 4. **Delta/Push**: Data exchange.
145
+ 5. **Commit**: Session finalized.
128
146
 
129
147
  ## 4. Identity (Keystone)
130
148
 
131
149
  **[Keystone](file:src/keystone/README.md)** is a novel, graph-native identity mechanism using **Hash-Based Cryptography** (Post-Quantum ready).
132
150
 
133
- * **Concept**: An identity is not a public key; it is a **Timeline** (Keystone). Verification is **Auditability**. To verify "Alice", you replay her Keystone timeline from Genesis to now, verifying proofs at each step.
134
- * **Mechanisms**:
135
- * **Hash-Reveal**: Uses schemes similar to **Lamport Signatures** or **Winternitz OTS**, but adapted for the ibGib graph.
136
- * **Merkle DAGs**: Efficiently communicates identity state by only syncing missing graph nodes.
137
- * **Sigma Protocols**: Can support zero-knowledge proofs for authentication without revealing private keys (future).
138
- * **Session Identity**: In Sync, we use ephemeral "Session Keystones" to sign the Saga, ensuring the integrity of the sync session without exposing long-term Master Identity keys.
151
+ * **Concept**: An identity is not a public key; it is a **Timeline** (Keystone). Verification is **Auditability**. To verify "Alice", you replay her Keystone timeline from Genesis to now, verifying proofs at each step.
152
+ * **Mechanisms**:
153
+ * **Hash-Reveal**: Uses schemes similar to **Lamport Signatures** or **Winternitz OTS**, but adapted for the ibGib graph.
154
+ * **Merkle DAGs**: Efficiently communicates identity state by only syncing missing graph nodes.
155
+ * **Sigma Protocols**: Can support zero-knowledge proofs for authentication without revealing private keys.
156
+ * Only partially implemented
157
+ * **Session Identity**: In Sync, we use ephemeral "Session Keystones" to sign the Saga, ensuring the integrity of the sync session without exposing long-term Master Identity keys.
158
+ * Only partially implemented
139
159
 
140
160
  ## Reference Links
141
- * **Core Types**: [libs/ts-gib/src/types.mts](file:../libs/ts-gib/src/types.mts)
142
- * **Transforms**: [libs/ts-gib/src/V1/transforms/](file:../libs/ts-gib/src/V1/transforms/)
143
- * **Witness**: [libs/core-gib/src/witness/witness-types.mts](file:src/witness/witness-types.mts)
144
- * **Space**: [libs/core-gib/src/witness/space/space-types.mts](file:src/witness/space/space-types.mts)
145
- * **Timeline API**: [libs/core-gib/src/timeline/timeline-api.mts](file:src/timeline/timeline-api.mts)
146
- * **Sync Coordinator**: [libs/core-gib/src/sync/sync-saga-coordinator.mts](file:src/sync/sync-saga-coordinator.mts)
147
- * **Keystone**: [libs/core-gib/src/keystone/README.md](file:src/keystone/README.md)
161
+ * **Core Types**: [libs/ts-gib/src/types.mts](file:../libs/ts-gib/src/types.mts)
162
+ * **Transforms**: [libs/ts-gib/src/V1/transforms/](file:../libs/ts-gib/src/V1/transforms/)
163
+ * **Witness**: [libs/core-gib/src/witness/witness-types.mts](file:src/witness/witness-types.mts)
164
+ * **Space**: [libs/core-gib/src/witness/space/space-types.mts](file:src/witness/space/space-types.mts)
165
+ * **Timeline API**: [libs/core-gib/src/timeline/timeline-api.mts](file:src/timeline/timeline-api.mts)
166
+ * **Sync Coordinator**: [libs/core-gib/src/sync/sync-saga-coordinator.mts](file:src/sync/sync-saga-coordinator.mts)
167
+ * **Keystone**: [libs/core-gib/src/keystone/README.md](file:src/keystone/README.md)
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@ibgib/core-gib",
3
- "version": "0.1.47",
3
+ "version": "0.1.49",
4
4
  "description": "ibgib core functionality, including base architecture for witnesses, spaces, apps, robbots, etc., as well as shared utility functions. Node v19+ needed for heavily-used isomorphic webcrypto hashing consumed in both node and browsers.",
5
5
  "funding": {
6
6
  "type": "individual",
@@ -1074,3 +1074,42 @@ export async function getIbGibsFromCache_fallbackToSpaces({
1074
1074
  if (logalot) { console.log(`${lc} complete.`); }
1075
1075
  }
1076
1076
  }
1077
+
1078
+ /**
1079
+ * naive general purpose helper guard function based off of a given ibgib's
1080
+ * `ib` property.
1081
+ *
1082
+ * uses conventional V1 `ib` schema, expecting space-delimited `ib` with the
1083
+ * first piece being the atom.
1084
+ *
1085
+ * @param x - any object, usually known to be an ibgib
1086
+ * @param atom - the expected atom that determines the type of ibgib
1087
+ * @returns true if `x.ib` contains `atom` and thus is `TIbGib`, else false
1088
+ */
1089
+ export function isIbGibWithAtom<TIbGib extends IbGib_V1>(x: any, atom: string): x is TIbGib {
1090
+ const lc = `[${isIbGibWithAtom.name}]`;
1091
+ try {
1092
+ if (logalot) { console.log(`${lc} starting... (I: e946f8ca70b65e6968bd8e78aa473826)`); }
1093
+
1094
+ if (!x.ib) {
1095
+ return false; /* <<<< returns early */
1096
+ }
1097
+
1098
+ if (typeof x.ib !== 'string') {
1099
+ return false; /* <<<< returns early */
1100
+ }
1101
+
1102
+ const [pieceAtom, ...otherPieces] = x.ib.split(' ');
1103
+
1104
+ if (atom !== pieceAtom) {
1105
+ return false; /* <<<< returns early */
1106
+ }
1107
+
1108
+ return true;
1109
+ } catch (error) {
1110
+ console.error(`${lc} ${extractErrorMsg(error)}`);
1111
+ throw error;
1112
+ } finally {
1113
+ if (logalot) { console.log(`${lc} complete.`); }
1114
+ }
1115
+ }
@@ -39,7 +39,7 @@ export async function deriveKey({
39
39
  const strategy = kdfOpts.strategy;
40
40
 
41
41
  switch (strategy) {
42
- case KdfStrategy['recursive-salt-wrap']:
42
+ case KdfStrategy.recursive_salt_wrap:
43
43
  return await kdf_recursiveSaltWrap({
44
44
  masterSecret,
45
45
  salt: kdfOpts.salt,
@@ -47,7 +47,7 @@ export async function deriveKey({
47
47
  algorithm: kdfOpts.algorithm
48
48
  });
49
49
  default:
50
- throw new Error(`Unknown KDF strategy: ${strategy}. valid values: ${KDF_STRATEGY_VALID_VALUES.join(', ')} (E: a1b2c3d4e5f6g7h8i9j0)`);
50
+ throw new Error(`Unknown KDF strategy: ${strategy}. valid values: ${KDF_STRATEGY_VALID_VALUES.join(', ')} (E: c81258e9d9481eb0f88385a825193226)`);
51
51
  }
52
52
 
53
53
  } catch (error) {
@@ -244,15 +244,23 @@ interface KeystoneConfigFactoryOptions_Standard {
244
244
  * verbs for the pool
245
245
  */
246
246
  verbs?: string[];
247
+
248
+ // only hash challenge type currently implemented
249
+ type?: KeystoneChallengeType,
247
250
  hashAlgorithm?: HashAlgorithm;
248
251
  hashRounds?: number;
249
252
  }
250
253
 
251
254
  export function createStandardPoolConfig(opts: KeystoneConfigFactoryOptions_Standard): KeystonePoolConfig {
252
- let {
255
+ if (opts.type && opts.type !== KeystoneChallengeType.hash_reveal_v1) {
256
+ throw new Error(`invalid type (${opts.type}). Only ${KeystoneChallengeType.hash_reveal_v1} currently implemented. (E: c38616cd7a459149f670418f88766526)`);
257
+ }
258
+
259
+ const {
253
260
  salt, id, size, sequential, random, targetBinding, replenishStrategy,
254
261
  verbs, hashAlgorithm, hashRounds,
255
262
  } = opts;
263
+
256
264
  return KeystoneConfig.hash()
257
265
  .withId(id)
258
266
  .withSalt(salt)
@@ -272,7 +280,10 @@ export function createStandardPoolConfig(opts: KeystoneConfigFactoryOptions_Stan
272
280
  }
273
281
 
274
282
  export function createHighSecurityPoolConfig(opts: KeystoneConfigFactoryOptions_Standard): KeystonePoolConfig {
275
- let {
283
+ if (opts.type && opts.type !== KeystoneChallengeType.hash_reveal_v1) {
284
+ throw new Error(`invalid type (${opts.type}). Only ${KeystoneChallengeType.hash_reveal_v1} currently implemented. (E: 09c1f7772bd2a7910f5562b4934d3826)`);
285
+ }
286
+ const {
276
287
  salt, id, size, sequential, random, targetBinding, replenishStrategy,
277
288
  verbs, hashAlgorithm, hashRounds,
278
289
  } = opts;
@@ -21,9 +21,14 @@ export const KEYSTONE_VERB_REVOKE = "revoke";
21
21
  * @see {@link KeystoneVerb.MANAGE}
22
22
  */
23
23
  export const KEYSTONE_VERB_MANAGE = "manage";
24
+ /**
25
+ * @see {@link KeystoneVerb.SIGN}
26
+ */
27
+ export const KEYSTONE_VERB_SIGN = "sign";
24
28
  export type KeystoneVerb =
25
29
  | typeof KEYSTONE_VERB_REVOKE
26
- | typeof KEYSTONE_VERB_MANAGE;
30
+ | typeof KEYSTONE_VERB_MANAGE
31
+ | typeof KEYSTONE_VERB_SIGN;
27
32
 
28
33
  /**
29
34
  * Verbs that describe actions that can be authorized by a Keystone.
@@ -41,8 +46,15 @@ export const KeystoneVerb = {
41
46
  * "Root access" to the identity.
42
47
  *
43
48
  * Basically, this is the verb for the "admin" pool.
49
+ *
50
+ * todo: add a separate "add pool" verb
51
+ * todo: add a one-time mechanism that limits pool use per verb.
44
52
  */
45
53
  MANAGE: KEYSTONE_VERB_MANAGE,
54
+ /**
55
+ * This is the least of all privileges that can actually evolve a keystone.
56
+ */
57
+ SIGN: KEYSTONE_VERB_SIGN,
46
58
  } satisfies { [key: string]: KeystoneVerb };
47
59
  export const KEYSTONE_VERB_VALID_VALUES = Object.values(KeystoneVerb);
48
60
  export function isKeystoneVerb(value: string): value is KeystoneVerb {
@@ -51,11 +63,21 @@ export function isKeystoneVerb(value: string): value is KeystoneVerb {
51
63
  // #endregion KeystoneVerb enum
52
64
 
53
65
  /**
54
- * Standard pool IDs can be conventionally named after their primary verb.
66
+ * Some standard pool IDs can be conventionally named after their primary verb,
67
+ * but this is not a requirement.
55
68
  */
56
69
  export const POOL_ID_REVOKE = KEYSTONE_VERB_REVOKE;
57
70
  export const POOL_ID_MANAGE = KEYSTONE_VERB_MANAGE;
58
71
  export const POOL_ID_DEFAULT = "default";
72
+ export const POOL_ID_DELEGATE = "delegate";
73
+ /**
74
+ * **THESE SHOULD ONLY BE USED IN TEMPORARY/SESSION KEYSTONES.**
75
+ * _this is because a receiver could intercept the stone, DoS participants and
76
+ * then take over a stone._
77
+ *
78
+ * transition pools are used as a temporary mechanism to create one-time management pools for delegates to create their own pools.
79
+ */
80
+ export const POOL_ID_TRANSITION = "transition";
59
81
 
60
82
  export const KEYSTONE_CONFIG_DEFAULT_SIZE = 200;
61
83
  export const KEYSTONE_CONFIG_DEFAULT_SEQUENTIAL = 2;
@@ -189,12 +189,14 @@ export function addToBindingMap(
189
189
  const firstChar = challengeId.charAt(0).toLowerCase();
190
190
  // Validate it is hex
191
191
  if (/[0-9a-f]/.test(firstChar)) {
192
- if (!map[firstChar]) map[firstChar] = [];
192
+ if (!map[firstChar]) { map[firstChar] = []; }
193
193
  map[firstChar].push(challengeId);
194
194
 
195
195
  // OPTIONAL: Implement Full Coverage Strategy here?
196
196
  // e.g. map[challengeId[1]].push(challengeId) ...
197
197
  // For V1, we stick to Native/Implicit bucket (Index 0).
198
+ } else {
199
+ throw new Error(`invalid challengeId (${challengeId}). Must start with a hex character. (E: c96ed8460de89e28c801370a0f07f826)`);
198
200
  }
199
201
  }
200
202
 
@@ -968,13 +970,6 @@ export async function validateKeystoneGraph({
968
970
  // maybe too defensive but...
969
971
  if (!keystoneIbGib) { throw new Error(`(UNEXPECTED) keystoneIbGib falsy? (E: 26482871d529fff6e8899c5d8a6c3826)`); }
970
972
 
971
- // #region leaving off here
972
- // asdf
973
- // just implemented validate keystone graph. incorporate this into the
974
- // context ibgib, which now has the session ibgib as part of it. each
975
- // step in ping pong should validate the entire keystone graph
976
-
977
- // #endregion leaving off here
978
973
  const errors: string[] = [];
979
974
 
980
975
  // first, get the latest if that is the case...
@@ -1048,8 +1043,8 @@ export async function validateKeystoneGraph({
1048
1043
  const keys = Object.keys(orderedKeystonesMap);
1049
1044
  if (keys.length === 0) {
1050
1045
  throw new Error(`(UNEXPECTED) orderedKeystonesMap empty? (E: d437b80bef58e83a034b28af46278726)`);
1051
- } else if (keys.length > 0) {
1052
- // keys.length > 0
1046
+ } else if (keys.length > 1) {
1047
+ // keys.length > 1
1053
1048
  throw new Error(`(UNEXPECTED) more than one timeline in keystone graph? ATOW (02/19/2026) we are expecting only a single timeline. (E: 66085b14e3887a59c872afd240511f26)`);
1054
1049
  }
1055
1050
  // happy path: exactly one timeline
@@ -31,11 +31,13 @@ export class KeystoneService_V1 {
31
31
  */
32
32
  async genesis({
33
33
  masterSecret,
34
+ frameDetails,
34
35
  configs,
35
36
  metaspace,
36
37
  space,
37
38
  }: {
38
39
  masterSecret: string;
40
+ frameDetails?: any;
39
41
  configs: KeystonePoolConfig[];
40
42
  metaspace: MetaspaceService;
41
43
  space: IbGibSpaceAny;
@@ -81,6 +83,7 @@ export class KeystoneService_V1 {
81
83
  if (challengePools.length === 0) { throw new Error(`No challenge pools created. (E: 38e538530996940e1f16a8b199995825)`); }
82
84
 
83
85
  const data: KeystoneData_V1 = { challengePools, proofs: [] };
86
+ if (frameDetails) { data.frameDetails = frameDetails; }
84
87
  const keystoneIbGib = await createKeystoneIbGibImpl({ data, metaspace, space });
85
88
  return keystoneIbGib;
86
89
  } catch (error) {
@@ -97,6 +100,8 @@ export class KeystoneService_V1 {
97
100
  * Uses a hybrid selection strategy: Mandatory IDs (Alice) + Sequential (FIFO) + Random (Stochastic).
98
101
  *
99
102
  * Supports Delegation via `poolFilter` to find specific foreign pools.
103
+ *
104
+ * todo: wrap this and other entire keystone sign/method implementations in locks on the keystone's tjpGib.
100
105
  */
101
106
  async sign({
102
107
  latestKeystone,