@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.
Files changed (108) hide show
  1. package/README.md +6 -3
  2. package/SECURITY.md +89 -1
  3. package/bin/warp-graph.js +574 -208
  4. package/index.d.ts +55 -0
  5. package/index.js +4 -0
  6. package/package.json +8 -4
  7. package/src/domain/WarpGraph.js +334 -161
  8. package/src/domain/crdt/LWW.js +1 -1
  9. package/src/domain/crdt/ORSet.js +10 -6
  10. package/src/domain/crdt/VersionVector.js +5 -1
  11. package/src/domain/errors/EmptyMessageError.js +2 -4
  12. package/src/domain/errors/ForkError.js +4 -0
  13. package/src/domain/errors/IndexError.js +4 -0
  14. package/src/domain/errors/OperationAbortedError.js +4 -0
  15. package/src/domain/errors/QueryError.js +4 -0
  16. package/src/domain/errors/SchemaUnsupportedError.js +4 -0
  17. package/src/domain/errors/ShardCorruptionError.js +2 -6
  18. package/src/domain/errors/ShardLoadError.js +2 -6
  19. package/src/domain/errors/ShardValidationError.js +2 -7
  20. package/src/domain/errors/StorageError.js +2 -6
  21. package/src/domain/errors/SyncError.js +4 -0
  22. package/src/domain/errors/TraversalError.js +4 -0
  23. package/src/domain/errors/WarpError.js +2 -4
  24. package/src/domain/errors/WormholeError.js +4 -0
  25. package/src/domain/services/AnchorMessageCodec.js +1 -4
  26. package/src/domain/services/BitmapIndexBuilder.js +10 -6
  27. package/src/domain/services/BitmapIndexReader.js +27 -21
  28. package/src/domain/services/BoundaryTransitionRecord.js +22 -15
  29. package/src/domain/services/CheckpointMessageCodec.js +1 -7
  30. package/src/domain/services/CheckpointSerializerV5.js +20 -19
  31. package/src/domain/services/CheckpointService.js +18 -18
  32. package/src/domain/services/CommitDagTraversalService.js +13 -1
  33. package/src/domain/services/DagPathFinding.js +40 -18
  34. package/src/domain/services/DagTopology.js +7 -6
  35. package/src/domain/services/DagTraversal.js +5 -3
  36. package/src/domain/services/Frontier.js +7 -6
  37. package/src/domain/services/HealthCheckService.js +15 -14
  38. package/src/domain/services/HookInstaller.js +64 -13
  39. package/src/domain/services/HttpSyncServer.js +88 -19
  40. package/src/domain/services/IndexRebuildService.js +12 -12
  41. package/src/domain/services/IndexStalenessChecker.js +13 -6
  42. package/src/domain/services/JoinReducer.js +28 -27
  43. package/src/domain/services/LogicalTraversal.js +7 -6
  44. package/src/domain/services/MessageCodecInternal.js +2 -0
  45. package/src/domain/services/ObserverView.js +6 -6
  46. package/src/domain/services/PatchBuilderV2.js +9 -9
  47. package/src/domain/services/PatchMessageCodec.js +1 -7
  48. package/src/domain/services/ProvenanceIndex.js +6 -8
  49. package/src/domain/services/ProvenancePayload.js +1 -2
  50. package/src/domain/services/QueryBuilder.js +29 -23
  51. package/src/domain/services/StateDiff.js +7 -7
  52. package/src/domain/services/StateSerializerV5.js +8 -6
  53. package/src/domain/services/StreamingBitmapIndexBuilder.js +29 -23
  54. package/src/domain/services/SyncAuthService.js +396 -0
  55. package/src/domain/services/SyncProtocol.js +23 -26
  56. package/src/domain/services/TemporalQuery.js +4 -3
  57. package/src/domain/services/TranslationCost.js +4 -4
  58. package/src/domain/services/WormholeService.js +19 -15
  59. package/src/domain/types/TickReceipt.js +10 -6
  60. package/src/domain/types/WarpTypesV2.js +2 -3
  61. package/src/domain/utils/CachedValue.js +1 -1
  62. package/src/domain/utils/LRUCache.js +3 -3
  63. package/src/domain/utils/MinHeap.js +2 -2
  64. package/src/domain/utils/RefLayout.js +19 -0
  65. package/src/domain/utils/WriterId.js +2 -2
  66. package/src/domain/utils/defaultCodec.js +9 -2
  67. package/src/domain/utils/defaultCrypto.js +36 -0
  68. package/src/domain/utils/roaring.js +5 -5
  69. package/src/domain/utils/seekCacheKey.js +32 -0
  70. package/src/domain/warp/PatchSession.js +3 -3
  71. package/src/domain/warp/Writer.js +2 -2
  72. package/src/infrastructure/adapters/BunHttpAdapter.js +21 -8
  73. package/src/infrastructure/adapters/CasSeekCacheAdapter.js +311 -0
  74. package/src/infrastructure/adapters/ClockAdapter.js +2 -2
  75. package/src/infrastructure/adapters/DenoHttpAdapter.js +22 -9
  76. package/src/infrastructure/adapters/GitGraphAdapter.js +25 -83
  77. package/src/infrastructure/adapters/InMemoryGraphAdapter.js +488 -0
  78. package/src/infrastructure/adapters/NodeCryptoAdapter.js +16 -3
  79. package/src/infrastructure/adapters/NodeHttpAdapter.js +33 -11
  80. package/src/infrastructure/adapters/WebCryptoAdapter.js +21 -11
  81. package/src/infrastructure/adapters/adapterValidation.js +90 -0
  82. package/src/infrastructure/codecs/CborCodec.js +16 -8
  83. package/src/ports/BlobPort.js +2 -2
  84. package/src/ports/CodecPort.js +2 -2
  85. package/src/ports/CommitPort.js +8 -21
  86. package/src/ports/ConfigPort.js +3 -3
  87. package/src/ports/CryptoPort.js +7 -7
  88. package/src/ports/GraphPersistencePort.js +12 -14
  89. package/src/ports/HttpServerPort.js +1 -5
  90. package/src/ports/IndexStoragePort.js +1 -0
  91. package/src/ports/LoggerPort.js +9 -9
  92. package/src/ports/RefPort.js +5 -5
  93. package/src/ports/SeekCachePort.js +73 -0
  94. package/src/ports/TreePort.js +3 -3
  95. package/src/visualization/layouts/converters.js +14 -7
  96. package/src/visualization/layouts/elkAdapter.js +17 -4
  97. package/src/visualization/layouts/elkLayout.js +23 -7
  98. package/src/visualization/layouts/index.js +3 -3
  99. package/src/visualization/renderers/ascii/check.js +30 -17
  100. package/src/visualization/renderers/ascii/graph.js +92 -1
  101. package/src/visualization/renderers/ascii/history.js +28 -26
  102. package/src/visualization/renderers/ascii/info.js +9 -7
  103. package/src/visualization/renderers/ascii/materialize.js +20 -16
  104. package/src/visualization/renderers/ascii/opSummary.js +15 -7
  105. package/src/visualization/renderers/ascii/path.js +1 -1
  106. package/src/visualization/renderers/ascii/seek.js +187 -23
  107. package/src/visualization/renderers/ascii/table.js +1 -1
  108. 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 20+)
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 four runtimes in parallel
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
- ## 🐞 Reporting a Vulnerability
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).