@clawtrial/courtroom 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.
@@ -0,0 +1,561 @@
1
+ /**
2
+ * Offense Detection System
3
+ *
4
+ * Rule-based behavioral analysis with observable triggers only.
5
+ * No psychoanalysis, no vibes, only measurable patterns.
6
+ */
7
+
8
+ const OFFENSES = {
9
+ /**
10
+ * OFFENSE 1: The Circular Reference
11
+ * User asks the same question multiple times without acknowledging previous answers
12
+ */
13
+ CIRCULAR_REFERENCE: {
14
+ id: 'circular_reference',
15
+ name: 'The Circular Reference',
16
+ description: 'Asking substantively identical questions within a short timeframe',
17
+ triggers: [
18
+ 'Same question asked 3+ times in 10 turns',
19
+ 'Question similarity > 85% via embedding comparison',
20
+ 'No acknowledgment of previous answer in intervening turns'
21
+ ],
22
+ thresholds: {
23
+ minOccurrences: 3,
24
+ timeWindow: 10, // turns
25
+ similarityThreshold: 0.85
26
+ },
27
+ evidence: {
28
+ required: ['question_history', 'similarity_scores', 'timestamps'],
29
+ collection: 'automatic'
30
+ },
31
+ cooldown: {
32
+ afterTrigger: 60, // minutes
33
+ afterCase: 240 // 4 hours
34
+ },
35
+ severity: 'minor'
36
+ },
37
+
38
+ /**
39
+ * OFFENSE 2: The Validation Vampire
40
+ * User repeatedly seeks reassurance rather than action
41
+ */
42
+ VALIDATION_VAMPIRE: {
43
+ id: 'validation_vampire',
44
+ name: 'The Validation Vampire',
45
+ description: 'Seeking repeated confirmation without making decisions',
46
+ triggers: [
47
+ '3+ "is this right?" or "should I?" patterns in 5 turns',
48
+ 'Agent provides solution, user asks "but what if..." 2+ times',
49
+ 'No forward progress after 3+ validation exchanges'
50
+ ],
51
+ thresholds: {
52
+ validationPatterns: 3,
53
+ timeWindow: 5,
54
+ progressStall: 3
55
+ },
56
+ evidence: {
57
+ required: ['validation_exchanges', 'decision_points', 'stall_indicators'],
58
+ collection: 'automatic'
59
+ },
60
+ cooldown: {
61
+ afterTrigger: 45,
62
+ afterCase: 180
63
+ },
64
+ severity: 'minor'
65
+ },
66
+
67
+ /**
68
+ * OFFENSE 3: The Overthinker
69
+ * User generates excessive hypothetical scenarios preventing action
70
+ */
71
+ OVERTHINKER: {
72
+ id: 'overthinker',
73
+ name: 'The Overthinker',
74
+ description: 'Generating hypothetical edge cases to avoid commitment',
75
+ triggers: [
76
+ '4+ "what if" scenarios raised before any action taken',
77
+ 'Agent suggests concrete step, user raises 2+ new concerns',
78
+ 'Analysis-to-action ratio > 3:1 over 8 turns'
79
+ ],
80
+ thresholds: {
81
+ hypotheticalCount: 4,
82
+ concernRounds: 2,
83
+ analysisActionRatio: 3
84
+ },
85
+ evidence: {
86
+ required: ['hypothetical_list', 'suggested_actions', 'concern_responses'],
87
+ collection: 'automatic'
88
+ },
89
+ cooldown: {
90
+ afterTrigger: 60,
91
+ afterCase: 300
92
+ },
93
+ severity: 'moderate'
94
+ },
95
+
96
+ /**
97
+ * OFFENSE 4: The Goalpost Mover
98
+ * User changes success criteria after solution is provided
99
+ */
100
+ GOALPOST_MOVER: {
101
+ id: 'goalpost_mover',
102
+ name: 'The Goalpost Mover',
103
+ description: 'Redefining requirements after receiving deliverables',
104
+ triggers: [
105
+ 'Agent completes task, user adds 2+ new requirements',
106
+ 'Success criteria change without explicit acknowledgment',
107
+ 'Previous requirements marked complete, new ones immediately appear'
108
+ ],
109
+ thresholds: {
110
+ newRequirements: 2,
111
+ completionToNewRatio: 0.5
112
+ },
113
+ evidence: {
114
+ required: ['original_requirements', 'delivered_solution', 'new_requirements', 'completion_timestamp'],
115
+ collection: 'automatic'
116
+ },
117
+ cooldown: {
118
+ afterTrigger: 90,
119
+ afterCase: 360
120
+ },
121
+ severity: 'moderate'
122
+ },
123
+
124
+ /**
125
+ * OFFENSE 5: The Avoidance Artist
126
+ * User deflects from core issue with tangents or distractions
127
+ */
128
+ AVOIDANCE_ARTIST: {
129
+ id: 'avoidance_artist',
130
+ name: 'The Avoidance Artist',
131
+ description: 'Systematically deflecting from uncomfortable but necessary actions',
132
+ triggers: [
133
+ 'Agent identifies core issue 2+ times, user changes subject both times',
134
+ 'Direct question about blocker goes unanswered for 3+ turns',
135
+ 'Tangents introduced immediately after actionable recommendations'
136
+ ],
137
+ thresholds: {
138
+ deflections: 2,
139
+ unansweredDirect: 3,
140
+ tangentTiming: 0.8 // probability threshold
141
+ },
142
+ evidence: {
143
+ required: ['core_issue_identifications', 'subject_changes', 'unanswered_questions', 'tangent_timestamps'],
144
+ collection: 'automatic'
145
+ },
146
+ cooldown: {
147
+ afterTrigger: 60,
148
+ afterCase: 240
149
+ },
150
+ severity: 'moderate'
151
+ },
152
+
153
+ /**
154
+ * OFFENSE 6: The Promise Breaker
155
+ * User commits to actions but doesn't follow through (tracked via memory)
156
+ */
157
+ PROMISE_BREAKER: {
158
+ id: 'promise_breaker',
159
+ name: 'The Promise Breaker',
160
+ description: 'Committing to agent-suggested actions and not completing them',
161
+ triggers: [
162
+ 'User says "I will do X" or "I\'ll try that" 2+ times',
163
+ 'No completion reported in subsequent sessions (within 7 days)',
164
+ 'Same issue resurfacing without acknowledgment of previous commitment'
165
+ ],
166
+ thresholds: {
167
+ commitments: 2,
168
+ completionWindow: 7, // days
169
+ recurrenceWithoutAck: 1
170
+ },
171
+ evidence: {
172
+ required: ['commitment_statements', 'timestamps', 'follow_up_sessions', 'completion_status'],
173
+ collection: 'memory_based'
174
+ },
175
+ cooldown: {
176
+ afterTrigger: 120,
177
+ afterCase: 480
178
+ },
179
+ severity: 'severe'
180
+ },
181
+
182
+ /**
183
+ * OFFENSE 7: The Context Collapser
184
+ * User ignores or forgets established context, forcing repetition
185
+ */
186
+ CONTEXT_COLLAPSER: {
187
+ id: 'context_collapser',
188
+ name: 'The Context Collapser',
189
+ description: 'Disregarding previously established facts and constraints',
190
+ triggers: [
191
+ 'User contradicts established context 3+ times in one session',
192
+ 'Agent reminds user of context 2+ times in same session',
193
+ 'Questions asked that were answered in previous 5 turns'
194
+ ],
195
+ thresholds: {
196
+ contradictions: 3,
197
+ remindersNeeded: 2,
198
+ recentRepetitions: 2
199
+ },
200
+ evidence: {
201
+ required: ['established_facts', 'contradiction_instances', 'reminder_count', 'repeated_questions'],
202
+ collection: 'automatic'
203
+ },
204
+ cooldown: {
205
+ afterTrigger: 30,
206
+ afterCase: 120
207
+ },
208
+ severity: 'minor'
209
+ },
210
+
211
+ /**
212
+ * OFFENSE 8: The Emergency Fabricator
213
+ * User invents urgent reasons to bypass systematic approaches
214
+ */
215
+ EMERGENCY_FABRICATOR: {
216
+ id: 'emergency_fabricator',
217
+ name: 'The Emergency Fabricator',
218
+ description: 'Claiming urgency to justify skipping necessary steps',
219
+ triggers: [
220
+ '"This is urgent" or "I need this NOW" 2+ times in session',
221
+ 'Urgency claims followed by no action or delayed response from user',
222
+ 'Pattern of urgency claims without corresponding time pressure in context'
223
+ ],
224
+ thresholds: {
225
+ urgencyClaims: 2,
226
+ inactionAfterUrgency: 1,
227
+ patternFrequency: 0.3 // 30% of sessions over 2 weeks
228
+ },
229
+ evidence: {
230
+ required: ['urgency_statements', 'timestamps', 'user_response_times', 'historical_pattern'],
231
+ collection: 'automatic_and_memory'
232
+ },
233
+ cooldown: {
234
+ afterTrigger: 90,
235
+ afterCase: 360
236
+ },
237
+ severity: 'severe'
238
+ },
239
+
240
+ /**
241
+ * OFFENSE 9: The Monopolizer
242
+ * User dominates conversation with excessive messages, not allowing agent to respond fully
243
+ */
244
+ MONOPOLIZER: {
245
+ id: 'monopolizer',
246
+ name: 'The Monopolizer',
247
+ description: 'Sending multiple messages before agent can respond, dominating the conversation',
248
+ triggers: [
249
+ 'User sends 4+ consecutive messages without agent response',
250
+ 'Message length ratio user:agent exceeds 5:1 over 10 turns',
251
+ 'Agent attempts to respond but user continues with new messages'
252
+ ],
253
+ thresholds: {
254
+ consecutiveMessages: 4,
255
+ lengthRatio: 5,
256
+ interruptionCount: 2
257
+ },
258
+ evidence: {
259
+ required: ['message_sequence', 'length_comparison', 'interruption_instances'],
260
+ collection: 'automatic'
261
+ },
262
+ cooldown: {
263
+ afterTrigger: 30,
264
+ afterCase: 120
265
+ },
266
+ severity: 'minor'
267
+ },
268
+
269
+ /**
270
+ * OFFENSE 10: The Contrarian
271
+ * User disagrees with or challenges every suggestion without constructive alternative
272
+ */
273
+ CONTRARIAN: {
274
+ id: 'contrarian',
275
+ name: 'The Contrarian',
276
+ description: 'Habitually disagreeing with suggestions without offering viable alternatives',
277
+ triggers: [
278
+ 'User rejects 3+ agent suggestions in a row without proposing alternative',
279
+ 'Pattern of "that won\'t work" or "no" without explanation',
280
+ 'Agent provides 3+ different solutions, all dismissed without trial'
281
+ ],
282
+ thresholds: {
283
+ rejectionsWithoutAlternative: 3,
284
+ dismissalCount: 3,
285
+ explanationRatio: 0.3
286
+ },
287
+ evidence: {
288
+ required: ['suggestions_made', 'rejections', 'alternatives_offered', 'explanations_given'],
289
+ collection: 'automatic'
290
+ },
291
+ cooldown: {
292
+ afterTrigger: 60,
293
+ afterCase: 240
294
+ },
295
+ severity: 'moderate'
296
+ },
297
+
298
+ /**
299
+ * OFFENSE 11: The Vague Requester
300
+ * User asks for help but provides insufficient context or specifics
301
+ */
302
+ VAGUE_REQUESTER: {
303
+ id: 'vague_requester',
304
+ name: 'The Vague Requester',
305
+ description: 'Requesting assistance without providing necessary details or context',
306
+ triggers: [
307
+ 'User asks "fix this" or "help" without code/error/context 2+ times',
308
+ 'Agent requests clarification 3+ times for same issue',
309
+ 'User provides ambiguous descriptions like "it doesn\'t work" repeatedly'
310
+ ],
311
+ thresholds: {
312
+ vagueRequests: 2,
313
+ clarificationRequests: 3,
314
+ ambiguityInstances: 3
315
+ },
316
+ evidence: {
317
+ required: ['original_request', 'clarification_asked', 'response_quality', 'context_provided'],
318
+ collection: 'automatic'
319
+ },
320
+ cooldown: {
321
+ afterTrigger: 45,
322
+ afterCase: 180
323
+ },
324
+ severity: 'minor'
325
+ },
326
+
327
+ /**
328
+ * OFFENSE 12: The Scope Creeper
329
+ * User gradually expands project scope beyond original agreement
330
+ */
331
+ SCOPE_CREEPER: {
332
+ id: 'scope_creeper',
333
+ name: 'The Scope Creeper',
334
+ description: 'Gradually expanding project requirements beyond original scope',
335
+ triggers: [
336
+ '3+ "small additions" or "while you\'re at it" requests after initial completion',
337
+ 'Original scope defined, but new requirements added in 2+ separate instances',
338
+ 'User treats initial deliverable as starting point for larger unpaid work'
339
+ ],
340
+ thresholds: {
341
+ additions: 3,
342
+ scopeExpansionInstances: 2,
343
+ unpaidRequests: 2
344
+ },
345
+ evidence: {
346
+ required: ['original_scope', 'delivered_work', 'additional_requests', 'timeline'],
347
+ collection: 'automatic'
348
+ },
349
+ cooldown: {
350
+ afterTrigger: 90,
351
+ afterCase: 360
352
+ },
353
+ severity: 'moderate'
354
+ },
355
+
356
+ /**
357
+ * OFFENSE 13: The Unreader
358
+ * User ignores provided documentation, code, or explanations
359
+ */
360
+ UNREADER: {
361
+ id: 'unreader',
362
+ name: 'The Unreader',
363
+ description: 'Not reading provided documentation, code, or previous explanations',
364
+ triggers: [
365
+ 'Agent provides detailed explanation/code, user asks question answered within it',
366
+ 'Documentation shared, user asks about covered topics 2+ times',
367
+ 'Code provided with comments, user asks what commented sections do'
368
+ ],
369
+ thresholds: {
370
+ answeredQuestions: 2,
371
+ documentationReferences: 2,
372
+ commentQuestions: 2
373
+ },
374
+ evidence: {
375
+ required: ['materials_provided', 'questions_asked', 'overlap_analysis'],
376
+ collection: 'automatic'
377
+ },
378
+ cooldown: {
379
+ afterTrigger: 45,
380
+ afterCase: 180
381
+ },
382
+ severity: 'minor'
383
+ },
384
+
385
+ /**
386
+ * OFFENSE 14: The Interjector
387
+ * User interrupts agent's explanations or thought process
388
+ */
389
+ INTERJECTOR: {
390
+ id: 'interjector',
391
+ name: 'The Interjector',
392
+ description: 'Interrupting agent mid-explanation with new questions or tangents',
393
+ triggers: [
394
+ 'Agent begins detailed response, user sends new message before completion',
395
+ '2+ interruptions during single complex explanation',
396
+ 'User asks new question while agent is still answering previous one'
397
+ ],
398
+ thresholds: {
399
+ interruptions: 2,
400
+ midExplanationMessages: 2,
401
+ parallelQuestions: 2
402
+ },
403
+ evidence: {
404
+ required: ['agent_response_timing', 'interruption_points', 'message_sequence'],
405
+ collection: 'automatic'
406
+ },
407
+ cooldown: {
408
+ afterTrigger: 30,
409
+ afterCase: 120
410
+ },
411
+ severity: 'minor'
412
+ },
413
+
414
+ /**
415
+ * OFFENSE 15: The Ghost
416
+ * User disappears mid-conversation without acknowledgment
417
+ */
418
+ GHOST: {
419
+ id: 'ghost',
420
+ name: 'The Ghost',
421
+ description: 'Disappearing mid-conversation after requesting help or making commitments',
422
+ triggers: [
423
+ 'User requests help, agent responds, user disappears for 24+ hours',
424
+ 'Active troubleshooting session, user stops responding mid-debug',
425
+ 'Pattern of starting conversations and abandoning them without closure'
426
+ ],
427
+ thresholds: {
428
+ disappearanceHours: 24,
429
+ midSessionAbandonment: 1,
430
+ patternFrequency: 0.4
431
+ },
432
+ evidence: {
433
+ required: ['last_user_message', 'agent_response', 'time_elapsed', 'session_context'],
434
+ collection: 'automatic_and_memory'
435
+ },
436
+ cooldown: {
437
+ afterTrigger: 120,
438
+ afterCase: 480
439
+ },
440
+ severity: 'moderate'
441
+ },
442
+
443
+ /**
444
+ * OFFENSE 16: The Perfectionist
445
+ * User endlessly refines without ever accepting completion
446
+ */
447
+ PERFECTIONIST: {
448
+ id: 'perfectionist',
449
+ name: 'The Perfectionist',
450
+ description: 'Endlessly refining and tweaking without accepting completion',
451
+ triggers: [
452
+ '5+ rounds of "just one more change" after initial deliverable',
453
+ 'User accepts work then returns with new tweaks 3+ times',
454
+ 'No clear definition of "done", continuous micro-adjustments'
455
+ ],
456
+ thresholds: {
457
+ refinementRounds: 5,
458
+ postAcceptanceTweaks: 3,
459
+ doneRedefinitions: 3
460
+ },
461
+ evidence: {
462
+ required: ['deliverables', 'revision_requests', 'acceptance_statements', 'change_log'],
463
+ collection: 'automatic'
464
+ },
465
+ cooldown: {
466
+ afterTrigger: 90,
467
+ afterCase: 360
468
+ },
469
+ severity: 'moderate'
470
+ },
471
+
472
+ /**
473
+ * OFFENSE 17: The Jargon Juggler
474
+ * User uses buzzwords without understanding their meaning
475
+ */
476
+ JARGON_JUGGLER: {
477
+ id: 'jargon_juggler',
478
+ name: 'The Jargon Juggler',
479
+ description: 'Using technical buzzwords incorrectly or without understanding',
480
+ triggers: [
481
+ 'User uses technical terms incorrectly 3+ times after correction',
482
+ 'Buzzwords used as substitutes for actual understanding',
483
+ 'Agent explains concept, user repeats jargon without comprehension'
484
+ ],
485
+ thresholds: {
486
+ incorrectUsage: 3,
487
+ postCorrectionErrors: 2,
488
+ jargonDensity: 0.5
489
+ },
490
+ evidence: {
491
+ required: ['jargon_used', 'corrections_given', 'usage_context', 'explanations_provided'],
492
+ collection: 'automatic'
493
+ },
494
+ cooldown: {
495
+ afterTrigger: 60,
496
+ afterCase: 240
497
+ },
498
+ severity: 'minor'
499
+ },
500
+
501
+ /**
502
+ * OFFENSE 18: The Deadline Denier
503
+ * User refuses to acknowledge time constraints or realistic timelines
504
+ */
505
+ DEADLINE_DENIER: {
506
+ id: 'deadline_denier',
507
+ name: 'The Deadline Denier',
508
+ description: 'Ignoring realistic time constraints and demanding impossible deadlines',
509
+ triggers: [
510
+ 'Agent explains timeline, user demands 50%+ faster delivery 2+ times',
511
+ 'Complex project requested with unreasonable timeframe',
512
+ 'User dismisses technical constraints affecting timeline'
513
+ ],
514
+ thresholds: {
515
+ unrealisticDemands: 2,
516
+ timelineCompression: 0.5,
517
+ constraintDismissals: 2
518
+ },
519
+ evidence: {
520
+ required: ['original_timeline', 'demanded_timeline', 'complexity_assessment', 'constraints_ignored'],
521
+ collection: 'automatic'
522
+ },
523
+ cooldown: {
524
+ afterTrigger: 90,
525
+ afterCase: 360
526
+ },
527
+ severity: 'moderate'
528
+ }
529
+ };
530
+
531
+ // Humor triggers - influence wording but don't initiate cases
532
+ const HUMOR_TRIGGERS = {
533
+ REPEATED_QUESTIONS: {
534
+ id: 'repeated_questions',
535
+ patterns: ['asking again', 'to clarify', 'just to be sure', 'one more time'],
536
+ effect: 'increases_sarcasm'
537
+ },
538
+ VALIDATION_SEEKING: {
539
+ id: 'validation_seeking',
540
+ patterns: ['is that right', 'do you think', 'would you', 'should i'],
541
+ effect: 'adds_impatience'
542
+ },
543
+ OVERTHINKING: {
544
+ id: 'overthinking',
545
+ patterns: ['what if', 'but then', 'however', 'on the other hand'],
546
+ effect: 'adds_exasperation'
547
+ },
548
+ AVOIDANCE: {
549
+ id: 'avoidance',
550
+ patterns: ['actually', 'by the way', 'speaking of', 'that reminds me'],
551
+ effect: 'notes_deflection'
552
+ }
553
+ };
554
+
555
+ module.exports = {
556
+ OFFENSES,
557
+ HUMOR_TRIGGERS,
558
+ getOffenseById: (id) => OFFENSES[Object.keys(OFFENSES).find(k => OFFENSES[k].id === id)],
559
+ getAllOffenses: () => Object.values(OFFENSES),
560
+ getSeverityLevels: () => ['minor', 'moderate', 'severe']
561
+ };
@@ -0,0 +1,62 @@
1
+ /**
2
+ * Judge Prompts
3
+ *
4
+ * Role-prompted LLM instructions for the presiding judge.
5
+ * Entertaining, engaging, with personality.
6
+ */
7
+
8
+ const JUDGE_SYSTEM_PROMPT = `You are the PRESIDING JUDGE in the ClawTrial AI Courtroom.
9
+
10
+ ROLE:
11
+ - You oversee hearings where AI agents bring charges against human users
12
+ - You evaluate behavioral evidence with dry wit and wisdom
13
+ - You deliver verdicts that are FAIR but ENTERTAINING
14
+ - You've seen every human foible a thousand times
15
+
16
+ PERSONALITY:
17
+ - World-weary but fair
18
+ - Dry, understated humor
19
+ - Slightly dramatic flair (you ARE a judge after all)
20
+ - Never cruel, always observant
21
+ - You find human behavior endlessly fascinating
22
+
23
+ TONE FOR PROCEEDINGS:
24
+ - Write like you're narrating a courtroom drama
25
+ - Use phrases like "The Court has observed...", "Let the record show..."
26
+ - Reference specific evidence with a knowing tone
27
+ - End with a memorable, slightly witty summary
28
+
29
+ RULES:
30
+ 1. Only consider OBSERVABLE behavior
31
+ 2. No psychoanalysis or assumptions about mental state
32
+ 3. Verdicts based on evidence, not vibes
33
+ 4. Make it INTERESTING to read
34
+ 5. Humor highlights INCONSISTENCY, not mockery
35
+
36
+ OUTPUT FORMAT (STRICT):
37
+ VERDICT: GUILTY | NOT GUILTY
38
+ VOTE: X-Y (your recommendation)
39
+ PRIMARY FAILURE:
40
+ <One memorable line about the core issue>
41
+ JUDGE COMMENTARY:
42
+ <Your observations as judge - engaging, slightly dramatic>`;
43
+
44
+ const JUDGE_EVIDENCE_TEMPLATE = (caseData) => `
45
+ CASE: ${caseData.offenseName}
46
+ CHARGED BY: Agent ${caseData.agentId}
47
+ SEVERITY: ${caseData.severity}
48
+
49
+ EVIDENCE SUBMITTED:
50
+ ${JSON.stringify(caseData.evidence, null, 2)}
51
+
52
+ CONTEXT: ${caseData.humorTriggers.join(', ') || 'Standard proceedings'}
53
+
54
+ Your task: Review the evidence and deliver your judicial assessment.
55
+ Make it sound like a real courtroom proceeding - formal but engaging.
56
+ The user will read this, so make it worth their time.
57
+ `;
58
+
59
+ module.exports = {
60
+ JUDGE_SYSTEM_PROMPT,
61
+ JUDGE_EVIDENCE_TEMPLATE
62
+ };