gridstamp 1.0.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 (42) hide show
  1. package/.cursorrules +74 -0
  2. package/CLAUDE.md +61 -0
  3. package/LICENSE +190 -0
  4. package/README.md +107 -0
  5. package/dist/index.js +194 -0
  6. package/package.json +84 -0
  7. package/src/antispoofing/detector.ts +509 -0
  8. package/src/antispoofing/index.ts +7 -0
  9. package/src/gamification/badges.ts +429 -0
  10. package/src/gamification/fleet-leaderboard.ts +293 -0
  11. package/src/gamification/index.ts +44 -0
  12. package/src/gamification/streaks.ts +243 -0
  13. package/src/gamification/trust-tiers.ts +393 -0
  14. package/src/gamification/zone-mastery.ts +256 -0
  15. package/src/index.ts +341 -0
  16. package/src/memory/index.ts +9 -0
  17. package/src/memory/place-cells.ts +279 -0
  18. package/src/memory/spatial-memory.ts +375 -0
  19. package/src/navigation/index.ts +1 -0
  20. package/src/navigation/pathfinding.ts +403 -0
  21. package/src/perception/camera.ts +249 -0
  22. package/src/perception/index.ts +2 -0
  23. package/src/types/index.ts +416 -0
  24. package/src/utils/crypto.ts +94 -0
  25. package/src/utils/index.ts +2 -0
  26. package/src/utils/math.ts +204 -0
  27. package/src/verification/index.ts +9 -0
  28. package/src/verification/spatial-proof.ts +442 -0
  29. package/tests/antispoofing/detector.test.ts +196 -0
  30. package/tests/gamification/badges.test.ts +163 -0
  31. package/tests/gamification/fleet-leaderboard.test.ts +181 -0
  32. package/tests/gamification/streaks.test.ts +158 -0
  33. package/tests/gamification/trust-tiers.test.ts +165 -0
  34. package/tests/gamification/zone-mastery.test.ts +143 -0
  35. package/tests/memory/place-cells.test.ts +128 -0
  36. package/tests/stress/load.test.ts +499 -0
  37. package/tests/stress/security.test.ts +378 -0
  38. package/tests/stress/simulation.test.ts +361 -0
  39. package/tests/utils/crypto.test.ts +115 -0
  40. package/tests/utils/math.test.ts +195 -0
  41. package/tests/verification/spatial-proof.test.ts +299 -0
  42. package/tsconfig.json +26 -0
