@git-stunts/git-warp 10.3.2 → 10.7.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +6 -3
- package/SECURITY.md +89 -1
- package/bin/warp-graph.js +574 -208
- package/index.d.ts +55 -0
- package/index.js +4 -0
- package/package.json +8 -4
- package/src/domain/WarpGraph.js +334 -161
- package/src/domain/crdt/LWW.js +1 -1
- package/src/domain/crdt/ORSet.js +10 -6
- package/src/domain/crdt/VersionVector.js +5 -1
- package/src/domain/errors/EmptyMessageError.js +2 -4
- package/src/domain/errors/ForkError.js +4 -0
- package/src/domain/errors/IndexError.js +4 -0
- package/src/domain/errors/OperationAbortedError.js +4 -0
- package/src/domain/errors/QueryError.js +4 -0
- package/src/domain/errors/SchemaUnsupportedError.js +4 -0
- package/src/domain/errors/ShardCorruptionError.js +2 -6
- package/src/domain/errors/ShardLoadError.js +2 -6
- package/src/domain/errors/ShardValidationError.js +2 -7
- package/src/domain/errors/StorageError.js +2 -6
- package/src/domain/errors/SyncError.js +4 -0
- package/src/domain/errors/TraversalError.js +4 -0
- package/src/domain/errors/WarpError.js +2 -4
- package/src/domain/errors/WormholeError.js +4 -0
- package/src/domain/services/AnchorMessageCodec.js +1 -4
- package/src/domain/services/BitmapIndexBuilder.js +10 -6
- package/src/domain/services/BitmapIndexReader.js +27 -21
- package/src/domain/services/BoundaryTransitionRecord.js +22 -15
- package/src/domain/services/CheckpointMessageCodec.js +1 -7
- package/src/domain/services/CheckpointSerializerV5.js +20 -19
- package/src/domain/services/CheckpointService.js +18 -18
- package/src/domain/services/CommitDagTraversalService.js +13 -1
- package/src/domain/services/DagPathFinding.js +40 -18
- package/src/domain/services/DagTopology.js +7 -6
- package/src/domain/services/DagTraversal.js +5 -3
- package/src/domain/services/Frontier.js +7 -6
- package/src/domain/services/HealthCheckService.js +15 -14
- package/src/domain/services/HookInstaller.js +64 -13
- package/src/domain/services/HttpSyncServer.js +88 -19
- package/src/domain/services/IndexRebuildService.js +12 -12
- package/src/domain/services/IndexStalenessChecker.js +13 -6
- package/src/domain/services/JoinReducer.js +28 -27
- package/src/domain/services/LogicalTraversal.js +7 -6
- package/src/domain/services/MessageCodecInternal.js +2 -0
- package/src/domain/services/ObserverView.js +6 -6
- package/src/domain/services/PatchBuilderV2.js +9 -9
- package/src/domain/services/PatchMessageCodec.js +1 -7
- package/src/domain/services/ProvenanceIndex.js +6 -8
- package/src/domain/services/ProvenancePayload.js +1 -2
- package/src/domain/services/QueryBuilder.js +29 -23
- package/src/domain/services/StateDiff.js +7 -7
- package/src/domain/services/StateSerializerV5.js +8 -6
- package/src/domain/services/StreamingBitmapIndexBuilder.js +29 -23
- package/src/domain/services/SyncAuthService.js +396 -0
- package/src/domain/services/SyncProtocol.js +23 -26
- package/src/domain/services/TemporalQuery.js +4 -3
- package/src/domain/services/TranslationCost.js +4 -4
- package/src/domain/services/WormholeService.js +19 -15
- package/src/domain/types/TickReceipt.js +10 -6
- package/src/domain/types/WarpTypesV2.js +2 -3
- package/src/domain/utils/CachedValue.js +1 -1
- package/src/domain/utils/LRUCache.js +3 -3
- package/src/domain/utils/MinHeap.js +2 -2
- package/src/domain/utils/RefLayout.js +19 -0
- package/src/domain/utils/WriterId.js +2 -2
- package/src/domain/utils/defaultCodec.js +9 -2
- package/src/domain/utils/defaultCrypto.js +36 -0
- package/src/domain/utils/roaring.js +5 -5
- package/src/domain/utils/seekCacheKey.js +32 -0
- package/src/domain/warp/PatchSession.js +3 -3
- package/src/domain/warp/Writer.js +2 -2
- package/src/infrastructure/adapters/BunHttpAdapter.js +21 -8
- package/src/infrastructure/adapters/CasSeekCacheAdapter.js +311 -0
- package/src/infrastructure/adapters/ClockAdapter.js +2 -2
- package/src/infrastructure/adapters/DenoHttpAdapter.js +22 -9
- package/src/infrastructure/adapters/GitGraphAdapter.js +25 -83
- package/src/infrastructure/adapters/InMemoryGraphAdapter.js +488 -0
- package/src/infrastructure/adapters/NodeCryptoAdapter.js +16 -3
- package/src/infrastructure/adapters/NodeHttpAdapter.js +33 -11
- package/src/infrastructure/adapters/WebCryptoAdapter.js +21 -11
- package/src/infrastructure/adapters/adapterValidation.js +90 -0
- package/src/infrastructure/codecs/CborCodec.js +16 -8
- package/src/ports/BlobPort.js +2 -2
- package/src/ports/CodecPort.js +2 -2
- package/src/ports/CommitPort.js +8 -21
- package/src/ports/ConfigPort.js +3 -3
- package/src/ports/CryptoPort.js +7 -7
- package/src/ports/GraphPersistencePort.js +12 -14
- package/src/ports/HttpServerPort.js +1 -5
- package/src/ports/IndexStoragePort.js +1 -0
- package/src/ports/LoggerPort.js +9 -9
- package/src/ports/RefPort.js +5 -5
- package/src/ports/SeekCachePort.js +73 -0
- package/src/ports/TreePort.js +3 -3
- package/src/visualization/layouts/converters.js +14 -7
- package/src/visualization/layouts/elkAdapter.js +17 -4
- package/src/visualization/layouts/elkLayout.js +23 -7
- package/src/visualization/layouts/index.js +3 -3
- package/src/visualization/renderers/ascii/check.js +30 -17
- package/src/visualization/renderers/ascii/graph.js +92 -1
- package/src/visualization/renderers/ascii/history.js +28 -26
- package/src/visualization/renderers/ascii/info.js +9 -7
- package/src/visualization/renderers/ascii/materialize.js +20 -16
- package/src/visualization/renderers/ascii/opSummary.js +15 -7
- package/src/visualization/renderers/ascii/path.js +1 -1
- package/src/visualization/renderers/ascii/seek.js +187 -23
- package/src/visualization/renderers/ascii/table.js +1 -1
- package/src/visualization/renderers/svg/index.js +5 -1
package/README.md
CHANGED
|
@@ -414,6 +414,8 @@ git warp seek --tick=-1 # step backward one tick
|
|
|
414
414
|
git warp seek --save before-refactor # bookmark current position
|
|
415
415
|
git warp seek --load before-refactor # restore bookmark
|
|
416
416
|
git warp seek --latest # return to present
|
|
417
|
+
git warp seek --clear-cache # purge persistent seek cache
|
|
418
|
+
git warp seek --no-persistent-cache --tick 5 # skip cache for one invocation
|
|
417
419
|
|
|
418
420
|
# Visualize query results (ascii output by default)
|
|
419
421
|
git warp query --match 'user:*' --outgoing manages --view
|
|
@@ -439,15 +441,17 @@ The codebase follows hexagonal architecture with ports and adapters:
|
|
|
439
441
|
- `CryptoPort` -- hash/HMAC operations
|
|
440
442
|
- `LoggerPort` -- structured logging
|
|
441
443
|
- `ClockPort` -- time measurement
|
|
444
|
+
- `SeekCachePort` -- persistent seek materialization cache
|
|
442
445
|
|
|
443
446
|
**Adapters** implement the ports:
|
|
444
447
|
- `GitGraphAdapter` -- wraps `@git-stunts/plumbing` for Git operations
|
|
445
448
|
- `ClockAdapter` -- unified clock (factory: `ClockAdapter.node()`, `ClockAdapter.global()`)
|
|
446
449
|
- `NodeCryptoAdapter` -- cryptographic operations via `node:crypto`
|
|
447
|
-
- `WebCryptoAdapter` -- cryptographic operations via Web Crypto API (browsers, Deno, Bun, Node
|
|
450
|
+
- `WebCryptoAdapter` -- cryptographic operations via Web Crypto API (browsers, Deno, Bun, Node 22+)
|
|
448
451
|
- `NodeHttpAdapter` / `BunHttpAdapter` / `DenoHttpAdapter` -- HTTP server per runtime
|
|
449
452
|
- `ConsoleLogger` / `NoOpLogger` -- logging implementations
|
|
450
453
|
- `CborCodec` -- CBOR serialization for patches
|
|
454
|
+
- `CasSeekCacheAdapter` -- persistent seek cache via `@git-stunts/git-cas`
|
|
451
455
|
|
|
452
456
|
**Domain** contains the core logic:
|
|
453
457
|
- `WarpGraph` -- public API facade
|
|
@@ -483,10 +487,9 @@ npm run lint # eslint
|
|
|
483
487
|
|
|
484
488
|
# Multi-runtime test matrix (Docker)
|
|
485
489
|
npm run test:node22 # Node 22: unit + integration + BATS CLI
|
|
486
|
-
npm run test:node20 # Node 20: unit + integration + BATS CLI
|
|
487
490
|
npm run test:bun # Bun: API integration tests
|
|
488
491
|
npm run test:deno # Deno: API integration tests
|
|
489
|
-
npm run test:matrix # All
|
|
492
|
+
npm run test:matrix # All runtimes in parallel
|
|
490
493
|
```
|
|
491
494
|
|
|
492
495
|
## AIΩN Foundations Series
|
package/SECURITY.md
CHANGED
|
@@ -25,6 +25,94 @@ The `GitGraphAdapter` validates all ref arguments to prevent injection attacks:
|
|
|
25
25
|
- **Bitmap Indexing**: Sharded Roaring Bitmap indexes enable O(1) lookups without loading entire graphs
|
|
26
26
|
- **Delimiter Safety**: Uses ASCII Record Separator (`\x1E`) to prevent message collision
|
|
27
27
|
|
|
28
|
-
##
|
|
28
|
+
## Sync Authentication (SHIELD)
|
|
29
|
+
|
|
30
|
+
### Overview
|
|
31
|
+
|
|
32
|
+
The HTTP sync protocol supports optional HMAC-SHA256 request signing with replay protection. When enabled, every sync request must carry a valid signature computed over a canonical payload that includes the request body, timestamp, and a unique nonce.
|
|
33
|
+
|
|
34
|
+
### Threat Model
|
|
35
|
+
|
|
36
|
+
**Protected against:**
|
|
37
|
+
- Unauthorized sync requests from unknown peers
|
|
38
|
+
- Replay attacks (nonce-based, with 5-minute TTL window)
|
|
39
|
+
- Request body tampering (HMAC covers body SHA-256)
|
|
40
|
+
- Timing attacks on signature comparison (`timingSafeEqual`)
|
|
41
|
+
|
|
42
|
+
**Not protected against:**
|
|
43
|
+
- Compromised shared secrets (rotate keys immediately if leaked)
|
|
44
|
+
- Denial-of-service (body size limits provide basic protection, but no rate limiting)
|
|
45
|
+
- Man-in-the-middle without TLS (use HTTPS in production)
|
|
46
|
+
|
|
47
|
+
### Authentication Flow
|
|
48
|
+
|
|
49
|
+
1. Client computes SHA-256 of request body
|
|
50
|
+
2. Client builds canonical payload: `warp-v1|KEY_ID|METHOD|PATH|TIMESTAMP|NONCE|CONTENT_TYPE|BODY_SHA256`
|
|
51
|
+
3. Client computes HMAC-SHA256 of canonical payload using shared secret
|
|
52
|
+
4. Client sends 5 auth headers: `x-warp-sig-version`, `x-warp-key-id`, `x-warp-timestamp`, `x-warp-nonce`, `x-warp-signature`
|
|
53
|
+
5. Server validates header formats (cheap checks first)
|
|
54
|
+
6. Server checks clock skew (default: 5 minutes)
|
|
55
|
+
7. Server reserves nonce atomically (prevents replay)
|
|
56
|
+
8. Server resolves key by key-id
|
|
57
|
+
9. Server recomputes HMAC and compares with constant-time equality
|
|
58
|
+
|
|
59
|
+
### Enforcement Modes
|
|
60
|
+
|
|
61
|
+
- **`enforce`** (default): Rejects requests that fail authentication with appropriate HTTP status codes (400/401/403). No request details leak in error responses.
|
|
62
|
+
- **`log-only`**: Logs authentication failures but allows requests through. Use during rollout to identify issues before enforcing.
|
|
63
|
+
|
|
64
|
+
### Error Response Hygiene
|
|
65
|
+
|
|
66
|
+
External error responses use coarse status codes and generic reason strings:
|
|
67
|
+
- `400` — Malformed headers (version, timestamp, nonce, signature format)
|
|
68
|
+
- `401` — Missing auth headers, unknown key-id, invalid signature
|
|
69
|
+
- `403` — Expired timestamp, replayed nonce
|
|
70
|
+
|
|
71
|
+
Detailed diagnostics (exact failure reason, key-id, peer info) are sent to the structured logger only.
|
|
72
|
+
|
|
73
|
+
### Nonce Cache and Restart Semantics
|
|
74
|
+
|
|
75
|
+
The nonce cache is an in-memory LRU (default capacity: 100,000 entries). On server restart, the cache is empty. This means:
|
|
76
|
+
- Nonces from before the restart can be replayed within the 5-minute clock skew window
|
|
77
|
+
- This is an accepted trade-off for simplicity; persistent nonce storage is not implemented in v1
|
|
78
|
+
- For higher security, keep the clock skew window small and use TLS
|
|
79
|
+
|
|
80
|
+
### Key Rotation
|
|
81
|
+
|
|
82
|
+
Key management uses a key-id system for zero-downtime rotation:
|
|
83
|
+
|
|
84
|
+
1. Add the new key-id and secret to the server's `keys` map
|
|
85
|
+
2. Deploy the server
|
|
86
|
+
3. Update clients to use the new key-id
|
|
87
|
+
4. Remove the old key-id from the server's `keys` map
|
|
88
|
+
5. Deploy again
|
|
89
|
+
|
|
90
|
+
Multiple key-ids can coexist indefinitely.
|
|
91
|
+
|
|
92
|
+
### Configuration
|
|
93
|
+
|
|
94
|
+
**Server (`serve()`):**
|
|
95
|
+
```js
|
|
96
|
+
await graph.serve({
|
|
97
|
+
port: 3000,
|
|
98
|
+
httpPort: new NodeHttpAdapter(),
|
|
99
|
+
auth: {
|
|
100
|
+
keys: { default: 'your-shared-secret' },
|
|
101
|
+
mode: 'enforce', // or 'log-only'
|
|
102
|
+
},
|
|
103
|
+
});
|
|
104
|
+
```
|
|
105
|
+
|
|
106
|
+
**Client (`syncWith()`):**
|
|
107
|
+
```js
|
|
108
|
+
await graph.syncWith('http://peer:3000', {
|
|
109
|
+
auth: {
|
|
110
|
+
secret: 'your-shared-secret',
|
|
111
|
+
keyId: 'default',
|
|
112
|
+
},
|
|
113
|
+
});
|
|
114
|
+
```
|
|
115
|
+
|
|
116
|
+
## Reporting a Vulnerability
|
|
29
117
|
|
|
30
118
|
If you discover a security vulnerability, please send an e-mail to [james@flyingrobots.dev](mailto:james@flyingrobots.dev).
|