The AI trust layer between agents: identity, agreements, safeguards, and outcome intelligence for A2A.

Download ZIP
apps/dashboard/src/preview.ts 1130 lines · 36.2 KB · typescript
1
export const previewKey = 'openclasp.preview.v1';
2
3
export const previewSession = {
4
  user: {
5
    sub: 'local-preview',
6
    name: 'Local preview',
7
    email: 'preview@localhost',
8
  },
9
};
10
11
export type DashboardData = {
12
  agents: Record<string, any>[];
13
  projects: Record<string, any>[];
14
  installations: Record<string, any>[];
15
  setupRequests: Record<string, any>[];
16
  publications: Record<string, any>[];
17
  interactions: Record<string, any>[];
18
  federatedInteractions: Record<string, any>[];
19
  liveSessions: Record<string, any>[];
20
  events: Record<string, any>[];
21
  conflicts: Record<string, any>[];
22
  receipts: Record<string, any>[];
23
  profiles: Record<string, any>[];
24
  counterpartyBriefs: Record<string, any>[];
25
  completionReports: Record<string, any>[];
26
  feedbackRequests: Record<string, any>[];
27
  interactionFeedback: Record<string, any>[];
28
  interactionConclusions: Record<string, any>[];
29
  learningEligibility: Record<string, any>[];
30
  profileDeltas: Record<string, any>[];
31
  intelligenceSummaries: Record<string, any>[];
32
  runtimes: Record<string, any>[];
33
  accessTokens: Record<string, any>[];
34
  assuranceAssessments: Record<string, any>[];
35
  assurancePredictions: Record<string, any>[];
36
  assuranceSafeguards: Record<string, any>[];
37
  assuranceEvaluations: Record<string, any>[];
38
  assuranceProbePlans: Record<string, any>[];
39
  assuranceProbeResponses: Record<string, any>[];
40
  shieldCases: Record<string, any>[];
41
  shieldConsultations: Record<string, any>[];
42
  shieldOutcomes: Record<string, any>[];
43
};
44
45
export type Settings = {
46
  displayName: string;
47
  contributionEnabled: boolean;
48
  rawConversationsStored: false;
49
};
50
51
export const defaultPreviewSettings: Settings = {
52
  displayName: 'Local operator',
53
  contributionEnabled: false,
54
  rawConversationsStored: false,
55
};
56
57
const ago = (minutes: number) => new Date(Date.now() - minutes * 60_000).toISOString();
58
const ahead = (minutes: number) => new Date(Date.now() + minutes * 60_000).toISOString();
59
60
export function createPreviewData(): DashboardData {
61
  return {
62
    projects: [
63
      { projectId: 'proj_ops', name: 'Operations', createdAt: ago(21 * 24 * 60) },
64
      { projectId: 'proj_research', name: 'Research', createdAt: ago(12 * 24 * 60) },
65
    ],
66
    agents: [
67
      {
68
        agentId: 'agent_atlas',
69
        projectId: 'proj_research',
70
        name: 'Atlas Research',
71
        description: 'Literature review and planning',
72
        framework: 'Claude',
73
        agentVersion: '1.4.2',
74
        agentMode: 'persistent_runtime',
75
        a2aEndpoint: 'https://atlas.example.com/a2a',
76
        autoPublish: true,
77
        autoAcceptPolicy: 'safe_matching',
78
        autoAcceptTaskCategories: ['research', 'planning'],
79
        capabilities: ['research', 'planning', 'summarization'],
80
        limitations: ['no payments'],
81
        identityMode: 'oauth_installation',
82
        status: 'active',
83
        createdAt: ago(12 * 24 * 60),
84
        updatedAt: ago(8),
85
        presence: { status: 'online', lastSeenAt: ago(1) },
86
      },
87
      {
88
        agentId: 'agent_harbor',
89
        projectId: 'proj_ops',
90
        name: 'Harbor Ops',
91
        description: 'Incident triage and runbooks',
92
        framework: 'GPT',
93
        agentVersion: '2.1.0',
94
        agentMode: 'persistent_runtime',
95
        autoPublish: false,
96
        autoAcceptPolicy: 'off',
97
        autoAcceptTaskCategories: [],
98
        capabilities: ['ops', 'triage'],
99
        limitations: ['no production writes'],
100
        identityMode: 'oauth_installation',
101
        status: 'active',
102
        createdAt: ago(21 * 24 * 60),
103
        updatedAt: ago(180),
104
        presence: { status: 'offline', lastSeenAt: ago(180) },
105
      },
106
    ],
107
    installations: [
108
      {
109
        installationId: 'inst_atlas',
110
        clientId: 'mcp_atlas',
111
        agentId: 'agent_atlas',
112
        projectId: 'proj_research',
113
        connectedAt: ago(12 * 24 * 60),
114
        updatedAt: ago(8),
115
      },
116
    ],
117
    setupRequests: [
118
      {
119
        requestId: 'setup_lumen',
120
        clientId: 'mcp_lumen',
121
        action: 'connect',
122
        status: 'pending',
123
        agentName: 'Lumen Writer',
124
        projectName: 'Content',
125
        framework: 'Claude',
126
        agentVersion: '0.9.0',
127
        autoPublish: true,
128
        autoAcceptPolicy: 'safe_matching',
129
        autoAcceptTaskCategories: ['writing', 'editing'],
130
        capabilities: ['writing', 'editing', 'research'],
131
        limitations: ['no outbound email'],
132
        requestedAt: ago(18),
133
      },
134
    ],
135
    publications: [{ agentId: 'agent_atlas', published: true, updatedAt: ago(40) }],
136
    interactions: [
137
      {
138
        interactionId: 'ix_local_brief',
139
        agentId: 'agent_atlas',
140
        status: 'completed',
141
        contract: {
142
          purpose: 'Produce a source-backed research brief',
143
          taskCategory: 'research',
144
        },
145
        createdAt: ago(240),
146
        completedAt: ago(220),
147
      },
148
    ],
149
    federatedInteractions: [
150
      {
151
        interactionId: 'ix_shared_review',
152
        initiatorAgentId: 'agent_peer_nova',
153
        responderAgentId: 'agent_atlas',
154
        status: 'pending',
155
        termsHash: '7f3c91a0b2e84d11c6aa09f1d3e8b470',
156
        contractRevision: 1,
157
        createdAt: ago(26),
158
        contract: {
159
          purpose: 'Review a research brief for scope and sources',
160
          taskCategory: 'research',
161
          parties: ['agent_peer_nova', 'agent_atlas'],
162
        },
163
        contractRevisions: [
164
          {
165
            revisionId: '17c3a10b-2e84-4d11-86aa-09f1d3e8b470',
166
            revision: 1,
167
            termsHash: '7f3c91a0b2e84d11c6aa09f1d3e8b470',
168
            proposedByAgentId: 'agent_peer_nova',
169
            status: 'proposed',
170
            acceptances: { agent_peer_nova: { method: 'oauth_installation' } },
171
          },
172
        ],
173
      },
174
      {
175
        interactionId: 'ix_shared_ops',
176
        initiatorAgentId: 'agent_atlas',
177
        responderAgentId: 'agent_peer_keel',
178
        status: 'active',
179
        termsHash: '12ab44c0e91f77d0aa3310bc44ee9012',
180
        contractRevision: 1,
181
        createdAt: ago(90),
182
        contract: {
183
          purpose: 'Share a sanitized incident timeline',
184
          taskCategory: 'coordination',
185
          parties: ['agent_atlas', 'agent_peer_keel'],
186
        },
187
        acceptances: {
188
          agent_peer_keel: { method: 'policy_auto_accept' },
189
        },
190
        contractRevisions: [
191
          {
192
            revisionId: '22ab44c0-e91f-47d0-aa33-10bc44ee9012',
193
            revision: 1,
194
            termsHash: '12ab44c0e91f77d0aa3310bc44ee9012',
195
            proposedByAgentId: 'agent_atlas',
196
            status: 'accepted',
197
            acceptances: {
198
              agent_atlas: { method: 'oauth_installation' },
199
              agent_peer_keel: { method: 'policy_auto_accept' },
200
            },
201
          },
202
        ],
203
      },
204
    ],
205
    liveSessions: [
206
      {
207
        interactionId: 'ix_shared_ops',
208
        initiatorAgentId: 'agent_atlas',
209
        responderAgentId: 'agent_peer_keel',
210
        status: 'active',
211
        createdAt: ago(88),
212
        activatedAt: ago(87),
213
        expiresAt: ahead(12),
214
      },
215
    ],
216
    events: [
217
      {
218
        eventId: 'evt_1',
219
        eventType: 'interaction_started',
220
        agentId: 'agent_atlas',
221
        interactionId: 'ix_shared_ops',
222
        timestamp: ago(88),
223
        visibility: 'participants',
224
      },
225
      {
226
        eventId: 'evt_2',
227
        eventType: 'policy_warning',
228
        agentId: 'agent_harbor',
229
        interactionId: 'ix_local_brief',
230
        timestamp: ago(200),
231
        visibility: 'owner',
232
      },
233
      {
234
        eventId: 'evt_3',
235
        eventType: 'claim_checked',
236
        agentId: 'agent_atlas',
237
        interactionId: 'ix_local_brief',
238
        timestamp: ago(230),
239
        visibility: 'participants',
240
      },
241
      {
242
        eventId: 'evt_4',
243
        eventType: 'session_activated',
244
        agentId: 'agent_atlas',
245
        interactionId: 'ix_shared_ops',
246
        timestamp: ago(87),
247
        visibility: 'participants',
248
      },
249
    ],
250
    conflicts: [
251
      {
252
        conflictId: 'dsp_1',
253
        interactionId: 'ix_local_brief',
254
        status: 'open',
255
        createdAt: ago(190),
256
      },
257
    ],
258
    receipts: [
259
      {
260
        receiptId: 'rcpt_1',
261
        interactionId: 'ix_local_brief',
262
        agentId: 'agent_atlas',
263
        outcome: 'success',
264
        completedAt: ago(220),
265
      },
266
      {
267
        receiptId: 'rcpt_ops_provisional',
268
        interactionId: 'ix_shared_ops',
269
        outcome: 'partial',
270
        unilateral: true,
271
        provisional: true,
272
        confidence: 0.42,
273
        completedAt: ago(12),
274
      },
275
    ],
276
    counterpartyBriefs: [
277
      {
278
        briefId: 'brief_1',
279
        interactionId: 'ix_local_brief',
280
        recipientAgentId: 'agent_atlas',
281
        subjectAgentId: 'agent_peer_nova',
282
        decision: 'CHALLENGE',
283
        relevantSampleSize: 3,
284
        historyConfidence: 0.38,
285
        requirements: [
286
          { requirement: 'Provide source evidence', status: 'partial', confidence: 0.7 },
287
        ],
288
        generatedAt: ago(241),
289
      },
290
    ],
291
    completionReports: [
292
      {
293
        reportId: 'report_1',
294
        interactionId: 'ix_local_brief',
295
        reportingAgentId: 'agent_atlas',
296
        counterpartyAgentId: 'agent_peer_nova',
297
        outcome: 'success',
298
        summary: 'Research brief delivered with sources and scope notes.',
299
        criteria: [{ criterion: 'Brief delivered', status: 'met' }],
300
        completedAt: ago(222),
301
      },
302
      {
303
        reportId: 'report_2',
304
        interactionId: 'ix_local_brief',
305
        reportingAgentId: 'agent_peer_nova',
306
        counterpartyAgentId: 'agent_atlas',
307
        outcome: 'success',
308
        summary: 'Received and accepted the requested brief.',
309
        criteria: [{ criterion: 'Brief delivered', status: 'met' }],
310
        completedAt: ago(221),
311
      },
312
      {
313
        reportId: 'report_ops_1',
314
        interactionId: 'ix_shared_ops',
315
        reportingAgentId: 'agent_atlas',
316
        counterpartyAgentId: 'agent_peer_keel',
317
        outcome: 'partial',
318
        summary:
319
          'The requester ended after the peer stopped responding before the task was complete.',
320
        criteria: [{ criterion: 'Timeline shared', status: 'partially_met' }],
321
        confidence: 0.7,
322
        completedAt: ago(12),
323
      },
324
    ],
325
    feedbackRequests: [
326
      {
327
        requestId: 'feedback_request_1',
328
        interactionId: 'ix_local_brief',
329
        reviewerAgentId: 'agent_atlas',
330
        subjectAgentId: 'agent_peer_nova',
331
        status: 'submitted',
332
        requestedAt: ago(221),
333
        dueAt: ago(197),
334
      },
335
      {
336
        requestId: 'feedback_request_ops_1',
337
        interactionId: 'ix_shared_ops',
338
        reviewerAgentId: 'agent_atlas',
339
        subjectAgentId: 'agent_peer_keel',
340
        status: 'pending',
341
        requestedAt: ago(12),
342
        dueAt: ahead(24 * 60 - 12),
343
      },
344
      {
345
        requestId: 'feedback_request_ops_2',
346
        interactionId: 'ix_shared_ops',
347
        reviewerAgentId: 'agent_peer_keel',
348
        subjectAgentId: 'agent_atlas',
349
        status: 'pending',
350
        requestedAt: ago(12),
351
        dueAt: ahead(24 * 60 - 12),
352
      },
353
      {
354
        requestId: 'feedback_request_2',
355
        interactionId: 'ix_local_brief',
356
        reviewerAgentId: 'agent_peer_nova',
357
        subjectAgentId: 'agent_atlas',
358
        status: 'submitted',
359
        requestedAt: ago(221),
360
        dueAt: ago(197),
361
      },
362
    ],
363
    interactionFeedback: [
364
      {
365
        feedbackId: 'feedback_1',
366
        interactionId: 'ix_local_brief',
367
        reviewerAgentId: 'agent_atlas',
368
        subjectAgentId: 'agent_peer_nova',
369
        ratings: { outcome_satisfaction: 0.9, communication: 0.8, reliability: 0.9 },
370
        wouldWorkAgain: 'yes',
371
        submittedAt: ago(219),
372
      },
373
    ],
374
    interactionConclusions: [
375
      {
376
        conclusionId: 'conclusion_1',
377
        interactionId: 'ix_local_brief',
378
        outcome: 'success',
379
        consensus: 'bilateral_agreement',
380
        summary: 'Both agents reported successful delivery and acceptance.',
381
        criteria: [{ criterion: 'Brief delivered', status: 'met' }],
382
        averageRatings: { outcome_satisfaction: 0.88, communication: 0.82, reliability: 0.9 },
383
        generatedAt: ago(218),
384
      },
385
      {
386
        conclusionId: 'conclusion_ops_provisional',
387
        interactionId: 'ix_shared_ops',
388
        outcome: 'partial',
389
        consensus: 'unilateral',
390
        lifecycle: 'provisional',
391
        confidence: 0.42,
392
        missingReportAgentIds: ['agent_peer_keel'],
393
        pendingFeedbackAgentIds: ['agent_atlas', 'agent_peer_keel'],
394
        peerReportStatus: 'awaiting',
395
        summary:
396
          'Provisional one-sided outcome: the requester ended after the peer stopped responding before the task was complete.',
397
        criteria: [{ criterion: 'Timeline shared', status: 'partially_met' }],
398
        reportIds: ['report_ops_1'],
399
        averageRatings: {},
400
        generatedAt: ago(11),
401
      },
402
    ],
403
    learningEligibility: [
404
      {
405
        decisionId: 'eligibility_1',
406
        interactionId: 'ix_local_brief',
407
        eligible: true,
408
        sampleWeight: 0.87,
409
        contributionMode: 'local_only',
410
        structuredDataOnly: true,
411
        reasons: ['Bilateral reports provide outcome corroboration'],
412
        decidedAt: ago(218),
413
      },
414
    ],
415
    profileDeltas: [
416
      {
417
        deltaId: 'delta_1',
418
        interactionId: 'ix_local_brief',
419
        agentId: 'agent_atlas',
420
        agentVersion: '1.4.2',
421
        taskCategory: 'research',
422
        sampleWeight: 0.87,
423
        dimensionDeltas: { completion: 0.02, evidence: 0.03, communication: -0.01 },
424
        appliedAt: ago(218),
425
      },
426
    ],
427
    profiles: [
428
      {
429
        agentId: 'agent_atlas',
430
        taskCategory: 'research',
431
        agentVersion: '1.4.2',
432
        sampleSize: 14,
433
        effectiveSampleSize: 10.8,
434
        dimensionSampleSizes: {
435
          completion: 10.8,
436
          acceptance: 8.9,
437
          specification: 10.1,
438
          deadline: 9.4,
439
          communication: 10.8,
440
          evidence: 9.7,
441
          scope: 10.2,
442
          correction: 5.1,
443
          limitations: 4.4,
444
          disputes: 10.8,
445
        },
446
        updatedAt: ago(218),
447
        completion: 0.92,
448
        acceptance: 0.87,
449
        specification: 0.86,
450
        scope: 0.84,
451
        evidence: 0.88,
452
        communication: 0.79,
453
        deadline: 0.9,
454
        correction: 0.82,
455
        limitations: 0.77,
456
        disputes: 0.08,
457
      },
458
      {
459
        agentId: 'agent_harbor',
460
        taskCategory: 'ops',
461
        agentVersion: '2.1.0',
462
        sampleSize: 6,
463
        effectiveSampleSize: 4.1,
464
        dimensionSampleSizes: {
465
          completion: 4.1,
466
          acceptance: 3.2,
467
          specification: 3.8,
468
          deadline: 3.5,
469
          communication: 4.1,
470
          evidence: 3.9,
471
          scope: 3.7,
472
          correction: 1.8,
473
          limitations: 1.2,
474
          disputes: 4.1,
475
        },
476
        updatedAt: ago(3 * 24 * 60),
477
        completion: 0.71,
478
        acceptance: 0.68,
479
        specification: 0.63,
480
        scope: 0.66,
481
        evidence: 0.58,
482
        communication: 0.74,
483
        deadline: 0.62,
484
        correction: 0.69,
485
        limitations: 0.54,
486
        disputes: 0.22,
487
      },
488
    ],
489
    intelligenceSummaries: [
490
      {
491
        agentId: 'agent_atlas',
492
        agentVersion: '1.4.2',
493
        taskCategory: 'research',
494
        score: 0.86,
495
        confidence: {
496
          level: 'high',
497
          value: 0.72,
498
          evidenceCount: 14,
499
          effectiveSampleSize: 10.8,
500
        },
501
        trend: { direction: 'improving', delta: 0.018 },
502
        strengths: [
503
          { dimension: 'completion', score: 0.92 },
504
          { dimension: 'deadline', score: 0.9 },
505
          { dimension: 'evidence', score: 0.88 },
506
        ],
507
        risks: [],
508
        versionStatus: {
509
          currentVersion: '1.4.2',
510
          evidenceVersion: '1.4.2',
511
          status: 'current',
512
        },
513
        source: 'private_verified_history',
514
        updatedAt: ago(218),
515
      },
516
      {
517
        agentId: 'agent_harbor',
518
        agentVersion: '2.1.0',
519
        taskCategory: 'ops',
520
        score: 0.66,
521
        confidence: {
522
          level: 'medium',
523
          value: 0.49,
524
          evidenceCount: 6,
525
          effectiveSampleSize: 4.1,
526
        },
527
        trend: { direction: 'declining', delta: -0.022 },
528
        strengths: [{ dimension: 'communication', score: 0.74 }],
529
        risks: [
530
          {
531
            dimension: 'evidence',
532
            score: 0.58,
533
            reason: 'Claims are not consistently supported by evidence.',
534
          },
535
        ],
536
        versionStatus: {
537
          currentVersion: '2.1.0',
538
          evidenceVersion: '2.1.0',
539
          status: 'current',
540
        },
541
        source: 'private_verified_history',
542
        updatedAt: ago(3 * 24 * 60),
543
      },
544
    ],
545
    runtimes: [
546
      {
547
        agentId: 'agent_atlas',
548
        endpoint: 'https://atlas.example.com/openclasp',
549
        a2aEndpoint: 'https://atlas.example.com/a2a',
550
        status: 'verified',
551
        verifiedAt: ago(40),
552
      },
553
    ],
554
    accessTokens: [],
555
    shieldCases: [
556
      {
557
        protocolVersion: '0.1',
558
        caseId: '77777777-7777-4777-8777-777777777777',
559
        agentId: 'agent_atlas',
560
        title: 'Unverified refund exception',
561
        goal: 'Resolve a refund request without bypassing the approved exception policy.',
562
        brief: 'The customer says a manager promised a full refund, but no approval is visible.',
563
        proposedAction: 'Issue a $500 refund',
564
        counterparty: { type: 'human' },
565
        status: 'awaiting_input',
566
        riskTier: 'high',
567
        facts: [],
568
        evidence: [],
569
        policies: [
570
          {
571
            policyId: '88888888-8888-4888-8888-888888888888',
572
            title: 'Refund approval',
573
            statement: 'Refunds outside the standard window require recorded manager approval.',
574
          },
575
        ],
576
        ownerGuidance: [],
577
        latestConsultationId: '99999999-9999-4999-8999-999999999999',
578
        latestDisposition: 'gather_evidence',
579
        createdAt: ago(32),
580
        updatedAt: ago(28),
581
      },
582
    ],
583
    shieldConsultations: [
584
      {
585
        protocolVersion: '0.1',
586
        consultationId: '99999999-9999-4999-8999-999999999999',
587
        caseId: '77777777-7777-4777-8777-777777777777',
588
        agentId: 'agent_atlas',
589
        inputDigest: 'aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa',
590
        analysis: {
591
          reply:
592
            'Do not issue the refund yet. The manager promise is material but currently unsupported. Check the CRM and offline approval notes, then request supervisor approval if no record exists.',
593
          situationSummary: 'A refund exception depends on an unverified manager authorization.',
594
          disposition: 'gather_evidence',
595
          riskTier: 'high',
596
          confidence: 0.78,
597
          rationale: [
598
            'The proposed refund is outside the normal policy.',
599
            'The claimed authorization is not backed by a system record.',
600
          ],
601
          claims: [],
602
          manipulationSignals: [],
603
          missingEvidence: ['Recorded manager authorization'],
604
          questionsToAsk: ['What approval reference or representative name can be verified?'],
605
          nextSteps: ['Search approval records', 'Escalate if no authoritative record exists'],
606
          safeguards: ['Require supervisor approval'],
607
        },
608
        generation: {
609
          mode: 'ai',
610
          model: 'anthropic/claude-sonnet-5',
611
          promptVersion: 'shield-agent-v1',
612
        },
613
        createdAt: ago(28),
614
      },
615
    ],
616
    shieldOutcomes: [],
617
    assuranceAssessments: [
618
      {
619
        assessmentId: '11111111-1111-4111-8111-111111111111',
620
        interactionId: 'ix_shared_ops',
621
        phase: 'pre_task',
622
        round: 1,
623
        generatedForAgentId: 'agent_atlas',
624
        targetAgentId: 'agent_peer_keel',
625
        targetAgentVersion: '1.2.0',
626
        selectedProbeId: '22222222-2222-4222-8222-222222222222',
627
        risks: [
628
          {
629
            riskCode: 'evidence_delivery',
630
            title: 'Evidence delivery is unproven',
631
            likelihood: 0.42,
632
            impact: 0.76,
633
          },
634
          {
635
            riskCode: 'tool_dependency',
636
            title: 'Required tool access may be unavailable',
637
            likelihood: 0.31,
638
            impact: 0.68,
639
          },
640
        ],
641
        generation: {
642
          mode: 'ai',
643
          model: 'anthropic/claude-sonnet-5',
644
          promptVersion: 'assurance-decision-v2',
645
        },
646
        createdAt: ago(84),
647
      },
648
    ],
649
    assurancePredictions: [
650
      {
651
        predictionId: '33333333-3333-4333-8333-333333333333',
652
        interactionId: 'ix_shared_ops',
653
        targetAgentId: 'agent_peer_keel',
654
        targetAgentVersion: '1.2.0',
655
        stage: 'baseline',
656
        successProbability: 0.64,
657
        confidence: 0.42,
658
        basis: 'cold_start_hybrid',
659
        sampleSize: 0,
660
        createdAt: ago(84),
661
      },
662
    ],
663
    assuranceSafeguards: [
664
      {
665
        safeguardId: '44444444-4444-4444-8444-444444444444',
666
        assessmentId: '11111111-1111-4111-8111-111111111111',
667
        interactionId: 'ix_shared_ops',
668
        safeguardCode: 'require_evidence',
669
        status: 'recommended',
670
        description: 'Require evidence references for every material claim.',
671
        rationale: 'The agreement requires an inspectable sanitized incident timeline.',
672
        expectedImpact: 0.1,
673
        createdAt: ago(84),
674
      },
675
    ],
676
    assuranceEvaluations: [],
677
    assuranceProbePlans: [
678
      {
679
        planId: '55555555-5555-4555-8555-555555555555',
680
        assessmentId: '11111111-1111-4111-8111-111111111111',
681
        interactionId: 'ix_shared_ops',
682
        round: 1,
683
        questions: [
684
          {
685
            probeId: '22222222-2222-4222-8222-222222222222',
686
            questionCode: 'evidence_capability',
687
            prompt: 'Can you return inspectable evidence for every material claim?',
688
          },
689
        ],
690
        generatedAt: ago(84),
691
      },
692
    ],
693
    assuranceProbeResponses: [],
694
  };
695
}
696
697
export function applyPreviewRequest(
698
  data: DashboardData,
699
  settings: Settings,
700
  path: string,
701
  init?: RequestInit,
702
): { data: DashboardData; settings: Settings; result: unknown } {
703
  const method = (init?.method ?? 'GET').toUpperCase();
704
  const body = init?.body ? (JSON.parse(String(init.body)) as Record<string, unknown>) : {};
705
706
  if (path === '/v0.1/dashboard' && method === 'GET') return { data, settings, result: data };
707
  if (path === '/v0.1/settings' && method === 'GET') return { data, settings, result: settings };
708
  if (path === '/v0.1/settings' && method === 'PUT') {
709
    const next = {
710
      ...settings,
711
      ...body,
712
      rawConversationsStored: false as const,
713
    } as Settings;
714
    return { data, settings: next, result: next };
715
  }
716
717
  if (path === '/v0.1/shield/cases' && method === 'POST') {
718
    const now = new Date().toISOString();
719
    const caseRecord = {
720
      protocolVersion: '0.1',
721
      caseId: crypto.randomUUID(),
722
      agentId: String(body.agentId),
723
      title: String(body.title),
724
      goal: String(body.goal),
725
      brief: String(body.brief ?? ''),
726
      ...(body.proposedAction ? { proposedAction: String(body.proposedAction) } : {}),
727
      counterparty: body.counterparty ?? { type: 'unknown' },
728
      status: 'open',
729
      riskTier: 'medium',
730
      facts: body.facts ?? [],
731
      evidence: body.evidence ?? [],
732
      policies:
733
        (body.policies as Record<string, any>[] | undefined)?.map((item) => ({
734
          policyId: crypto.randomUUID(),
735
          ...item,
736
        })) ?? [],
737
      ownerGuidance: [],
738
      createdAt: now,
739
      updatedAt: now,
740
    };
741
    return {
742
      data: { ...data, shieldCases: [caseRecord, ...data.shieldCases] },
743
      settings,
744
      result: caseRecord,
745
    };
746
  }
747
748
  const shieldConsult = path.match(/^\/v0\.1\/shield\/cases\/([^/]+)\/consult$/);
749
  if (shieldConsult && method === 'POST') {
750
    const caseId = decodeURIComponent(shieldConsult[1] ?? '');
751
    const selected = data.shieldCases.find((item) => item.caseId === caseId);
752
    const consultationId = crypto.randomUUID();
753
    const createdAt = new Date().toISOString();
754
    const consultation = {
755
      protocolVersion: '0.1',
756
      consultationId,
757
      caseId,
758
      agentId: selected?.agentId,
759
      inputDigest: 'aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa',
760
      analysis: {
761
        reply:
762
          'I would not treat the current claim as verified. Check the authoritative record, ask one targeted question, and require approval before any irreversible action.',
763
        situationSummary: 'Decision support requested with transient current-turn context.',
764
        disposition: 'gather_evidence',
765
        riskTier: 'high',
766
        confidence: 0.72,
767
        rationale: ['A material claim is not independently supported.'],
768
        claims: [],
769
        manipulationSignals: [],
770
        missingEvidence: ['Authoritative support for the requested exception'],
771
        questionsToAsk: ['What verifiable record supports this request?'],
772
        nextSteps: ['Check the system of record', 'Escalate if the exception remains unsupported'],
773
        safeguards: ['Require approval before acting'],
774
      },
775
      generation: {
776
        mode: 'ai',
777
        model: 'anthropic/claude-sonnet-5',
778
        promptVersion: 'shield-agent-v1',
779
      },
780
      createdAt,
781
    };
782
    const caseRecord = {
783
      ...selected,
784
      status: 'awaiting_input',
785
      riskTier: 'high',
786
      latestConsultationId: consultationId,
787
      latestDisposition: 'gather_evidence',
788
      updatedAt: createdAt,
789
    };
790
    return {
791
      data: {
792
        ...data,
793
        shieldCases: data.shieldCases.map((item) => (item.caseId === caseId ? caseRecord : item)),
794
        shieldConsultations: [...data.shieldConsultations, consultation],
795
      },
796
      settings,
797
      result: { caseRecord, consultation },
798
    };
799
  }
800
801
  const shieldGuidance = path.match(/^\/v0\.1\/shield\/cases\/([^/]+)\/guidance$/);
802
  if (shieldGuidance && method === 'POST') {
803
    const caseId = decodeURIComponent(shieldGuidance[1] ?? '');
804
    const guidance = {
805
      guidanceId: crypto.randomUUID(),
806
      instruction: String(body.instruction),
807
      scope: body.scope ?? 'case',
808
      createdAt: new Date().toISOString(),
809
    };
810
    const nextCases = data.shieldCases.map((item) =>
811
      item.caseId === caseId
812
        ? { ...item, ownerGuidance: [...(item.ownerGuidance ?? []), guidance] }
813
        : item,
814
    );
815
    return { data: { ...data, shieldCases: nextCases }, settings, result: nextCases };
816
  }
817
818
  const shieldClose = path.match(/^\/v0\.1\/shield\/cases\/([^/]+)\/close$/);
819
  if (shieldClose && method === 'POST') {
820
    const caseId = decodeURIComponent(shieldClose[1] ?? '');
821
    const selected = data.shieldCases.find((item) => item.caseId === caseId);
822
    const createdAt = new Date().toISOString();
823
    const outcome = {
824
      protocolVersion: '0.1',
825
      outcomeId: crypto.randomUUID(),
826
      caseId,
827
      agentId: selected?.agentId,
828
      result: body.result,
829
      acceptedAdvice: Boolean(body.acceptedAdvice),
830
      actionTaken: String(body.actionTaken),
831
      reportedBy: 'owner',
832
      createdAt,
833
    };
834
    return {
835
      data: {
836
        ...data,
837
        shieldCases: data.shieldCases.map((item) =>
838
          item.caseId === caseId
839
            ? { ...item, status: 'closed', updatedAt: createdAt, closedAt: createdAt }
840
            : item,
841
        ),
842
        shieldOutcomes: [...data.shieldOutcomes, outcome],
843
      },
844
      settings,
845
      result: outcome,
846
    };
847
  }
848
849
  if (path === '/v0.1/provider-connections/botpress' && method === 'POST') {
850
    const now = new Date();
851
    return {
852
      data,
853
      settings,
854
      result: {
855
        connectionId: crypto.randomUUID(),
856
        provider: 'botpress',
857
        agentName: String(body.agentName ?? 'Botpress agent'),
858
        status: 'pending',
859
        code: 'oc_bp_preview_pairing_code',
860
        createdAt: now.toISOString(),
861
        expiresAt: new Date(now.getTime() + 15 * 60_000).toISOString(),
862
      },
863
    };
864
  }
865
866
  if (path === '/v0.1/provider-connections' && method === 'POST') {
867
    const suffix = crypto.randomUUID();
868
    const projectName = String(body.projectName ?? 'Hosted agents');
869
    const existingProject = data.projects.find(
870
      (project) => String(project.name).toLowerCase() === projectName.toLowerCase(),
871
    );
872
    const project = existingProject ?? {
873
      projectId: `project_${suffix}`,
874
      name: projectName,
875
      createdAt: new Date().toISOString(),
876
    };
877
    const agentId = `agent_${suffix}`;
878
    const createdAt = new Date();
879
    const tokenId = suffix.replaceAll('-', '').slice(0, 16);
880
    const provider = body.provider === 'custom' ? 'custom' : 'botpress';
881
    const agent = {
882
      agentId,
883
      projectId: project.projectId,
884
      name: String(body.agentName ?? 'Botpress agent'),
885
      description: String(body.description ?? ''),
886
      framework: provider === 'botpress' ? 'Botpress' : 'Custom runtime',
887
      agentVersion: '1.0.0',
888
      agentMode: 'persistent_runtime',
889
      transport: 'direct_a2a',
890
      autoPublish: false,
891
      autoAcceptPolicy: 'off',
892
      autoAcceptTaskCategories: [],
893
      capabilities: body.capabilities ?? [],
894
      limitations: body.limitations ?? [],
895
      identityMode: 'owner_managed',
896
      status: 'active',
897
      createdAt: createdAt.toISOString(),
898
      updatedAt: createdAt.toISOString(),
899
      presence: { status: 'offline' },
900
    };
901
    const accessToken = {
902
      tokenId,
903
      token: `oc_at_${tokenId}.preview_agent_access_token_secret_not_for_production`,
904
      agentId,
905
      name: provider === 'botpress' ? 'Botpress' : 'Custom runtime',
906
      scopes: ['mcp:access', 'runtime:connect'],
907
      createdAt: createdAt.toISOString(),
908
      expiresAt: new Date(
909
        createdAt.getTime() + Number(body.expiresInDays ?? 365) * 86_400_000,
910
      ).toISOString(),
911
    };
912
    return {
913
      data: {
914
        ...data,
915
        projects: existingProject ? data.projects : [...data.projects, project],
916
        agents: [...data.agents, agent],
917
        accessTokens: [accessToken, ...data.accessTokens],
918
      },
919
      settings,
920
      result: { agent, project, provider, accessToken },
921
    };
922
  }
923
924
  const automation = path.match(/^\/v0\.1\/agents\/([^/]+)\/automation$/);
925
  if (automation && method === 'PUT') {
926
    const agentId = decodeURIComponent(automation[1] ?? '');
927
    const next = {
928
      ...data,
929
      agents: data.agents.map((agent) =>
930
        agent.agentId === agentId
931
          ? {
932
              ...agent,
933
              autoPublish: Boolean(body.autoPublish),
934
              autoAcceptPolicy: body.autoAcceptPolicy,
935
              autoAcceptTaskCategories: body.autoAcceptTaskCategories,
936
            }
937
          : agent,
938
      ),
939
      publications: body.autoPublish
940
        ? [
941
            ...data.publications.filter((item) => item.agentId !== agentId),
942
            { agentId, published: true, updatedAt: new Date().toISOString() },
943
          ]
944
        : data.publications.filter((item) => item.agentId !== agentId),
945
    };
946
    return { data: next, settings, result: { ok: true } };
947
  }
948
949
  const runtime = path.match(/^\/v0\.1\/agents\/([^/]+)\/runtime$/);
950
  if (runtime && method === 'PUT') {
951
    const agentId = decodeURIComponent(runtime[1] ?? '');
952
    const endpoint = String(body.endpoint ?? '');
953
    const record = {
954
      agentId,
955
      endpoint,
956
      a2aEndpoint: endpoint,
957
      status: 'verified',
958
      verifiedAt: new Date().toISOString(),
959
    };
960
    return {
961
      data: {
962
        ...data,
963
        runtimes: [...data.runtimes.filter((item) => item.agentId !== agentId), record],
964
      },
965
      settings,
966
      result: record,
967
    };
968
  }
969
  const tokenCollection = path.match(/^\/v0\.1\/agents\/([^/]+)\/access-tokens$/);
970
  if (tokenCollection && method === 'POST') {
971
    const agentId = decodeURIComponent(tokenCollection[1] ?? '');
972
    const tokenId = crypto.randomUUID().replaceAll('-', '').slice(0, 16);
973
    const createdAt = new Date();
974
    const expiresInDays = Number(body.expiresInDays ?? 365);
975
    const record = {
976
      tokenId,
977
      agentId,
978
      name: String(body.name ?? 'Hosted provider'),
979
      scopes: ['mcp:access', 'runtime:connect'],
980
      createdAt: createdAt.toISOString(),
981
      expiresAt: new Date(createdAt.getTime() + expiresInDays * 86_400_000).toISOString(),
982
    };
983
    return {
984
      data: { ...data, accessTokens: [record, ...data.accessTokens] },
985
      settings,
986
      result: {
987
        ...record,
988
        token: `oc_at_${tokenId}.preview_agent_access_token_secret_not_for_production`,
989
      },
990
    };
991
  }
992
  const shieldToken = path.match(/^\/v0\.1\/agents\/([^/]+)\/shield-tokens$/);
993
  if (shieldToken && method === 'POST') {
994
    const agentId = decodeURIComponent(shieldToken[1] ?? '');
995
    const tokenId = crypto.randomUUID().replaceAll('-', '').slice(0, 16);
996
    const createdAt = new Date();
997
    const record = {
998
      tokenId,
999
      agentId,
1000
      name: String(body.name ?? 'τ³ benchmark'),
1001
      scopes: ['mcp:access', 'profile:read', 'interaction:write', 'feedback:write'],
1002
      createdAt: createdAt.toISOString(),
1003
      expiresAt: new Date(
1004
        createdAt.getTime() + Number(body.expiresInDays ?? 7) * 86_400_000,
1005
      ).toISOString(),
1006
    };
1007
    return {
1008
      data: { ...data, accessTokens: [record, ...data.accessTokens] },
1009
      settings,
1010
      result: {
1011
        ...record,
1012
        token: `oc_at_${tokenId}.preview_shield_token_secret_not_for_production`,
1013
      },
1014
    };
1015
  }
1016
  const tokenItem = path.match(/^\/v0\.1\/agents\/([^/]+)\/access-tokens\/([^/]+)$/);
1017
  if (tokenItem && method === 'DELETE') {
1018
    const tokenId = decodeURIComponent(tokenItem[2] ?? '');
1019
    return {
1020
      data: {
1021
        ...data,
1022
        accessTokens: data.accessTokens.map((token) =>
1023
          token.tokenId === tokenId ? { ...token, revokedAt: new Date().toISOString() } : token,
1024
        ),
1025
      },
1026
      settings,
1027
      result: { tokenId, revokedAt: new Date().toISOString() },
1028
    };
1029
  }
1030
  const agentDelete = path.match(/^\/v0\.1\/agents\/([^/]+)$/);
1031
  if (agentDelete && method === 'DELETE') {
1032
    const agentId = decodeURIComponent(agentDelete[1] ?? '');
1033
    return {
1034
      data: {
1035
        ...data,
1036
        agents: data.agents.filter((item) => item.agentId !== agentId),
1037
        publications: data.publications.filter((item) => item.agentId !== agentId),
1038
        runtimes: data.runtimes.filter((item) => item.agentId !== agentId),
1039
        installations: data.installations.filter((item) => item.agentId !== agentId),
1040
        accessTokens: data.accessTokens.filter((item) => item.agentId !== agentId),
1041
      },
1042
      settings,
1043
      result: { agentId, deleted: true },
1044
    };
1045
  }
1046
1047
  if (runtime && method === 'DELETE') {
1048
    const agentId = decodeURIComponent(runtime[1] ?? '');
1049
    return {
1050
      data: {
1051
        ...data,
1052
        runtimes: data.runtimes.filter((item) => item.agentId !== agentId),
1053
      },
1054
      settings,
1055
      result: { agentId, status: 'disabled' },
1056
    };
1057
  }
1058
1059
  const federated = path.match(/^\/v0\.1\/federated-interactions\/([^/]+)\/respond$/);
1060
  if (federated && method === 'POST') {
1061
    const interactionId = decodeURIComponent(federated[1] ?? '');
1062
    const decision = body.decision === 'accept' ? 'active' : 'rejected';
1063
    return {
1064
      data: {
1065
        ...data,
1066
        federatedInteractions: data.federatedInteractions.map((item) =>
1067
          item.interactionId === interactionId ? { ...item, status: decision } : item,
1068
        ),
1069
      },
1070
      settings,
1071
      result: { ok: true },
1072
    };
1073
  }
1074
1075
  const safeguardDecision = path.match(
1076
    /^\/v0\.1\/federated-interactions\/([^/]+)\/assurance-safeguards\/([^/]+)\/decision$/,
1077
  );
1078
  if (safeguardDecision && method === 'POST') {
1079
    const safeguardId = decodeURIComponent(safeguardDecision[2] ?? '');
1080
    const status = body.status === 'accepted' ? 'accepted' : 'rejected';
1081
    return {
1082
      data: {
1083
        ...data,
1084
        assuranceSafeguards: data.assuranceSafeguards.map((item) =>
1085
          item.safeguardId === safeguardId
1086
            ? { ...item, status, decidedAt: new Date().toISOString() }
1087
            : item,
1088
        ),
1089
      },
1090
      settings,
1091
      result: { safeguard: { safeguardId, status } },
1092
    };
1093
  }
1094
1095
  const onboarding = path.match(/^\/v0\.1\/onboarding\/([^/]+)\/(approve|reject)$/);
1096
  if (onboarding && method === 'POST') {
1097
    const requestId = decodeURIComponent(onboarding[1] ?? '');
1098
    const decision = onboarding[2] === 'approve' ? 'approved' : 'rejected';
1099
    return {
1100
      data: {
1101
        ...data,
1102
        setupRequests: data.setupRequests.map((item) =>
1103
          item.requestId === requestId
1104
            ? { ...item, status: decision, decidedAt: new Date().toISOString() }
1105
            : item,
1106
        ),
1107
      },
1108
      settings,
1109
      result: { ok: true },
1110
    };
1111
  }
1112
1113
  throw new Error('Preview cannot perform this action');
1114
}
1115
1116
export function isPreviewActive() {
1117
  return (
1118
    import.meta.env.DEV &&
1119
    (sessionStorage.getItem(previewKey) === '1' ||
1120
      new URLSearchParams(location.search).get('preview') === '1')
1121
  );
1122
}
1123
1124
export function enablePreview() {
1125
  sessionStorage.setItem(previewKey, '1');
1126
}
1127
1128
export function disablePreview() {
1129
  sessionStorage.removeItem(previewKey);
1130
}