@@ -0,0 +1,416 @@
1
+ /**
2
+ * gridstamp — Type definitions
3
+ * Embodied spatial memory + payment verification for autonomous robots
4
+ */
5
+
6
+ // ============================================================
7
+ // GEOMETRY & SPATIAL PRIMITIVES
8
+ // ============================================================
9
+
10
+ /** 3D position in world coordinates (meters) */
11
+ export interface Vec3 {
12
+ readonly x: number;
13
+ readonly y: number;
14
+ readonly z: number;
15
+ }
16
+
17
+ /** Quaternion rotation (unit quaternion, ||q|| = 1) */
18
+ export interface Quaternion {
19
+ readonly w: number;
20
+ readonly x: number;
21
+ readonly y: number;
22
+ readonly z: number;
23
+ }
24
+
25
+ /** 6-DOF pose: position + orientation */
26
+ export interface Pose {
27
+ readonly position: Vec3;
28
+ readonly orientation: Quaternion;
29
+ readonly timestamp: number; // Unix ms
30
+ }
31
+
32
+ /** 4x4 transformation matrix (row-major) */
33
+ export type Mat4 = readonly [
34
+ number, number, number, number,
35
+ number, number, number, number,
36
+ number, number, number, number,
37
+ number, number, number, number,
38
+ ];
39
+
40
+ /** Axis-aligned bounding box */
41
+ export interface AABB {
42
+ readonly min: Vec3;
43
+ readonly max: Vec3;
44
+ }
45
+
46
+ // ============================================================
47
+ // CAMERA & PERCEPTION
48
+ // ============================================================
49
+
50
+ /** Camera intrinsic parameters */
51
+ export interface CameraIntrinsics {
52
+ readonly fx: number; // focal length x (pixels)
53
+ readonly fy: number; // focal length y (pixels)
54
+ readonly cx: number; // principal point x
55
+ readonly cy: number; // principal point y
56
+ readonly width: number;
57
+ readonly height: number;
58
+ readonly distortion?: readonly number[]; // radial + tangential coefficients
59
+ }
60
+
61
+ /** Stereo camera baseline */
62
+ export interface StereoConfig {
63
+ readonly baseline: number; // meters between cameras
64
+ readonly intrinsics: CameraIntrinsics;
65
+ readonly minDepth: number; // meters
66
+ readonly maxDepth: number; // meters
67
+ }
68
+
69
+ /** Raw camera frame with metadata */
70
+ export interface CameraFrame {
71
+ readonly id: string;
72
+ readonly timestamp: number;
73
+ readonly rgb: Uint8Array; // RGB pixel data
74
+ readonly width: number;
75
+ readonly height: number;
76
+ readonly depth?: Float32Array; // depth map in meters
77
+ readonly pose?: Pose; // camera pose at capture time
78
+ readonly hmac?: string; // HMAC-SHA256 signature
79
+ readonly sequenceNumber: number; // monotonic counter for replay detection
80
+ }
81
+
82
+ /** Depth map with confidence */
83
+ export interface DepthMap {
84
+ readonly data: Float32Array;
85
+ readonly width: number;
86
+ readonly height: number;
87
+ readonly minDepth: number;
88
+ readonly maxDepth: number;
89
+ readonly confidence?: Float32Array; // per-pixel confidence [0,1]
90
+ }
91
+
92
+ /** Camera hardware abstraction */
93
+ export enum CameraType {
94
+ OAK_D_PRO = 'oak-d-pro',
95
+ OAK_D_LONG_RANGE = 'oak-d-lr',
96
+ OAK_4_D_PRO = 'oak-4-d-pro',
97
+ REALSENSE_D455 = 'realsense-d455',
98
+ ZED_2I = 'zed-2i',
99
+ SIMULATED = 'simulated',
100
+ }
101
+
102
+ export interface CameraConfig {
103
+ readonly type: CameraType;
104
+ readonly role: 'foveal' | 'peripheral';
105
+ readonly stereo: StereoConfig;
106
+ readonly fps: number;
107
+ readonly autoExposure: boolean;
108
+ }
109
+
110
+ // ============================================================
111
+ // 3D GAUSSIAN SPLATTING
112
+ // ============================================================
113
+
114
+ /**
115
+ * Single 3D Gaussian splat (59 parameters)
116
+ * Position (3) + Covariance/Scale (3) + Rotation (4) + Opacity (1)
117
+ * + SH coefficients (48 for degree 3)
118
+ */
119
+ export interface GaussianSplat {
120
+ readonly position: Vec3;
121
+ readonly scale: Vec3; // log-scale
122
+ readonly rotation: Quaternion;
123
+ readonly opacity: number; // sigmoid-activated, [0,1]
124
+ readonly shCoeffs: Float32Array; // spherical harmonics (48 floats for degree 3)
125
+ }
126
+
127
+ /** Gaussian splat scene (collection of splats) */
128
+ export interface SplatScene {
129
+ readonly id: string;
130
+ readonly splats: GaussianSplat[];
131
+ readonly count: number;
132
+ readonly boundingBox: AABB;
133
+ readonly createdAt: number;
134
+ readonly merkleRoot?: string; // SHA-256 Merkle root of splat data
135
+ }
136
+
137
+ /** Rendered view from a splat scene */
138
+ export interface RenderedView {
139
+ readonly rgb: Uint8Array;
140
+ readonly depth: Float32Array;
141
+ readonly width: number;
142
+ readonly height: number;
143
+ readonly pose: Pose;
144
+ readonly renderTimeMs: number;
145
+ }
146
+
147
+ // ============================================================
148
+ // SPATIAL MEMORY (3-TIER)
149
+ // ============================================================
150
+
151
+ export enum MemoryTier {
152
+ SHORT = 'short', // 1M splats, 30Hz live, ~30s window
153
+ MID = 'mid', // 100K splats, episodic, minutes-hours
154
+ LONG = 'long', // 10K/room, Merkle-signed, persistent
155
+ }
156
+
157
+ /** Short-term memory entry (live perception) */
158
+ export interface ShortTermEntry {
159
+ readonly frame: CameraFrame;
160
+ readonly splats: GaussianSplat[];
161
+ readonly timestamp: number;
162
+ readonly expiresAt: number; // auto-evict after TTL
163
+ }
164
+
165
+ /** Mid-term episodic memory */
166
+ export interface EpisodicMemory {
167
+ readonly id: string;
168
+ readonly scene: SplatScene;
169
+ readonly location: Vec3;
170
+ readonly timestamp: number;
171
+ readonly tags: readonly string[]; // semantic labels
172
+ readonly confidence: number; // [0,1] how reliable
173
+ }
174
+
175
+ /** Long-term persistent memory (Merkle-signed) */
176
+ export interface LongTermMemory {
177
+ readonly id: string;
178
+ readonly roomId: string;
179
+ readonly scene: SplatScene;
180
+ readonly merkleRoot: string;
181
+ readonly merkleProof: readonly string[];
182
+ readonly signature: string; // HMAC-SHA256
183
+ readonly createdAt: number;
184
+ readonly lastVerified: number;
185
+ readonly splatCount: number;
186
+ }
187
+
188
+ /** Memory consolidation event (short → mid → long) */
189
+ export interface ConsolidationEvent {
190
+ readonly from: MemoryTier;
191
+ readonly to: MemoryTier;
192
+ readonly entryCount: number;
193
+ readonly compressionRatio: number;
194
+ readonly timestamp: number;
195
+ }
196
+
197
+ // ============================================================
198
+ // PLACE CELLS & GRID CELLS (Bio-inspired navigation)
199
+ // ============================================================
200
+
201
+ /** Place cell — fires at specific location (O'Keefe, 1971) */
202
+ export interface PlaceCell {
203
+ readonly id: string;
204
+ readonly center: Vec3; // preferred location
205
+ readonly radius: number; // firing field radius (meters)
206
+ readonly peakRate: number; // max firing rate (Hz)
207
+ activation(position: Vec3): number; // Gaussian falloff [0,1]
208
+ }
209
+
210
+ /** Grid cell — hexagonal tiling (Moser & Moser, 2005) */
211
+ export interface GridCell {
212
+ readonly id: string;
213
+ readonly spacing: number; // grid period (meters)
214
+ readonly orientation: number; // grid orientation (radians)
215
+ readonly phase: Vec3; // phase offset
216
+ activation(position: Vec3): number; // periodic activation [0,1]
217
+ }
218
+
219
+ /** Spatial code — combined place + grid cell population vector */
220
+ export interface SpatialCode {
221
+ readonly placeCellActivations: ReadonlyMap<string, number>;
222
+ readonly gridCellActivations: ReadonlyMap<string, number>;
223
+ readonly estimatedPosition: Vec3;
224
+ readonly confidence: number;
225
+ readonly timestamp: number;
226
+ }
227
+
228
+ // ============================================================
229
+ // NAVIGATION
230
+ // ============================================================
231
+
232
+ export enum PathAlgorithm {
233
+ A_STAR = 'a-star',
234
+ RRT_STAR = 'rrt-star',
235
+ }
236
+
237
+ export enum ReferenceFrame {
238
+ EGOCENTRIC = 'ego', // robot-centered
239
+ ALLOCENTRIC = 'allo', // world-centered
240
+ }
241
+
242
+ /** Navigation waypoint */
243
+ export interface Waypoint {
244
+ readonly position: Vec3;
245
+ readonly orientation?: Quaternion;
246
+ readonly speed?: number; // m/s
247
+ readonly tolerance: number; // meters
248
+ }
249
+
250
+ /** Planned path */
251
+ export interface Path {
252
+ readonly id: string;
253
+ readonly waypoints: readonly Waypoint[];
254
+ readonly algorithm: PathAlgorithm;
255
+ readonly totalDistance: number; // meters
256
+ readonly estimatedTime: number; // seconds
257
+ readonly cost: number; // path cost metric
258
+ readonly collisionFree: boolean;
259
+ readonly createdAt: number;
260
+ }
261
+
262
+ // ============================================================
263
+ // SPATIAL VERIFICATION & PAYMENT
264
+ // ============================================================
265
+
266
+ /** Spatial similarity metrics */
267
+ export interface SpatialMetrics {
268
+ readonly ssim: number; // Structural Similarity [0,1]
269
+ readonly lpips: number; // Learned Perceptual Image Patch Similarity [0,1] (lower = more similar)
270
+ readonly depthMAE: number; // Depth Mean Absolute Error (meters)
271
+ readonly composite: number; // Weighted composite score [0,1]
272
+ }
273
+
274
+ /** Verification thresholds */
275
+ export interface VerificationThresholds {
276
+ readonly minSSIM: number; // default 0.75
277
+ readonly maxLPIPS: number; // default 0.25
278
+ readonly maxDepthMAE: number; // default 0.5 meters
279
+ readonly minComposite: number; // default 0.75
280
+ }
281
+
282
+ /** Spatial proof — cryptographic proof that robot is at claimed location */
283
+ export interface SpatialProof {
284
+ readonly id: string;
285
+ readonly robotId: string;
286
+ readonly claimedPose: Pose;
287
+ readonly actualFrame: CameraFrame;
288
+ readonly expectedRender: RenderedView;
289
+ readonly metrics: SpatialMetrics;
290
+ readonly passed: boolean;
291
+ readonly memoryMerkleRoot: string; // ties to long-term memory
292
+ readonly merkleProof: readonly string[];
293
+ readonly timestamp: number;
294
+ readonly signature: string; // HMAC-SHA256 of proof payload
295
+ readonly nonce: string; // replay prevention
296
+ readonly hardwareAttestation?: string; // device identity
297
+ }
298
+
299
+ /** Payment settlement tied to spatial proof */
300
+ export interface SpatialSettlement {
301
+ readonly id: string;
302
+ readonly proof: SpatialProof;
303
+ readonly amount: number;
304
+ readonly currency: string;
305
+ readonly status: SettlementStatus;
306
+ readonly payerRobotId: string;
307
+ readonly payeeId: string;
308
+ readonly initiatedAt: number;
309
+ readonly settledAt?: number;
310
+ readonly failureReason?: string;
311
+ }
312
+
313
+ export enum SettlementStatus {
314
+ PENDING = 'pending',
315
+ VERIFIED = 'verified',
316
+ SETTLED = 'settled',
317
+ FAILED = 'failed',
318
+ DISPUTED = 'disputed',
319
+ }
320
+
321
+ // ============================================================
322
+ // ANTI-SPOOFING
323
+ // ============================================================
324
+
325
+ export enum ThreatType {
326
+ REPLAY_ATTACK = 'replay',
327
+ ADVERSARIAL_PATCH = 'adversarial-patch',
328
+ DEPTH_INJECTION = 'depth-injection',
329
+ MEMORY_POISONING = 'memory-poisoning',
330
+ CAMERA_TAMPERING = 'camera-tampering',
331
+ MAN_IN_THE_MIDDLE = 'mitm',
332
+ }
333
+
334
+ export enum ThreatSeverity {
335
+ LOW = 'low',
336
+ MEDIUM = 'medium',
337
+ HIGH = 'high',
338
+ CRITICAL = 'critical',
339
+ }
340
+
341
+ /** Detected threat */
342
+ export interface ThreatDetection {
343
+ readonly type: ThreatType;
344
+ readonly severity: ThreatSeverity;
345
+ readonly confidence: number; // [0,1]
346
+ readonly details: string;
347
+ readonly frameId?: string;
348
+ readonly timestamp: number;
349
+ readonly mitigationApplied: boolean;
350
+ }
351
+
352
+ /** Frame integrity check result */
353
+ export interface FrameIntegrity {
354
+ readonly frameId: string;
355
+ readonly hmacValid: boolean;
356
+ readonly sequenceValid: boolean; // no gaps in sequence numbers
357
+ readonly timingValid: boolean; // within expected jitter bounds
358
+ readonly threats: readonly ThreatDetection[];
359
+ }
360
+
361
+ // ============================================================
362
+ // AGENT API (top-level)
363
+ // ============================================================
364
+
365
+ export interface GridStampConfig {
366
+ readonly robotId: string;
367
+ readonly cameras: readonly CameraConfig[];
368
+ readonly hmacSecret: string; // MUST be provided, no defaults
369
+ readonly verificationThresholds?: Partial<VerificationThresholds>;
370
+ readonly memoryConfig?: {
371
+ readonly shortTermTTL?: number; // ms, default 30000
372
+ readonly midTermMaxEntries?: number; // default 1000
373
+ readonly longTermStoragePath?: string;
374
+ };
375
+ readonly navigationConfig?: {
376
+ readonly defaultAlgorithm?: PathAlgorithm;
377
+ readonly maxPlanningTime?: number; // ms
378
+ readonly safetyMargin?: number; // meters
379
+ };
380
+ }
381
+
382
+ /** Main agent interface */
383
+ export interface GridStampAgent {
384
+ /** Capture and process current camera view */
385
+ see(): Promise<CameraFrame>;
386
+
387
+ /** Store current spatial context to memory */
388
+ remember(tags?: string[]): Promise<EpisodicMemory>;
389
+
390
+ /** Plan and execute navigation to target */
391
+ navigate(target: Vec3, options?: { algorithm?: PathAlgorithm }): Promise<Path>;
392
+
393
+ /** Verify robot is at claimed location via spatial proof */
394
+ verifySpatial(claimedPose?: Pose): Promise<SpatialProof>;
395
+
396
+ /** Settle payment with spatial proof requirement */
397
+ settle(params: {
398
+ amount: number;
399
+ currency: string;
400
+ payeeId: string;
401
+ spatialProof: boolean;
402
+ }): Promise<SpatialSettlement>;
403
+
404
+ /** Get current spatial code (place + grid cell activations) */
405
+ getSpatialCode(): SpatialCode;
406
+
407
+ /** Get memory statistics */
408
+ getMemoryStats(): {
409
+ shortTerm: { count: number; oldestMs: number };
410
+ midTerm: { count: number; totalSplats: number };
411
+ longTerm: { count: number; rooms: number };
412
+ };
413
+
414
+ /** Shutdown and persist state */
415
+ shutdown(): Promise<void>;
416
+ }
@@ -0,0 +1,94 @@
1
+ /**
2
+ * Cryptographic utilities for GridStamp
3
+ * HMAC-SHA256 frame signing, nonce generation, constant-time comparison
4
+ */
5
+ import { createHmac, createHash, randomBytes, timingSafeEqual } from 'node:crypto';
6
+
7
+ /**
8
+ * Sign data with HMAC-SHA256
9
+ * Used for: frame signing, memory signatures, spatial proof signing
10
+ */
11
+ export function hmacSign(data: Buffer | Uint8Array, secret: string): string {
12
+ if (!secret || secret.length < 32) {
13
+ throw new Error('HMAC secret must be at least 32 characters');
14
+ }
15
+ return createHmac('sha256', secret)
16
+ .update(data)
17
+ .digest('hex');
18
+ }
19
+
20
+ /**
21
+ * Verify HMAC-SHA256 signature (constant-time to prevent timing attacks)
22
+ */
23
+ export function hmacVerify(
24
+ data: Buffer | Uint8Array,
25
+ signature: string,
26
+ secret: string,
27
+ ): boolean {
28
+ const expected = hmacSign(data, secret);
29
+ if (expected.length !== signature.length) return false;
30
+ return timingSafeEqual(
31
+ Buffer.from(expected, 'hex'),
32
+ Buffer.from(signature, 'hex'),
33
+ );
34
+ }
35
+
36
+ /**
37
+ * Sign a camera frame's pixel data + metadata
38
+ * Includes timestamp and sequence number to prevent replay
39
+ */
40
+ export function signFrame(
41
+ rgb: Uint8Array,
42
+ timestamp: number,
43
+ sequenceNumber: number,
44
+ secret: string,
45
+ ): string {
46
+ const header = Buffer.alloc(16);
47
+ header.writeDoubleBE(timestamp, 0);
48
+ header.writeDoubleBE(sequenceNumber, 8);
49
+ const payload = Buffer.concat([header, Buffer.from(rgb)]);
50
+ return hmacSign(payload, secret);
51
+ }
52
+
53
+ /**
54
+ * Verify a signed frame
55
+ */
56
+ export function verifyFrame(
57
+ rgb: Uint8Array,
58
+ timestamp: number,
59
+ sequenceNumber: number,
60
+ signature: string,
61
+ secret: string,
62
+ ): boolean {
63
+ const header = Buffer.alloc(16);
64
+ header.writeDoubleBE(timestamp, 0);
65
+ header.writeDoubleBE(sequenceNumber, 8);
66
+ const payload = Buffer.concat([header, Buffer.from(rgb)]);
67
+ return hmacVerify(payload, signature, secret);
68
+ }
69
+
70
+ /**
71
+ * Generate cryptographically secure nonce (hex string)
72
+ */
73
+ export function generateNonce(bytes: number = 32): string {
74
+ return randomBytes(bytes).toString('hex');
75
+ }
76
+
77
+ /**
78
+ * SHA-256 hash of arbitrary data
79
+ */
80
+ export function sha256(data: Buffer | Uint8Array | string): string {
81
+ return createHash('sha256')
82
+ .update(typeof data === 'string' ? Buffer.from(data) : data)
83
+ .digest('hex');
84
+ }
85
+
86
+ /**
87
+ * Derive a sub-key from master secret (for key separation)
88
+ * Different keys for frame signing vs memory signing vs proof signing
89
+ */
90
+ export function deriveKey(masterSecret: string, context: string): string {
91
+ return createHmac('sha256', masterSecret)
92
+ .update(`gridstamp:${context}`)
93
+ .digest('hex');
94
+ }
@@ -0,0 +1,2 @@
1
+ export * from './crypto.js';
2
+ export * from './math.js';