guardrail-ship 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 (119) hide show
  1. package/dist/index.d.ts +7 -0
  2. package/dist/index.d.ts.map +1 -0
  3. package/dist/index.js +7 -0
  4. package/dist/index.js.map +1 -0
  5. package/dist/mock-implementation.d.ts +1 -0
  6. package/dist/mock-implementation.d.ts.map +1 -0
  7. package/dist/mock-implementation.js +2 -0
  8. package/dist/mock-implementation.js.map +1 -0
  9. package/dist/mockproof/__tests__/import-graph-scanner.test.d.ts +5 -0
  10. package/dist/mockproof/__tests__/import-graph-scanner.test.d.ts.map +1 -0
  11. package/dist/mockproof/__tests__/import-graph-scanner.test.js +92 -0
  12. package/dist/mockproof/__tests__/import-graph-scanner.test.js.map +1 -0
  13. package/dist/mockproof/import-graph-scanner.d.ts +93 -0
  14. package/dist/mockproof/import-graph-scanner.d.ts.map +1 -0
  15. package/dist/mockproof/import-graph-scanner.js +411 -0
  16. package/dist/mockproof/import-graph-scanner.js.map +1 -0
  17. package/dist/mockproof/index.d.ts +10 -0
  18. package/dist/mockproof/index.d.ts.map +1 -0
  19. package/dist/mockproof/index.js +10 -0
  20. package/dist/mockproof/index.js.map +1 -0
  21. package/dist/reality-mode/auth-enforcer.d.ts +13 -0
  22. package/dist/reality-mode/auth-enforcer.d.ts.map +1 -0
  23. package/dist/reality-mode/auth-enforcer.js +90 -0
  24. package/dist/reality-mode/auth-enforcer.js.map +1 -0
  25. package/dist/reality-mode/explorer/critical-flows.d.ts +71 -0
  26. package/dist/reality-mode/explorer/critical-flows.d.ts.map +1 -0
  27. package/dist/reality-mode/explorer/critical-flows.js +463 -0
  28. package/dist/reality-mode/explorer/critical-flows.js.map +1 -0
  29. package/dist/reality-mode/explorer/flow-parser.d.ts +52 -0
  30. package/dist/reality-mode/explorer/flow-parser.d.ts.map +1 -0
  31. package/dist/reality-mode/explorer/flow-parser.js +250 -0
  32. package/dist/reality-mode/explorer/flow-parser.js.map +1 -0
  33. package/dist/reality-mode/explorer/index.d.ts +11 -0
  34. package/dist/reality-mode/explorer/index.d.ts.map +1 -0
  35. package/dist/reality-mode/explorer/index.js +11 -0
  36. package/dist/reality-mode/explorer/index.js.map +1 -0
  37. package/dist/reality-mode/explorer/runtime-explorer.d.ts +35 -0
  38. package/dist/reality-mode/explorer/runtime-explorer.d.ts.map +1 -0
  39. package/dist/reality-mode/explorer/runtime-explorer.js +688 -0
  40. package/dist/reality-mode/explorer/runtime-explorer.js.map +1 -0
  41. package/dist/reality-mode/explorer/surface-discovery.d.ts +60 -0
  42. package/dist/reality-mode/explorer/surface-discovery.d.ts.map +1 -0
  43. package/dist/reality-mode/explorer/surface-discovery.js +357 -0
  44. package/dist/reality-mode/explorer/surface-discovery.js.map +1 -0
  45. package/dist/reality-mode/explorer/types.d.ts +275 -0
  46. package/dist/reality-mode/explorer/types.d.ts.map +1 -0
  47. package/dist/reality-mode/explorer/types.js +8 -0
  48. package/dist/reality-mode/explorer/types.js.map +1 -0
  49. package/dist/reality-mode/fake-success-detector.d.ts +10 -0
  50. package/dist/reality-mode/fake-success-detector.d.ts.map +1 -0
  51. package/dist/reality-mode/fake-success-detector.js +76 -0
  52. package/dist/reality-mode/fake-success-detector.js.map +1 -0
  53. package/dist/reality-mode/index.d.ts +14 -0
  54. package/dist/reality-mode/index.d.ts.map +1 -0
  55. package/dist/reality-mode/index.js +14 -0
  56. package/dist/reality-mode/index.js.map +1 -0
  57. package/dist/reality-mode/reality-scanner.d.ts +48 -0
  58. package/dist/reality-mode/reality-scanner.d.ts.map +1 -0
  59. package/dist/reality-mode/reality-scanner.js +516 -0
  60. package/dist/reality-mode/reality-scanner.js.map +1 -0
  61. package/dist/reality-mode/report-generator.d.ts +11 -0
  62. package/dist/reality-mode/report-generator.d.ts.map +1 -0
  63. package/dist/reality-mode/report-generator.js +233 -0
  64. package/dist/reality-mode/report-generator.js.map +1 -0
  65. package/dist/reality-mode/traffic-classifier.d.ts +14 -0
  66. package/dist/reality-mode/traffic-classifier.d.ts.map +1 -0
  67. package/dist/reality-mode/traffic-classifier.js +131 -0
  68. package/dist/reality-mode/traffic-classifier.js.map +1 -0
  69. package/dist/reality-mode/types.d.ts +90 -0
  70. package/dist/reality-mode/types.d.ts.map +1 -0
  71. package/dist/reality-mode/types.js +2 -0
  72. package/dist/reality-mode/types.js.map +1 -0
  73. package/dist/ship-badge/__tests__/ship-badge-generator.test.d.ts +5 -0
  74. package/dist/ship-badge/__tests__/ship-badge-generator.test.d.ts.map +1 -0
  75. package/dist/ship-badge/__tests__/ship-badge-generator.test.js +146 -0
  76. package/dist/ship-badge/__tests__/ship-badge-generator.test.js.map +1 -0
  77. package/dist/ship-badge/index.d.ts +9 -0
  78. package/dist/ship-badge/index.d.ts.map +1 -0
  79. package/dist/ship-badge/index.js +9 -0
  80. package/dist/ship-badge/index.js.map +1 -0
  81. package/dist/ship-badge/ship-badge-generator.d.ts +136 -0
  82. package/dist/ship-badge/ship-badge-generator.d.ts.map +1 -0
  83. package/dist/ship-badge/ship-badge-generator.js +681 -0
  84. package/dist/ship-badge/ship-badge-generator.js.map +1 -0
  85. package/package.json +20 -0
  86. package/src/index.ts +7 -0
  87. package/src/mock-implementation.ts +0 -0
  88. package/src/mockproof/__tests__/import-graph-scanner.test.ts +115 -0
  89. package/src/mockproof/import-graph-scanner.d.ts +93 -0
  90. package/src/mockproof/import-graph-scanner.d.ts.map +1 -0
  91. package/src/mockproof/import-graph-scanner.js +482 -0
  92. package/src/mockproof/import-graph-scanner.ts +540 -0
  93. package/src/mockproof/index.ts +18 -0
  94. package/src/reality-mode/auth-enforcer.ts +97 -0
  95. package/src/reality-mode/explorer/critical-flows.ts +504 -0
  96. package/src/reality-mode/explorer/flow-parser.ts +293 -0
  97. package/src/reality-mode/explorer/index.ts +22 -0
  98. package/src/reality-mode/explorer/runtime-explorer.ts +715 -0
  99. package/src/reality-mode/explorer/surface-discovery.ts +498 -0
  100. package/src/reality-mode/explorer/templates/example-flows/auth-flow.yaml +41 -0
  101. package/src/reality-mode/explorer/templates/example-flows/checkout-flow.yaml +66 -0
  102. package/src/reality-mode/explorer/templates/example-flows/contact-form.yaml +43 -0
  103. package/src/reality-mode/explorer/templates/github-action.yml +132 -0
  104. package/src/reality-mode/explorer/types.ts +356 -0
  105. package/src/reality-mode/fake-success-detector.ts +89 -0
  106. package/src/reality-mode/index.ts +19 -0
  107. package/src/reality-mode/reality-scanner.d.ts +123 -0
  108. package/src/reality-mode/reality-scanner.d.ts.map +1 -0
  109. package/src/reality-mode/reality-scanner.js +526 -0
  110. package/src/reality-mode/reality-scanner.ts +576 -0
  111. package/src/reality-mode/report-generator.ts +253 -0
  112. package/src/reality-mode/traffic-classifier.ts +169 -0
  113. package/src/reality-mode/types.ts +95 -0
  114. package/src/ship-badge/__tests__/ship-badge-generator.test.ts +162 -0
  115. package/src/ship-badge/index.ts +16 -0
  116. package/src/ship-badge/ship-badge-generator.d.ts +136 -0
  117. package/src/ship-badge/ship-badge-generator.d.ts.map +1 -0
  118. package/src/ship-badge/ship-badge-generator.js +779 -0
  119. package/src/ship-badge/ship-badge-generator.ts +873 -0
