@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.
- package/dist/common/other/ibgib-helper.d.mts +12 -0
- package/dist/common/other/ibgib-helper.d.mts.map +1 -1
- package/dist/common/other/ibgib-helper.mjs +39 -0
- package/dist/common/other/ibgib-helper.mjs.map +1 -1
- package/dist/keystone/kdf/kdf-helpers.mjs +2 -2
- package/dist/keystone/kdf/kdf-helpers.mjs.map +1 -1
- package/dist/keystone/keystone-config-builder.d.mts +2 -1
- package/dist/keystone/keystone-config-builder.d.mts.map +1 -1
- package/dist/keystone/keystone-config-builder.mjs +8 -2
- package/dist/keystone/keystone-config-builder.mjs.map +1 -1
- package/dist/keystone/keystone-constants.d.mts +24 -3
- package/dist/keystone/keystone-constants.d.mts.map +1 -1
- package/dist/keystone/keystone-constants.mjs +22 -1
- package/dist/keystone/keystone-constants.mjs.map +1 -1
- package/dist/keystone/keystone-helpers.d.mts.map +1 -1
- package/dist/keystone/keystone-helpers.mjs +7 -9
- package/dist/keystone/keystone-helpers.mjs.map +1 -1
- package/dist/keystone/keystone-service-v1.d.mts +4 -1
- package/dist/keystone/keystone-service-v1.d.mts.map +1 -1
- package/dist/keystone/keystone-service-v1.mjs +6 -1
- package/dist/keystone/keystone-service-v1.mjs.map +1 -1
- package/dist/keystone/keystone-service-v1.respec.mjs +26 -26
- package/dist/keystone/keystone-service-v1.respec.mjs.map +1 -1
- package/dist/keystone/keystone-types.d.mts +24 -5
- package/dist/keystone/keystone-types.d.mts.map +1 -1
- package/dist/keystone/keystone-types.mjs.map +1 -1
- package/dist/sync/sync-conflict-adv-multitimelines.respec.mjs +2 -2
- package/dist/sync/sync-conflict-adv-multitimelines.respec.mjs.map +1 -1
- package/dist/sync/sync-conflict-basic-divergence.respec.mjs +2 -2
- package/dist/sync/sync-conflict-basic-divergence.respec.mjs.map +1 -1
- package/dist/sync/sync-conflict-basic-multitimelines.respec.mjs +2 -2
- package/dist/sync/sync-conflict-basic-multitimelines.respec.mjs.map +1 -1
- package/dist/sync/sync-conflict-text-merge.respec.mjs +2 -2
- package/dist/sync/sync-conflict-text-merge.respec.mjs.map +1 -1
- package/dist/sync/sync-constants.d.mts +47 -1
- package/dist/sync/sync-constants.d.mts.map +1 -1
- package/dist/sync/sync-constants.mjs +49 -1
- package/dist/sync/sync-constants.mjs.map +1 -1
- package/dist/sync/sync-innerspace-constants.respec.mjs +2 -2
- package/dist/sync/sync-innerspace-constants.respec.mjs.map +1 -1
- package/dist/sync/sync-innerspace-deep-updates.respec.mjs +2 -2
- package/dist/sync/sync-innerspace-deep-updates.respec.mjs.map +1 -1
- package/dist/sync/sync-innerspace-dest-ahead-withid.respec.mjs +22 -8
- package/dist/sync/sync-innerspace-dest-ahead-withid.respec.mjs.map +1 -1
- package/dist/sync/sync-innerspace-dest-ahead.respec.mjs +2 -2
- package/dist/sync/sync-innerspace-dest-ahead.respec.mjs.map +1 -1
- package/dist/sync/sync-innerspace-multiple-timelines.respec.mjs +2 -2
- package/dist/sync/sync-innerspace-multiple-timelines.respec.mjs.map +1 -1
- package/dist/sync/sync-innerspace-partial-update.respec.mjs +2 -2
- package/dist/sync/sync-innerspace-partial-update.respec.mjs.map +1 -1
- package/dist/sync/sync-innerspace.respec.mjs +2 -2
- package/dist/sync/sync-innerspace.respec.mjs.map +1 -1
- package/dist/sync/sync-peer/sync-peer-http-receiver/sync-http-node-adapter.d.mts +57 -0
- package/dist/sync/sync-peer/sync-peer-http-receiver/sync-http-node-adapter.d.mts.map +1 -0
- package/dist/sync/sync-peer/sync-peer-http-receiver/sync-http-node-adapter.mjs +310 -0
- package/dist/sync/sync-peer/sync-peer-http-receiver/sync-http-node-adapter.mjs.map +1 -0
- package/dist/sync/sync-peer/sync-peer-http-receiver/sync-peer-http-receiver-types.d.mts +27 -0
- package/dist/sync/sync-peer/sync-peer-http-receiver/sync-peer-http-receiver-types.d.mts.map +1 -0
- package/dist/sync/sync-peer/sync-peer-http-receiver/sync-peer-http-receiver-types.mjs +2 -0
- package/dist/sync/sync-peer/sync-peer-http-receiver/sync-peer-http-receiver-types.mjs.map +1 -0
- package/dist/sync/sync-peer/sync-peer-http-receiver/sync-peer-http-receiver-v1.d.mts +29 -0
- package/dist/sync/sync-peer/sync-peer-http-receiver/sync-peer-http-receiver-v1.d.mts.map +1 -0
- package/dist/sync/sync-peer/sync-peer-http-receiver/sync-peer-http-receiver-v1.mjs +122 -0
- package/dist/sync/sync-peer/sync-peer-http-receiver/sync-peer-http-receiver-v1.mjs.map +1 -0
- package/dist/sync/sync-peer/sync-peer-http-sender/sync-peer-http-sender-types.d.mts +27 -0
- package/dist/sync/sync-peer/sync-peer-http-sender/sync-peer-http-sender-types.d.mts.map +1 -0
- package/dist/sync/sync-peer/sync-peer-http-sender/sync-peer-http-sender-types.mjs +2 -0
- package/dist/sync/sync-peer/sync-peer-http-sender/sync-peer-http-sender-types.mjs.map +1 -0
- package/dist/sync/sync-peer/sync-peer-http-sender/sync-peer-http-sender-v1.d.mts +24 -0
- package/dist/sync/sync-peer/sync-peer-http-sender/sync-peer-http-sender-v1.d.mts.map +1 -0
- package/dist/sync/sync-peer/sync-peer-http-sender/sync-peer-http-sender-v1.mjs +111 -0
- package/dist/sync/sync-peer/sync-peer-http-sender/sync-peer-http-sender-v1.mjs.map +1 -0
- package/dist/sync/sync-peer/sync-peer-http.respec.d.mts +8 -0
- package/dist/sync/sync-peer/sync-peer-http.respec.d.mts.map +1 -0
- package/dist/sync/sync-peer/sync-peer-http.respec.mjs +333 -0
- package/dist/sync/sync-peer/sync-peer-http.respec.mjs.map +1 -0
- package/dist/sync/sync-peer/sync-peer-innerspace/sync-peer-innerspace-v1.d.mts.map +1 -1
- package/dist/sync/sync-peer/sync-peer-innerspace/sync-peer-innerspace-v1.mjs +13 -7
- package/dist/sync/sync-peer/sync-peer-innerspace/sync-peer-innerspace-v1.mjs.map +1 -1
- package/dist/sync/sync-peer/sync-peer-types.d.mts +5 -5
- package/dist/sync/sync-peer/sync-peer-types.d.mts.map +1 -1
- package/dist/sync/sync-peer/sync-peer-v1.d.mts +6 -3
- package/dist/sync/sync-peer/sync-peer-v1.d.mts.map +1 -1
- package/dist/sync/sync-peer/sync-peer-v1.mjs +75 -26
- package/dist/sync/sync-peer/sync-peer-v1.mjs.map +1 -1
- package/dist/sync/sync-saga-context/sync-saga-context-helpers.d.mts +7 -3
- package/dist/sync/sync-saga-context/sync-saga-context-helpers.d.mts.map +1 -1
- package/dist/sync/sync-saga-context/sync-saga-context-helpers.mjs +32 -3
- package/dist/sync/sync-saga-context/sync-saga-context-helpers.mjs.map +1 -1
- package/dist/sync/sync-saga-context/sync-saga-context-types.d.mts +16 -0
- package/dist/sync/sync-saga-context/sync-saga-context-types.d.mts.map +1 -1
- package/dist/sync/sync-saga-coordinator.d.mts +18 -3
- package/dist/sync/sync-saga-coordinator.d.mts.map +1 -1
- package/dist/sync/sync-saga-coordinator.mjs +241 -56
- package/dist/sync/sync-saga-coordinator.mjs.map +1 -1
- package/dist/sync/sync-types.d.mts +1 -1
- package/dist/sync/sync-types.d.mts.map +1 -1
- package/ibgib-foundations.md +109 -89
- package/package.json +1 -1
- package/src/common/other/ibgib-helper.mts +39 -0
- package/src/keystone/kdf/kdf-helpers.mts +2 -2
- package/src/keystone/keystone-config-builder.mts +13 -2
- package/src/keystone/keystone-constants.mts +24 -2
- package/src/keystone/keystone-helpers.mts +5 -10
- package/src/keystone/keystone-service-v1.mts +5 -0
- package/src/keystone/keystone-service-v1.respec.mts +25 -25
- package/src/keystone/keystone-types.mts +27 -7
- package/src/sync/sync-conflict-adv-multitimelines.respec.mts +2 -2
- package/src/sync/sync-conflict-basic-divergence.respec.mts +2 -2
- package/src/sync/sync-conflict-basic-multitimelines.respec.mts +2 -2
- package/src/sync/sync-conflict-text-merge.respec.mts +2 -2
- package/src/sync/sync-constants.mts +51 -1
- package/src/sync/sync-innerspace-constants.respec.mts +2 -2
- package/src/sync/sync-innerspace-deep-updates.respec.mts +2 -2
- package/src/sync/sync-innerspace-dest-ahead-withid.respec.mts +26 -9
- package/src/sync/sync-innerspace-dest-ahead.respec.mts +2 -2
- package/src/sync/sync-innerspace-multiple-timelines.respec.mts +2 -2
- package/src/sync/sync-innerspace-partial-update.respec.mts +2 -2
- package/src/sync/sync-innerspace.respec.mts +2 -2
- package/src/sync/sync-peer/sync-peer-http-receiver/sync-http-node-adapter.mts +319 -0
- package/src/sync/sync-peer/sync-peer-http-receiver/sync-http-node-adapter.mts.metadata.md +72 -0
- package/src/sync/sync-peer/sync-peer-http-receiver/sync-peer-http-receiver-types.mts +30 -0
- package/src/sync/sync-peer/sync-peer-http-receiver/sync-peer-http-receiver-v1.mts +146 -0
- package/src/sync/sync-peer/sync-peer-http-receiver/sync-peer-http-receiver-v1.mts.metadata.md +71 -0
- package/src/sync/sync-peer/sync-peer-http-sender/sync-peer-http-sender-types.mts +32 -0
- package/src/sync/sync-peer/sync-peer-http-sender/sync-peer-http-sender-v1.mts +129 -0
- package/src/sync/sync-peer/sync-peer-http.respec.mts +364 -0
- package/src/sync/sync-peer/sync-peer-innerspace/sync-peer-innerspace-types.mts +8 -8
- package/src/sync/sync-peer/sync-peer-innerspace/sync-peer-innerspace-v1.mts +15 -7
- package/src/sync/sync-peer/sync-peer-types.mts +11 -11
- package/src/sync/sync-peer/sync-peer-v1.mts +66 -30
- package/src/sync/sync-saga-context/sync-saga-context-helpers.mts +52 -4
- package/src/sync/sync-saga-context/sync-saga-context-types.mts +17 -0
- package/src/sync/sync-saga-coordinator.mts +296 -63
- package/src/sync/sync-types.mts +1 -1
- package/tmp-certs/server.pfx +0 -0
package/ibgib-foundations.md
CHANGED
|
@@ -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
|
-
*
|
|
10
|
-
*
|
|
11
|
-
*
|
|
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
|
-
*
|
|
16
|
-
*
|
|
17
|
-
*
|
|
18
|
-
*
|
|
19
|
-
*
|
|
20
|
-
*
|
|
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.
|
|
25
|
-
2.
|
|
26
|
-
*
|
|
27
|
-
*
|
|
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
|
-
*
|
|
32
|
-
*
|
|
33
|
-
*
|
|
34
|
-
*
|
|
35
|
-
*
|
|
36
|
-
*
|
|
37
|
-
*
|
|
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
|
-
*
|
|
42
|
-
*
|
|
43
|
-
*
|
|
44
|
-
*
|
|
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
|
-
*
|
|
52
|
-
*
|
|
53
|
-
*
|
|
54
|
-
*
|
|
55
|
-
*
|
|
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
|
-
*
|
|
60
|
-
*
|
|
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
|
-
*
|
|
64
|
-
*
|
|
65
|
-
*
|
|
66
|
-
*
|
|
67
|
-
*
|
|
68
|
-
*
|
|
69
|
-
*
|
|
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
|
-
*
|
|
74
|
-
*
|
|
75
|
-
|
|
76
|
-
### respec-gib Test Framework
|
|
77
|
-
|
|
78
|
-
`
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
*
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
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
|
-
*
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
*
|
|
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
|
-
*
|
|
99
|
-
*
|
|
100
|
-
*
|
|
101
|
-
*
|
|
102
|
-
*
|
|
103
|
-
*
|
|
104
|
-
*
|
|
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
|
-
*
|
|
116
|
-
*
|
|
117
|
-
*
|
|
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.
|
|
121
|
-
2.
|
|
122
|
-
*
|
|
123
|
-
*
|
|
124
|
-
*
|
|
125
|
-
3.
|
|
126
|
-
4.
|
|
127
|
-
5.
|
|
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
|
-
*
|
|
134
|
-
*
|
|
135
|
-
*
|
|
136
|
-
*
|
|
137
|
-
*
|
|
138
|
-
*
|
|
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
|
-
*
|
|
142
|
-
*
|
|
143
|
-
*
|
|
144
|
-
*
|
|
145
|
-
*
|
|
146
|
-
*
|
|
147
|
-
*
|
|
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.
|
|
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
|
|
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:
|
|
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
|
-
|
|
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
|
-
|
|
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
|
-
*
|
|
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 >
|
|
1052
|
-
// keys.length >
|
|
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,
|