@@ -0,0 +1,516 @@
1
+ /**
2
+ * Reality Mode - Runtime Fake Detection
3
+ *
4
+ * "Stop shipping pretend features. Guardrail runs your app and catches the lies."
5
+ *
6
+ * This module spins up the app, intercepts network calls, clicks through the UI,
7
+ * and detects:
8
+ * - Calls to localhost, jsonplaceholder, staging domains, ngrok
9
+ * - Routes returning demo/placeholder responses
10
+ * - Silent fallback success patterns
11
+ * - Mock billing and fake invoice IDs
12
+ *
13
+ * The killer feature: a "flight recorder" replay showing exactly what happened.
14
+ */
15
+ import { TrafficClassifier } from "./traffic-classifier";
16
+ import { FakeSuccessDetector } from "./fake-success-detector";
17
+ import { AuthEnforcer } from "./auth-enforcer";
18
+ // Export constants that are used in the generated test
19
+ export const FAKE_DOMAIN_PATTERNS = [
20
+ /localhost:\d+/i,
21
+ /127\.0\.0\.1:\d+/i,
22
+ /jsonplaceholder\.typicode\.com/i,
23
+ /reqres\.in/i,
24
+ /mockapi\.io/i,
25
+ /mocky\.io/i,
26
+ /httpbin\.org/i,
27
+ /\.ngrok\.io/i,
28
+ /\.ngrok-free\.app/i,
29
+ /staging\./i,
30
+ /\.local\//i,
31
+ /\.test\//i,
32
+ /api\.example\.com/i,
33
+ /fake\.api/i,
34
+ /demo\.api/i,
35
+ ];
36
+ export const FAKE_RESPONSE_PATTERNS = [
37
+ { pattern: /inv_demo_/i, name: "Demo invoice ID" },
38
+ { pattern: /user_demo_/i, name: "Demo user ID" },
39
+ { pattern: /cus_demo_/i, name: "Demo customer ID" },
40
+ { pattern: /sub_demo_/i, name: "Demo subscription ID" },
41
+ { pattern: /sk_test_/i, name: "Test Stripe key" },
42
+ { pattern: /pk_test_/i, name: "Test Stripe public key" },
43
+ { pattern: /"success":\s*true.*"demo"/i, name: "Demo success response" },
44
+ { pattern: /lorem\s+ipsum/i, name: "Lorem ipsum placeholder" },
45
+ { pattern: /john\.doe|jane\.doe/i, name: "Placeholder name" },
46
+ { pattern: /user@example\.com/i, name: "Placeholder email" },
47
+ { pattern: /placeholder\.(com|jpg|png)/i, name: "Placeholder domain/image" },
48
+ {
49
+ pattern: /"id":\s*("demo"|"test"|"fake"|1234567890)/i,
50
+ name: "Fake ID pattern",
51
+ },
52
+ { pattern: /"status":\s*"simulated"/i, name: "Simulated status" },
53
+ { pattern: /"mock":\s*true/i, name: "Mock flag enabled" },
54
+ { pattern: /"isDemo":\s*true/i, name: "Demo mode flag" },
55
+ ];
56
+ export const SILENT_FALLBACK_PATTERNS = [
57
+ {
58
+ pattern: /"error":\s*null.*"data":\s*\[\]/i,
59
+ name: "Empty success on error",
60
+ },
61
+ {
62
+ pattern: /catch.*return\s*\{\s*success:\s*true/i,
63
+ name: "Success on catch",
64
+ },
65
+ { pattern: /"fallback":\s*true/i, name: "Fallback flag" },
66
+ ];
67
+ export const DEFAULT_FAKE_PATTERNS = [
68
+ // Fake domain patterns
69
+ {
70
+ id: "fake-api-domain",
71
+ name: "Mock Backend (Domain)",
72
+ description: "Request to a mock/staging/localhost API domain",
73
+ severity: "critical",
74
+ detect: (item) => {
75
+ if (item.type !== "request")
76
+ return false;
77
+ return FAKE_DOMAIN_PATTERNS.some((p) => p.test(item.url));
78
+ },
79
+ },
80
+ // Demo response patterns
81
+ {
82
+ id: "demo-response-data",
83
+ name: "Mock Backend (Data)",
84
+ description: "Response contains demo/placeholder data",
85
+ severity: "critical",
86
+ detect: (item) => {
87
+ if (item.type !== "response" || !item.body)
88
+ return false;
89
+ return FAKE_RESPONSE_PATTERNS.some(({ pattern }) => pattern.test(item.body));
90
+ },
91
+ },
92
+ // Silent fallback
93
+ {
94
+ id: "silent-fallback-success",
95
+ name: "Fake Success (Fallback)",
96
+ description: "Code silently returns success on error (catch returns default)",
97
+ severity: "warning",
98
+ detect: (item) => {
99
+ if (item.type !== "response" || !item.body)
100
+ return false;
101
+ return SILENT_FALLBACK_PATTERNS.some(({ pattern }) => pattern.test(item.body));
102
+ },
103
+ },
104
+ // HTTP status checks
105
+ {
106
+ id: "mock-status-code",
107
+ name: "Mock Backend (Status)",
108
+ description: "Response with unusual status indicating mock (418, 999)",
109
+ severity: "warning",
110
+ detect: (item) => {
111
+ if (item.type !== "response")
112
+ return false;
113
+ return [418, 999, 0].includes(item.status);
114
+ },
115
+ },
116
+ // Test keys in production
117
+ {
118
+ id: "test-api-keys",
119
+ name: "Security Risk (Test Keys)",
120
+ description: "Test/demo API keys detected in request or response",
121
+ severity: "critical",
122
+ detect: (item) => {
123
+ const content = item.type === "request"
124
+ ? JSON.stringify(item.headers) + (item.body || "")
125
+ : item.body || "";
126
+ return /sk_test_|pk_test_|api_key_test|demo_api_key/i.test(content);
127
+ },
128
+ },
129
+ // Billing simulation
130
+ {
131
+ id: "simulated-billing",
132
+ name: "Mock Backend (Billing)",
133
+ description: "Billing/payment response appears to be simulated",
134
+ severity: "critical",
135
+ detect: (item) => {
136
+ if (item.type !== "response" || !item.body)
137
+ return false;
138
+ const billingUrls = /stripe|billing|payment|checkout|subscription/i;
139
+ const isBillingEndpoint = billingUrls.test(item.url);
140
+ const hasDemoData = /demo|test|simulate|fake|mock/i.test(item.body);
141
+ return isBillingEndpoint && hasDemoData;
142
+ },
143
+ },
144
+ ];
145
+ export class RealityScanner {
146
+ config;
147
+ trafficClassifier;
148
+ fakeSuccessDetector;
149
+ authEnforcer;
150
+ constructor(config = {}) {
151
+ this.config = {
152
+ timeout: 30000,
153
+ patterns: DEFAULT_FAKE_PATTERNS,
154
+ screenshotOnDetection: true,
155
+ headless: true,
156
+ checkAuth: true,
157
+ ...config,
158
+ };
159
+ this.trafficClassifier = new TrafficClassifier(this.config.patterns || DEFAULT_FAKE_PATTERNS);
160
+ this.fakeSuccessDetector = new FakeSuccessDetector();
161
+ this.authEnforcer = new AuthEnforcer();
162
+ }
163
+ /**
164
+ * Generate Playwright test code for Reality Mode scanning
165
+ */
166
+ generatePlaywrightTest(config) {
167
+ const { baseUrl, clickPaths, outputDir } = config;
168
+ const authTestCode = this.config.checkAuth
169
+ ? this.authEnforcer.generateAuthCheckTest({ baseUrl, outputDir })
170
+ : "";
171
+ return `/**
172
+ * Reality Mode - Auto-generated Playwright Test
173
+ *
174
+ * This test runs your app and intercepts all network calls to detect fake data.
175
+ * Generated by Guardrail Reality Mode.
176
+ */
177
+
178
+ import { test, expect, Page, Request, Response } from '@playwright/test';
179
+ import * as fs from 'fs';
180
+ import * as path from 'path';
181
+
182
+ const FAKE_DOMAIN_PATTERNS = ${JSON.stringify(FAKE_DOMAIN_PATTERNS.map((r) => r.source), null, 2)};
183
+
184
+ const FAKE_RESPONSE_PATTERNS = ${JSON.stringify(FAKE_RESPONSE_PATTERNS, null, 2)};
185
+
186
+ interface Detection {
187
+ type: string;
188
+ severity: 'critical' | 'warning';
189
+ url: string;
190
+ evidence: string;
191
+ timestamp: number;
192
+ }
193
+
194
+ interface ReplayStep {
195
+ timestamp: number;
196
+ type: 'request' | 'response' | 'action' | 'console';
197
+ data: any;
198
+ detections: Detection[];
199
+ screenshot?: string;
200
+ }
201
+
202
+ test.describe('Reality Mode Scan', () => {
203
+ let detections: Detection[] = [];
204
+ let replay: ReplayStep[] = [];
205
+
206
+ test.beforeEach(async ({ page }) => {
207
+ detections = [];
208
+ replay = [];
209
+
210
+ // Capture console logs
211
+ page.on('console', msg => {
212
+ replay.push({
213
+ timestamp: Date.now(),
214
+ type: 'console',
215
+ data: { type: msg.type(), text: msg.text() },
216
+ detections: []
217
+ });
218
+ });
219
+
220
+ // Intercept all network requests
221
+ page.on('request', (request: Request) => {
222
+ const url = request.url();
223
+ // Skip static assets to reduce noise
224
+ if (url.match(/\\.(js|css|png|jpg|svg|ico|woff|woff2|ttf)$/)) return;
225
+
226
+ const step: ReplayStep = {
227
+ timestamp: Date.now(),
228
+ type: 'request',
229
+ data: { url, method: request.method(), headers: request.headers() },
230
+ detections: []
231
+ };
232
+
233
+ // Check for fake domains
234
+ for (const pattern of FAKE_DOMAIN_PATTERNS) {
235
+ if (new RegExp(pattern, 'i').test(url)) {
236
+ const detection: Detection = {
237
+ type: 'fake-api-domain',
238
+ severity: 'critical',
239
+ url,
240
+ evidence: \`URL matches fake domain pattern: \${pattern}\`,
241
+ timestamp: Date.now()
242
+ };
243
+ step.detections.push(detection);
244
+ detections.push(detection);
245
+ }
246
+ }
247
+
248
+ replay.push(step);
249
+ });
250
+
251
+ page.on('response', async (response: Response) => {
252
+ const url = response.url();
253
+ if (url.match(/\\.(js|css|png|jpg|svg|ico|woff|woff2|ttf)$/)) return;
254
+
255
+ let body = '';
256
+
257
+ try {
258
+ body = await response.text();
259
+ } catch (e) {
260
+ // Some responses can't be read
261
+ }
262
+
263
+ const step: ReplayStep = {
264
+ timestamp: Date.now(),
265
+ type: 'response',
266
+ data: { url, status: response.status(), bodyPreview: body.slice(0, 500) },
267
+ detections: []
268
+ };
269
+
270
+ // Check for demo data patterns
271
+ for (const { pattern, name } of FAKE_RESPONSE_PATTERNS) {
272
+ if (new RegExp(pattern.source || pattern, 'i').test(body)) {
273
+ const detection: Detection = {
274
+ type: 'demo-response-data',
275
+ severity: 'critical',
276
+ url,
277
+ evidence: \`Response contains \${name}\`,
278
+ timestamp: Date.now()
279
+ };
280
+ step.detections.push(detection);
281
+ detections.push(detection);
282
+ }
283
+ }
284
+
285
+ replay.push(step);
286
+ });
287
+ });
288
+
289
+ test('should detect fake data in production flow', async ({ page }) => {
290
+ // Navigate to the app
291
+ await page.goto('${baseUrl}');
292
+
293
+ // Initial screenshot
294
+ const initScreenshot = \`init-\${Date.now()}.png\`;
295
+ const outputDir = '${outputDir.replace(/\\/g, "\\\\")}';
296
+ if (!fs.existsSync(outputDir)) fs.mkdirSync(outputDir, { recursive: true });
297
+
298
+ await page.screenshot({ path: path.join(outputDir, initScreenshot) });
299
+
300
+ replay.push({
301
+ timestamp: Date.now(),
302
+ type: 'action',
303
+ data: { type: 'navigation', url: '${baseUrl}' },
304
+ detections: [],
305
+ screenshot: initScreenshot
306
+ });
307
+
308
+ // Execute click paths
309
+ const clickPaths = ${JSON.stringify(clickPaths, null, 4)};
310
+
311
+ for (const path of clickPaths) {
312
+ for (const selector of path) {
313
+ try {
314
+ await page.waitForSelector(selector, { timeout: 5000 });
315
+ await page.click(selector);
316
+
317
+ // Wait for network activity to settle
318
+ await page.waitForLoadState('networkidle', { timeout: 5000 }).catch(() => {});
319
+
320
+ // Take screenshot after action
321
+ const stepScreenshot = \`step-\${Date.now()}.png\`;
322
+ await page.screenshot({ path: path.join(outputDir, stepScreenshot) });
323
+
324
+ replay.push({
325
+ timestamp: Date.now(),
326
+ type: 'action',
327
+ data: { type: 'click', selector },
328
+ detections: [],
329
+ screenshot: stepScreenshot
330
+ });
331
+
332
+ } catch (e) {
333
+ // Selector not found, skip
334
+ }
335
+ }
336
+ }
337
+
338
+ // Save raw replay data for post-analysis
339
+ fs.writeFileSync(
340
+ path.join(outputDir, 'reality-replay.json'),
341
+ JSON.stringify(replay, null, 2)
342
+ );
343
+
344
+ // Fail if critical fake data detected (NO-GO)
345
+ // Warnings do NOT fail the build (GO/WARN)
346
+ const criticalIssues = detections.filter(d => d.severity === 'critical');
347
+
348
+ if (criticalIssues.length > 0) {
349
+ console.log(\`\\n 🛑 NO-GO: Found \${criticalIssues.length} critical reality issues.\`);
350
+ criticalIssues.forEach(d => console.log(\` - \${d.evidence} (\${d.url})\`));
351
+ }
352
+
353
+ expect(criticalIssues.length, \`Found \${criticalIssues.length} critical fake data issues\`).toBe(0);
354
+ });
355
+
356
+ ${authTestCode}
357
+ });
358
+ `;
359
+ }
360
+ /**
361
+ * Post-process the replay to apply advanced detection logic
362
+ */
363
+ processReplay(replay, authViolations = []) {
364
+ const trafficAnalysis = [];
365
+ const fakeSuccessResults = this.fakeSuccessDetector.detect(replay);
366
+ const detections = [];
367
+ // 1. Analyze Traffic (Green/Yellow/Red)
368
+ const responseHistory = new Map(); // url -> body hash/content
369
+ let hasMutation = false;
370
+ for (const step of replay) {
371
+ if (step.type === "request") {
372
+ const req = {
373
+ type: "request",
374
+ url: step.data.url,
375
+ method: step.data.method,
376
+ headers: step.data.headers || {},
377
+ timestamp: step.timestamp,
378
+ };
379
+ if (["POST", "PUT", "PATCH", "DELETE"].includes(req.method)) {
380
+ hasMutation = true;
381
+ }
382
+ // Find corresponding response? (Simplification: analyze request independently first)
383
+ const classification = this.trafficClassifier.classify(req);
384
+ trafficAnalysis.push(classification);
385
+ // Convert classifier reasons to detections
386
+ if (classification.verdict === "red") {
387
+ detections.push({
388
+ pattern: {
389
+ id: "traffic-classifier-red",
390
+ name: "Fake Traffic",
391
+ description: classification.reasons.join(", "),
392
+ severity: "critical",
393
+ detect: () => true,
394
+ },
395
+ request: req,
396
+ timestamp: step.timestamp,
397
+ evidence: classification.reasons.join(", "),
398
+ });
399
+ }
400
+ }
401
+ else if (step.type === "response") {
402
+ const res = {
403
+ type: "response",
404
+ url: step.data.url,
405
+ status: step.data.status,
406
+ headers: {},
407
+ body: step.data.bodyPreview,
408
+ timestamp: step.timestamp,
409
+ };
410
+ const classification = this.trafficClassifier.classify({
411
+ type: "request",
412
+ url: res.url,
413
+ method: "GET",
414
+ headers: {},
415
+ timestamp: 0,
416
+ }, res);
417
+ trafficAnalysis.push(classification);
418
+ if (classification.verdict === "red") {
419
+ detections.push({
420
+ pattern: {
421
+ id: "traffic-classifier-red-res",
422
+ name: "Fake Response",
423
+ description: classification.reasons.join(", "),
424
+ severity: "critical",
425
+ detect: () => true,
426
+ },
427
+ response: res,
428
+ timestamp: step.timestamp,
429
+ evidence: classification.reasons.join(", "),
430
+ });
431
+ }
432
+ // Consistency Check (Fake Mutation)
433
+ // If we have seen this URL before, and there was a mutation, the body should ideally change
434
+ if (hasMutation &&
435
+ responseHistory.has(res.url) &&
436
+ responseHistory.get(res.url) === res.body) {
437
+ // Ignore static assets/config
438
+ if (!res.url.includes("/config") &&
439
+ !res.url.includes("/me") &&
440
+ !res.url.includes(".json")) {
441
+ const warning = {
442
+ verdict: "yellow",
443
+ score: 70,
444
+ reasons: [
445
+ `Data for ${res.url} did not change after a write operation (Fake Mutation?)`,
446
+ ],
447
+ };
448
+ trafficAnalysis.push(warning);
449
+ }
450
+ }
451
+ responseHistory.set(res.url, res.body || "");
452
+ }
453
+ }
454
+ // 2. Score Calculation
455
+ let score = 100;
456
+ score -= detections.length * 10;
457
+ score -= fakeSuccessResults.filter((f) => f.isFake).length * 20;
458
+ score -= authViolations.length * 25; // Auth violations are heavy penalties
459
+ // Penalize Red Traffic (Mock Backend / No-Wire)
460
+ const redTraffic = trafficAnalysis.filter((t) => t.verdict === "red");
461
+ score -= redTraffic.length * 15;
462
+ score = Math.max(0, score);
463
+ const verdict = score > 80 ? "real" : score > 50 ? "suspicious" : "fake";
464
+ return {
465
+ verdict,
466
+ score,
467
+ detections,
468
+ replay,
469
+ trafficAnalysis,
470
+ fakeSuccessAnalysis: fakeSuccessResults,
471
+ authViolations,
472
+ summary: {
473
+ totalRequests: replay.filter((r) => r.type === "request").length,
474
+ fakeRequests: detections.length + redTraffic.length,
475
+ totalActions: replay.filter((r) => r.type === "action").length,
476
+ criticalIssues: detections.length +
477
+ redTraffic.length +
478
+ fakeSuccessResults.filter((f) => f.isFake).length +
479
+ authViolations.length,
480
+ warnings: fakeSuccessResults.filter((f) => f.isFake).length,
481
+ },
482
+ timestamp: new Date().toISOString(),
483
+ duration: 0,
484
+ };
485
+ }
486
+ generateReport(result) {
487
+ // This is now handled by ReportGenerator, but we keep a simple string version for console output if needed
488
+ return `Reality Check Complete. Score: ${result.score}/100. Verdict: ${result.verdict.toUpperCase()}`;
489
+ }
490
+ generateDefaultClickPaths() {
491
+ return [
492
+ // 1. Login / Auth Flow
493
+ [
494
+ 'input[name="email"]',
495
+ 'input[name="password"]',
496
+ 'button[type="submit"]',
497
+ '[data-testid="login-submit"]',
498
+ ],
499
+ // 2. Dashboard Access
500
+ ['[href*="/dashboard"]', '[data-testid="nav-dashboard"]'],
501
+ // 3. View Report/Runs
502
+ ['[href*="/runs"]', '[href*="/reports"]', '[data-testid="view-report"]'],
503
+ // 4. Open Findings/Details
504
+ ['[data-testid="finding-item"]', 'tr[role="row"]'],
505
+ // 5. Settings / Configuration (Write actions often live here)
506
+ [
507
+ '[href*="/settings"]',
508
+ '[data-testid="nav-settings"]',
509
+ 'button:has-text("Save")',
510
+ '[data-testid="save-changes"]',
511
+ ],
512
+ ];
513
+ }
514
+ }
515
+ export const realityScanner = new RealityScanner();
516
+ //# sourceMappingURL=reality-scanner.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"reality-scanner.js","sourceRoot":"","sources":["../../src/reality-mode/reality-scanner.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,11 @@
1
+ import { RealityModeResult } from "./types";
2
+ export declare class ReportGenerator {
3
+ generateHtml(result: RealityModeResult): string;
4
+ private getBrandedChip;
5
+ private renderDetections;
6
+ private renderFakeSuccess;
7
+ private renderTrafficAnalysis;
8
+ private renderAuthViolations;
9
+ private renderReplayStep;
10
+ }
11
+ //# sourceMappingURL=report-generator.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"report-generator.d.ts","sourceRoot":"","sources":["../../src/reality-mode/report-generator.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,iBAAiB,EAAE,MAAM,SAAS,CAAC;AAE5C,qBAAa,eAAe;IAC1B,YAAY,CAAC,MAAM,EAAE,iBAAiB,GAAG,MAAM;IAmG/C,OAAO,CAAC,cAAc;IAetB,OAAO,CAAC,gBAAgB;IA2BxB,OAAO,CAAC,iBAAiB;IAqBzB,OAAO,CAAC,qBAAqB;IA2B7B,OAAO,CAAC,oBAAoB;IAwB5B,OAAO,CAAC,gBAAgB;CAoCzB"}