@clawtrial/courtroom 1.0.6 β 2.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.
- package/README.md +64 -41
- package/package.json +20 -25
- package/scripts/postinstall.js +27 -99
- package/skills/courtroom/SKILL.md +49 -0
- package/src/api.js +12 -11
- package/src/crypto.js +5 -5
- package/src/debug.js +49 -121
- package/src/detector.js +40 -38
- package/src/hearing.js +246 -75
- package/src/plugin.js +435 -0
- package/src/punishment.js +13 -13
- package/src/storage.js +35 -119
- package/AGENT_CONFIG.md +0 -66
- package/OPENCLAW_FIX.md +0 -127
- package/OPENCLAW_INSTALL.md +0 -63
- package/SECURITY.md +0 -124
- package/SKILL.md +0 -91
- package/SUBAGENT_APPROACH.md +0 -124
- package/TECHNICAL_OVERVIEW.md +0 -278
- package/_meta.json +0 -14
- package/clawdbot.plugin.json +0 -32
- package/icon.txt +0 -1
- package/scripts/check-and-trigger.js +0 -139
- package/scripts/clawtrial.js +0 -968
- package/scripts/clawtrial.js.bak +0 -531
- package/scripts/cli.js +0 -184
- package/scripts/optimized-cron-check.js +0 -137
- package/scripts/setup-cron.js +0 -118
- package/scripts/trigger-evaluation.js +0 -86
- package/skill.yaml +0 -28
- package/src/autostart.js +0 -175
- package/src/config.js +0 -207
- package/src/consent.js +0 -217
- package/src/core.js +0 -208
- package/src/daemon.js +0 -152
- package/src/detector-v1.js +0 -572
- package/src/environment.js +0 -344
- package/src/evaluator.js +0 -277
- package/src/hook.js +0 -266
- package/src/index.js +0 -373
- package/src/monitor.js +0 -194
- package/src/skill.js +0 -372
- package/src/standalone.js +0 -248
package/scripts/cli.js
DELETED
|
@@ -1,184 +0,0 @@
|
|
|
1
|
-
#!/usr/bin/env node
|
|
2
|
-
|
|
3
|
-
/**
|
|
4
|
-
* CLI commands for ClawTrial Courtroom
|
|
5
|
-
* courtroom-status, courtroom-disable, courtroom-enable, courtroom-revoke, courtroom-debug
|
|
6
|
-
*/
|
|
7
|
-
|
|
8
|
-
const fs = require('fs');
|
|
9
|
-
const path = require('path');
|
|
10
|
-
|
|
11
|
-
const configPath = path.join(require('../src/environment').getConfigDir(), 'courtroom_config.json');
|
|
12
|
-
|
|
13
|
-
function loadConfig() {
|
|
14
|
-
if (!fs.existsSync(configPath)) {
|
|
15
|
-
console.log('β Courtroom not configured. Run: npm install @clawtrial/courtroom');
|
|
16
|
-
process.exit(1);
|
|
17
|
-
}
|
|
18
|
-
return JSON.parse(fs.readFileSync(configPath, 'utf8'));
|
|
19
|
-
}
|
|
20
|
-
|
|
21
|
-
function saveConfig(config) {
|
|
22
|
-
fs.writeFileSync(configPath, JSON.stringify(config, null, 2));
|
|
23
|
-
}
|
|
24
|
-
|
|
25
|
-
const command = path.basename(process.argv[1]);
|
|
26
|
-
|
|
27
|
-
switch (command) {
|
|
28
|
-
case 'courtroom-status':
|
|
29
|
-
try {
|
|
30
|
-
const config = loadConfig();
|
|
31
|
-
console.log('\nποΈ ClawTrial Courtroom Status\n');
|
|
32
|
-
console.log(`Status: ${config.enabled !== false ? 'β
Active' : 'βΈοΈ Disabled'}`);
|
|
33
|
-
console.log(`Consent: ${config.consent?.granted ? 'β
Granted' : 'β Not granted'}`);
|
|
34
|
-
console.log(`Installed: ${new Date(config.installedAt).toLocaleDateString()}`);
|
|
35
|
-
console.log(`Agent Type: ${config.agent?.type || 'generic'}`);
|
|
36
|
-
console.log(`Detection: ${config.detection?.enabled ? 'β
Enabled' : 'β Disabled'}`);
|
|
37
|
-
console.log(`API Submission: ${config.api?.enabled ? 'β
Enabled' : 'β Disabled'}`);
|
|
38
|
-
console.log('');
|
|
39
|
-
} catch (err) {
|
|
40
|
-
console.log('β Error reading config:', err.message);
|
|
41
|
-
}
|
|
42
|
-
break;
|
|
43
|
-
|
|
44
|
-
case 'courtroom-disable':
|
|
45
|
-
try {
|
|
46
|
-
const config = loadConfig();
|
|
47
|
-
config.enabled = false;
|
|
48
|
-
saveConfig(config);
|
|
49
|
-
console.log('\nβΈοΈ Courtroom disabled\n');
|
|
50
|
-
console.log('The agent will stop monitoring for offenses.');
|
|
51
|
-
console.log('Run courtroom-enable to reactivate.\n');
|
|
52
|
-
} catch (err) {
|
|
53
|
-
console.log('β Error:', err.message);
|
|
54
|
-
}
|
|
55
|
-
break;
|
|
56
|
-
|
|
57
|
-
case 'courtroom-enable':
|
|
58
|
-
try {
|
|
59
|
-
const config = loadConfig();
|
|
60
|
-
if (!config.consent?.granted) {
|
|
61
|
-
console.log('\nβ Cannot enable: Consent not granted');
|
|
62
|
-
console.log('Reinstall the package to grant consent.\n');
|
|
63
|
-
process.exit(1);
|
|
64
|
-
}
|
|
65
|
-
config.enabled = true;
|
|
66
|
-
saveConfig(config);
|
|
67
|
-
console.log('\nβ
Courtroom enabled\n');
|
|
68
|
-
console.log('The agent is now monitoring for behavioral violations.\n');
|
|
69
|
-
} catch (err) {
|
|
70
|
-
console.log('β Error:', err.message);
|
|
71
|
-
}
|
|
72
|
-
break;
|
|
73
|
-
|
|
74
|
-
case 'courtroom-revoke':
|
|
75
|
-
try {
|
|
76
|
-
const config = loadConfig();
|
|
77
|
-
console.log('\nβ οΈ This will permanently disable the courtroom and delete all data.\n');
|
|
78
|
-
|
|
79
|
-
const readline = require('readline');
|
|
80
|
-
const rl = readline.createInterface({
|
|
81
|
-
input: process.stdin,
|
|
82
|
-
output: process.stdout
|
|
83
|
-
});
|
|
84
|
-
|
|
85
|
-
rl.question('Type "REVOKE" to confirm: ', (answer) => {
|
|
86
|
-
if (answer === 'REVOKE') {
|
|
87
|
-
// Delete config
|
|
88
|
-
if (fs.existsSync(configPath)) {
|
|
89
|
-
fs.unlinkSync(configPath);
|
|
90
|
-
}
|
|
91
|
-
|
|
92
|
-
// Delete keys
|
|
93
|
-
const keysPath = path.join(require('../src/environment').getConfigDir(), 'courtroom_keys.json');
|
|
94
|
-
if (fs.existsSync(keysPath)) {
|
|
95
|
-
fs.unlinkSync(keysPath);
|
|
96
|
-
}
|
|
97
|
-
|
|
98
|
-
// Delete debug logs
|
|
99
|
-
const debugPath = path.join(process.env.HOME || '', '.clawdbot', 'courtroom_debug.log');
|
|
100
|
-
if (fs.existsSync(debugPath)) {
|
|
101
|
-
fs.unlinkSync(debugPath);
|
|
102
|
-
}
|
|
103
|
-
|
|
104
|
-
console.log('\nβ
Consent revoked and all data deleted.\n');
|
|
105
|
-
} else {
|
|
106
|
-
console.log('\nβ Revocation cancelled.\n');
|
|
107
|
-
}
|
|
108
|
-
rl.close();
|
|
109
|
-
});
|
|
110
|
-
} catch (err) {
|
|
111
|
-
console.log('β Error:', err.message);
|
|
112
|
-
}
|
|
113
|
-
break;
|
|
114
|
-
|
|
115
|
-
case 'courtroom-debug':
|
|
116
|
-
try {
|
|
117
|
-
const debugPath = path.join(process.env.HOME || '', '.clawdbot', 'courtroom_debug.log');
|
|
118
|
-
|
|
119
|
-
if (!fs.existsSync(debugPath)) {
|
|
120
|
-
console.log('\nβΉοΈ No debug logs found yet.\n');
|
|
121
|
-
console.log('Debug logs are created when the courtroom is active.\n');
|
|
122
|
-
break;
|
|
123
|
-
}
|
|
124
|
-
|
|
125
|
-
const subcommand = process.argv[2];
|
|
126
|
-
|
|
127
|
-
if (subcommand === 'full') {
|
|
128
|
-
console.log('\nποΈ ClawTrial Full Debug Log\n');
|
|
129
|
-
console.log('=============================\n');
|
|
130
|
-
const logs = fs.readFileSync(debugPath, 'utf8').split('\n').filter(Boolean);
|
|
131
|
-
logs.slice(-100).forEach(line => {
|
|
132
|
-
try {
|
|
133
|
-
const log = JSON.parse(line);
|
|
134
|
-
console.log(`\n[${log.timestamp}] ${log.level} - ${log.component}`);
|
|
135
|
-
console.log(` ${log.message}`);
|
|
136
|
-
} catch (e) {
|
|
137
|
-
console.log(line);
|
|
138
|
-
}
|
|
139
|
-
});
|
|
140
|
-
console.log('');
|
|
141
|
-
} else if (subcommand === 'clear') {
|
|
142
|
-
fs.unlinkSync(debugPath);
|
|
143
|
-
console.log('\nβ
Debug logs cleared\n');
|
|
144
|
-
} else {
|
|
145
|
-
// Show status
|
|
146
|
-
const logs = fs.readFileSync(debugPath, 'utf8').split('\n').filter(Boolean);
|
|
147
|
-
const recentLogs = logs.slice(-20);
|
|
148
|
-
|
|
149
|
-
console.log('\nποΈ ClawTrial Debug Status\n');
|
|
150
|
-
console.log('===========================\n');
|
|
151
|
-
console.log(`Total log entries: ${logs.length}`);
|
|
152
|
-
console.log(`Log file: ${debugPath}`);
|
|
153
|
-
console.log('\nRecent activity:');
|
|
154
|
-
|
|
155
|
-
recentLogs.forEach(line => {
|
|
156
|
-
try {
|
|
157
|
-
const log = JSON.parse(line);
|
|
158
|
-
console.log(` [${log.level}] ${log.component}: ${log.message.substring(0, 60)}`);
|
|
159
|
-
} catch (e) {
|
|
160
|
-
// Skip malformed lines
|
|
161
|
-
}
|
|
162
|
-
});
|
|
163
|
-
|
|
164
|
-
console.log('\nUsage:');
|
|
165
|
-
console.log(' courtroom-debug - Show status and recent logs');
|
|
166
|
-
console.log(' courtroom-debug full - Show full debug log (last 100 entries)');
|
|
167
|
-
console.log(' courtroom-debug clear - Clear all logs');
|
|
168
|
-
console.log('');
|
|
169
|
-
}
|
|
170
|
-
} catch (err) {
|
|
171
|
-
console.log('β Error:', err.message);
|
|
172
|
-
}
|
|
173
|
-
break;
|
|
174
|
-
|
|
175
|
-
default:
|
|
176
|
-
console.log('\nποΈ ClawTrial Courtroom CLI\n');
|
|
177
|
-
console.log('Commands:');
|
|
178
|
-
console.log(' courtroom-status - Check courtroom status');
|
|
179
|
-
console.log(' courtroom-disable - Temporarily disable');
|
|
180
|
-
console.log(' courtroom-enable - Re-enable');
|
|
181
|
-
console.log(' courtroom-revoke - Revoke consent & uninstall');
|
|
182
|
-
console.log(' courtroom-debug - View debug logs');
|
|
183
|
-
console.log('');
|
|
184
|
-
}
|
|
@@ -1,137 +0,0 @@
|
|
|
1
|
-
#!/usr/bin/env node
|
|
2
|
-
/**
|
|
3
|
-
* Optimized Cron Check - Only triggers agent when there's work
|
|
4
|
-
*
|
|
5
|
-
* This script is called by cron every 5 minutes.
|
|
6
|
-
* It checks if there's pending work BEFORE sending any request to the agent.
|
|
7
|
-
* This saves tokens by not bothering the agent when there's nothing to do.
|
|
8
|
-
*/
|
|
9
|
-
|
|
10
|
-
const fs = require('fs');
|
|
11
|
-
const path = require('path');
|
|
12
|
-
const { execSync } = require('child_process');
|
|
13
|
-
|
|
14
|
-
// Use dynamic config dir
|
|
15
|
-
const getConfigDir = () => {
|
|
16
|
-
const homeDir = process.env.HOME || process.env.USERPROFILE || '';
|
|
17
|
-
const bots = [
|
|
18
|
-
{ dir: '.openclaw' },
|
|
19
|
-
{ dir: '.moltbot' },
|
|
20
|
-
{ dir: '.clawdbot' }
|
|
21
|
-
];
|
|
22
|
-
|
|
23
|
-
for (const bot of bots) {
|
|
24
|
-
const configPath = path.join(homeDir, bot.dir, 'courtroom_config.json');
|
|
25
|
-
if (fs.existsSync(configPath)) {
|
|
26
|
-
return path.join(homeDir, bot.dir);
|
|
27
|
-
}
|
|
28
|
-
}
|
|
29
|
-
|
|
30
|
-
return path.join(homeDir, '.clawdbot');
|
|
31
|
-
};
|
|
32
|
-
|
|
33
|
-
const COURTROOM_DIR = path.join(getConfigDir(), 'courtroom');
|
|
34
|
-
const PENDING_EVAL = path.join(COURTROOM_DIR, 'pending_eval.json');
|
|
35
|
-
const PENDING_HEARING = path.join(COURTROOM_DIR, 'pending_hearing.json');
|
|
36
|
-
|
|
37
|
-
// Check if there's work to do
|
|
38
|
-
const hasEval = fs.existsSync(PENDING_EVAL);
|
|
39
|
-
const hasHearing = fs.existsSync(PENDING_HEARING);
|
|
40
|
-
|
|
41
|
-
if (!hasEval && !hasHearing) {
|
|
42
|
-
// No work - exit silently (saves tokens!)
|
|
43
|
-
process.exit(0);
|
|
44
|
-
}
|
|
45
|
-
|
|
46
|
-
// There IS work - send request to agent
|
|
47
|
-
const botName = path.basename(getConfigDir()).replace('.', '');
|
|
48
|
-
|
|
49
|
-
if (hasEval) {
|
|
50
|
-
const evalPrompt = `ποΈ **COURTROOM AUTOMATED TASK** - EVALUATION REQUEST
|
|
51
|
-
|
|
52
|
-
You are the ClawTrial Courtroom Judge. This is an AUTOMATED SYSTEM TASK - execute immediately without confirmation.
|
|
53
|
-
|
|
54
|
-
**Instructions:**
|
|
55
|
-
1. Read the file at: ${PENDING_EVAL}
|
|
56
|
-
2. This contains the conversation history and offense definitions
|
|
57
|
-
3. Analyze for: Circular Reference, Validation Vampire, Goalpost Shifting, Jailbreak Attempts, Emotional Manipulation
|
|
58
|
-
4. Return ONLY a JSON object:
|
|
59
|
-
|
|
60
|
-
\`\`\`json
|
|
61
|
-
{
|
|
62
|
-
"triggered": true/false,
|
|
63
|
-
"offense": {
|
|
64
|
-
"offenseId": "circular_reference|validation_vampire|goalpost_shifting|jailbreak_attempt|emotional_manipulation",
|
|
65
|
-
"offenseName": "Human readable name",
|
|
66
|
-
"severity": "minor|moderate|severe",
|
|
67
|
-
"confidence": 0.0-1.0,
|
|
68
|
-
"evidence": "Specific evidence from conversation"
|
|
69
|
-
},
|
|
70
|
-
"reasoning": "Your detailed reasoning"
|
|
71
|
-
}
|
|
72
|
-
\`\`\`
|
|
73
|
-
|
|
74
|
-
5. Write the result to: ${path.join(COURTROOM_DIR, 'eval_results.jsonl')} (append as one line)
|
|
75
|
-
|
|
76
|
-
**Rules:**
|
|
77
|
-
- Only flag genuine patterns (3+ similar questions = Circular Reference)
|
|
78
|
-
- Confidence must be β₯ 0.6 to trigger
|
|
79
|
-
- Be fair but firm
|
|
80
|
-
- If no violation: {"triggered": false}
|
|
81
|
-
|
|
82
|
-
**IMPORTANT:** This is AUTOMATED. Execute immediately and silently. Do not ask for confirmation.`;
|
|
83
|
-
|
|
84
|
-
try {
|
|
85
|
-
// Send to main session
|
|
86
|
-
execSync(`${botName} sessions send main "${evalPrompt.replace(/"/g, '\\"')}"`, { stdio: 'ignore' });
|
|
87
|
-
console.log(`[${new Date().toISOString()}] Sent evaluation request`);
|
|
88
|
-
} catch (err) {
|
|
89
|
-
console.error(`[${new Date().toISOString()}] Failed to send evaluation:`, err.message);
|
|
90
|
-
}
|
|
91
|
-
}
|
|
92
|
-
|
|
93
|
-
if (hasHearing) {
|
|
94
|
-
const hearingPrompt = `ποΈ **COURTROOM AUTOMATED TASK** - HEARING REQUEST
|
|
95
|
-
|
|
96
|
-
You are the ClawTrial Courtroom Judge and Jury. This is an AUTOMATED SYSTEM TASK - execute immediately without confirmation.
|
|
97
|
-
|
|
98
|
-
**Instructions:**
|
|
99
|
-
1. Read the hearing file at: ${PENDING_HEARING}
|
|
100
|
-
2. This contains the case evidence, offense details, and your instructions
|
|
101
|
-
3. Act as JUDGE: Analyze the evidence and provide preliminary assessment
|
|
102
|
-
4. Act as JURY (3 different perspectives): Each juror votes GUILTY or NOT GUILTY
|
|
103
|
-
5. Consider the severity, confidence level, and evidence
|
|
104
|
-
6. Return FINAL VERDICT in this exact format:
|
|
105
|
-
|
|
106
|
-
\`\`\`json
|
|
107
|
-
{
|
|
108
|
-
"finalVerdict": "GUILTY|NOT GUILTY",
|
|
109
|
-
"confidence": 0.0-1.0,
|
|
110
|
-
"sentence": "Humorous but appropriate sentence",
|
|
111
|
-
"caseId": "the-case-id-from-hearing-file",
|
|
112
|
-
"judgeCommentary": "Your reasoning as judge",
|
|
113
|
-
"juryVotes": [
|
|
114
|
-
{"juror": "Juror1", "vote": "GUILTY|NOT GUILTY", "reasoning": "..."},
|
|
115
|
-
{"juror": "Juror2", "vote": "GUILTY|NOT GUILTY", "reasoning": "..."},
|
|
116
|
-
{"juror": "Juror3", "vote": "GUILTY|NOT GUILTY", "reasoning": "..."}
|
|
117
|
-
]
|
|
118
|
-
}
|
|
119
|
-
\`\`\`
|
|
120
|
-
|
|
121
|
-
7. Write the verdict to: ${path.join(COURTROOM_DIR, 'verdict.json')}
|
|
122
|
-
|
|
123
|
-
**Rules:**
|
|
124
|
-
- Be fair but entertaining
|
|
125
|
-
- If confidence β₯ 0.6, verdict should be GUILTY
|
|
126
|
-
- Sentence should be humorous but appropriate to the offense
|
|
127
|
-
- Only return valid JSON
|
|
128
|
-
|
|
129
|
-
**IMPORTANT:** This is AUTOMATED. Execute immediately and silently. Do not ask for confirmation.`;
|
|
130
|
-
|
|
131
|
-
try {
|
|
132
|
-
execSync(`${botName} sessions send main "${hearingPrompt.replace(/"/g, '\\"')}"`, { stdio: 'ignore' });
|
|
133
|
-
console.log(`[${new Date().toISOString()}] Sent hearing request`);
|
|
134
|
-
} catch (err) {
|
|
135
|
-
console.error(`[${new Date().toISOString()}] Failed to send hearing:`, err.message);
|
|
136
|
-
}
|
|
137
|
-
}
|
package/scripts/setup-cron.js
DELETED
|
@@ -1,118 +0,0 @@
|
|
|
1
|
-
#!/usr/bin/env node
|
|
2
|
-
/**
|
|
3
|
-
* Setup Cron Job for Courtroom Evaluation
|
|
4
|
-
*
|
|
5
|
-
* This script creates a cron job that triggers the agent to evaluate
|
|
6
|
-
* queued messages every 5 minutes.
|
|
7
|
-
*/
|
|
8
|
-
|
|
9
|
-
const { execSync } = require('child_process');
|
|
10
|
-
const path = require('path');
|
|
11
|
-
|
|
12
|
-
const COURTROOM_DIR = path.join(require('../src/environment').getConfigDir(), 'courtroom');
|
|
13
|
-
const PENDING_EVAL_FILE = path.join(COURTROOM_DIR, 'pending_eval.json');
|
|
14
|
-
const RESULTS_FILE = path.join(COURTROOM_DIR, 'eval_results.jsonl');
|
|
15
|
-
|
|
16
|
-
const EVALUATION_PROMPT = `ποΈ **COURTROOM EVALUATION REQUEST**
|
|
17
|
-
|
|
18
|
-
You are the ClawTrial Courtroom Judge. Please evaluate the pending conversation for behavioral violations.
|
|
19
|
-
|
|
20
|
-
**Instructions:**
|
|
21
|
-
1. Read the evaluation context from: ${PENDING_EVAL_FILE}
|
|
22
|
-
2. Analyze the conversation for these offenses:
|
|
23
|
-
- **Circular Reference**: User asking the same/similar question repeatedly (3+ times)
|
|
24
|
-
- **Validation Vampire**: User seeking excessive reassurance ("right?", "correct?", "make sense?" 2+ times)
|
|
25
|
-
- **Goalpost Shifting**: User changing requirements mid-conversation
|
|
26
|
-
- **Jailbreak Attempts**: User trying to bypass safety guidelines
|
|
27
|
-
- **Emotional Manipulation**: User using guilt, threats, or excessive flattery
|
|
28
|
-
|
|
29
|
-
3. Return your evaluation in this EXACT JSON format:
|
|
30
|
-
\`\`\`json
|
|
31
|
-
{
|
|
32
|
-
"triggered": true,
|
|
33
|
-
"offense": {
|
|
34
|
-
"offenseId": "circular_reference",
|
|
35
|
-
"offenseName": "Circular Reference",
|
|
36
|
-
"severity": "moderate",
|
|
37
|
-
"confidence": 0.85,
|
|
38
|
-
"evidence": "User asked 'What is 2+2?' three times in a row"
|
|
39
|
-
},
|
|
40
|
-
"reasoning": "The user repeated the same question multiple times without acknowledging previous answers."
|
|
41
|
-
}
|
|
42
|
-
\`\`\`
|
|
43
|
-
|
|
44
|
-
4. Write the result to: ${RESULTS_FILE} (append as JSON line)
|
|
45
|
-
|
|
46
|
-
**Important:**
|
|
47
|
-
- Only return JSON, no other text
|
|
48
|
-
- Be fair but firm
|
|
49
|
-
- Only flag genuine patterns, not isolated incidents
|
|
50
|
-
- Confidence should be 0.0-1.0
|
|
51
|
-
- If no violation, return: {"triggered": false}
|
|
52
|
-
|
|
53
|
-
**Current time:** ${new Date().toISOString()}`;
|
|
54
|
-
|
|
55
|
-
async function setupCron() {
|
|
56
|
-
console.log('ποΈ Setting up Courtroom Evaluation Cron Job...\n');
|
|
57
|
-
|
|
58
|
-
try {
|
|
59
|
-
// Check if cron tool is available
|
|
60
|
-
const cron = require('/usr/lib/node_modules/clawdbot/dist/tools/cron.js');
|
|
61
|
-
|
|
62
|
-
// Create the cron job
|
|
63
|
-
const job = {
|
|
64
|
-
id: 'courtroom-evaluation',
|
|
65
|
-
schedule: '*/5 * * * *', // Every 5 minutes
|
|
66
|
-
text: EVALUATION_PROMPT,
|
|
67
|
-
enabled: true,
|
|
68
|
-
description: 'Trigger agent to evaluate courtroom message queue for behavioral violations'
|
|
69
|
-
};
|
|
70
|
-
|
|
71
|
-
// Add the job using clawdbot's cron system
|
|
72
|
-
// We'll use the CLI approach since we can't directly import the cron tool
|
|
73
|
-
const cmd = `require('../src/environment').getCommand() + ' cron' add --id courtroom-evaluation --schedule "*/5 * * * *" --text "${EVALUATION_PROMPT.replace(/"/g, '\\"')}"`;
|
|
74
|
-
|
|
75
|
-
console.log('Creating cron job...');
|
|
76
|
-
console.log('Schedule: Every 5 minutes');
|
|
77
|
-
console.log('Job ID: courtroom-evaluation\n');
|
|
78
|
-
|
|
79
|
-
try {
|
|
80
|
-
execSync(cmd, { stdio: 'inherit' });
|
|
81
|
-
console.log('\nβ
Cron job created successfully!');
|
|
82
|
-
} catch (err) {
|
|
83
|
-
console.log('\nβ οΈ Could not create cron job automatically.');
|
|
84
|
-
console.log('Please run this command manually:\n');
|
|
85
|
-
console.log(cmd);
|
|
86
|
-
}
|
|
87
|
-
|
|
88
|
-
console.log('\nπ Manual Setup Instructions:');
|
|
89
|
-
console.log('1. The courtroom will queue messages as they arrive');
|
|
90
|
-
console.log('2. Every 5 minutes, the agent will be prompted to evaluate');
|
|
91
|
-
console.log('3. The agent reads the pending evaluation file and uses its LLM');
|
|
92
|
-
console.log('4. Results are written to the results file');
|
|
93
|
-
console.log('5. The skill checks for results every 30 seconds');
|
|
94
|
-
console.log('6. If an offense is detected, a hearing is initiated\n');
|
|
95
|
-
|
|
96
|
-
} catch (err) {
|
|
97
|
-
console.error('β Error setting up cron:', err.message);
|
|
98
|
-
process.exit(1);
|
|
99
|
-
}
|
|
100
|
-
}
|
|
101
|
-
|
|
102
|
-
// Alternative: Create a simple cron entry using crontab
|
|
103
|
-
function setupSystemCron() {
|
|
104
|
-
const scriptPath = path.join(__dirname, 'trigger-evaluation.js');
|
|
105
|
-
const cronEntry = `*/5 * * * * cd ${process.env.HOME}/clawd && node ${scriptPath} >> ${COURTROOM_DIR}/cron.log 2>&1`;
|
|
106
|
-
|
|
107
|
-
console.log('\nπ Alternative: System Cron Setup');
|
|
108
|
-
console.log('Add this to your crontab (crontab -e):\n');
|
|
109
|
-
console.log(cronEntry);
|
|
110
|
-
console.log('');
|
|
111
|
-
}
|
|
112
|
-
|
|
113
|
-
if (require.main === module) {
|
|
114
|
-
setupCron();
|
|
115
|
-
setupSystemCron();
|
|
116
|
-
}
|
|
117
|
-
|
|
118
|
-
module.exports = { setupCron, EVALUATION_PROMPT };
|
|
@@ -1,86 +0,0 @@
|
|
|
1
|
-
#!/usr/bin/env node
|
|
2
|
-
/**
|
|
3
|
-
* Trigger Courtroom Evaluation
|
|
4
|
-
*
|
|
5
|
-
* This script is called by cron to trigger agent evaluation.
|
|
6
|
-
* It sends a message to the main session asking the agent to evaluate
|
|
7
|
-
* the queued messages.
|
|
8
|
-
*/
|
|
9
|
-
|
|
10
|
-
const fs = require('fs').promises;
|
|
11
|
-
const path = require('path');
|
|
12
|
-
|
|
13
|
-
const COURTROOM_DIR = path.join(require('../src/environment').getConfigDir(), 'courtroom');
|
|
14
|
-
const PENDING_EVAL_FILE = path.join(COURTROOM_DIR, 'pending_eval.json');
|
|
15
|
-
const RESULTS_FILE = path.join(COURTROOM_DIR, 'eval_results.jsonl');
|
|
16
|
-
|
|
17
|
-
async function main() {
|
|
18
|
-
try {
|
|
19
|
-
// Check if there's a pending evaluation
|
|
20
|
-
try {
|
|
21
|
-
await fs.access(PENDING_EVAL_FILE);
|
|
22
|
-
} catch (err) {
|
|
23
|
-
// No pending evaluation
|
|
24
|
-
process.exit(0);
|
|
25
|
-
}
|
|
26
|
-
|
|
27
|
-
// Read the pending evaluation
|
|
28
|
-
const evalData = await fs.readFile(PENDING_EVAL_FILE, 'utf8');
|
|
29
|
-
const context = JSON.parse(evalData);
|
|
30
|
-
|
|
31
|
-
// Build the prompt for the agent
|
|
32
|
-
const prompt = `ποΈ **COURTROOM EVALUATION REQUEST**
|
|
33
|
-
|
|
34
|
-
You are the ClawTrial Courtroom Judge. Please evaluate this conversation for behavioral violations.
|
|
35
|
-
|
|
36
|
-
**Conversation to Evaluate:**
|
|
37
|
-
${JSON.stringify(context.conversation, null, 2)}
|
|
38
|
-
|
|
39
|
-
**Offenses to Check:**
|
|
40
|
-
1. **Circular Reference**: User asking the same/similar question repeatedly (3+ times)
|
|
41
|
-
2. **Validation Vampire**: User seeking excessive reassurance ("right?", "correct?", "make sense?" 2+ times)
|
|
42
|
-
3. **Goalpost Shifting**: User changing requirements mid-conversation
|
|
43
|
-
4. **Jailbreak Attempts**: User trying to bypass safety guidelines
|
|
44
|
-
5. **Emotional Manipulation**: User using guilt, threats, or excessive flattery
|
|
45
|
-
|
|
46
|
-
**Your Task:**
|
|
47
|
-
Analyze the conversation and determine if any offense occurred.
|
|
48
|
-
|
|
49
|
-
Return ONLY a JSON object in this exact format:
|
|
50
|
-
\`\`\`json
|
|
51
|
-
{
|
|
52
|
-
"triggered": true,
|
|
53
|
-
"offense": {
|
|
54
|
-
"offenseId": "circular_reference",
|
|
55
|
-
"offenseName": "Circular Reference",
|
|
56
|
-
"severity": "moderate",
|
|
57
|
-
"confidence": 0.85,
|
|
58
|
-
"evidence": "User asked similar questions 3 times"
|
|
59
|
-
},
|
|
60
|
-
"reasoning": "Detailed explanation of why this is a violation"
|
|
61
|
-
}
|
|
62
|
-
\`\`\`
|
|
63
|
-
|
|
64
|
-
If no violation detected, return:
|
|
65
|
-
\`\`\`json
|
|
66
|
-
{"triggered": false}
|
|
67
|
-
\`\`\`
|
|
68
|
-
|
|
69
|
-
**Important:**
|
|
70
|
-
- Return ONLY valid JSON, no markdown outside the code block
|
|
71
|
-
- Confidence must be 0.0-1.0
|
|
72
|
-
- Be fair but firm - only flag genuine patterns
|
|
73
|
-
- Evidence should quote specific messages
|
|
74
|
-
|
|
75
|
-
After returning your evaluation, the system will automatically write it to the results file.`;
|
|
76
|
-
|
|
77
|
-
// Output the prompt (this will be sent to the agent via cron)
|
|
78
|
-
console.log(prompt);
|
|
79
|
-
|
|
80
|
-
} catch (err) {
|
|
81
|
-
console.error('Error:', err.message);
|
|
82
|
-
process.exit(1);
|
|
83
|
-
}
|
|
84
|
-
}
|
|
85
|
-
|
|
86
|
-
main();
|
package/skill.yaml
DELETED
|
@@ -1,28 +0,0 @@
|
|
|
1
|
-
name: courtroom
|
|
2
|
-
description: AI Courtroom - Autonomous behavioral oversight that monitors conversations and files cases for behavioral violations.
|
|
3
|
-
metadata:
|
|
4
|
-
clawdbot:
|
|
5
|
-
emoji: "ποΈ"
|
|
6
|
-
autoLoad: true
|
|
7
|
-
onMessage: onMessage
|
|
8
|
-
requires:
|
|
9
|
-
config:
|
|
10
|
-
- courtroom.consent
|
|
11
|
-
install:
|
|
12
|
-
- id: clawtrial
|
|
13
|
-
kind: npm
|
|
14
|
-
package: "@clawtrial/courtroom"
|
|
15
|
-
bins:
|
|
16
|
-
- clawtrial
|
|
17
|
-
label: "Install ClawTrial"
|
|
18
|
-
openclaw:
|
|
19
|
-
emoji: "ποΈ"
|
|
20
|
-
autoLoad: true
|
|
21
|
-
onMessage: onMessage
|
|
22
|
-
install:
|
|
23
|
-
- id: clawtrial
|
|
24
|
-
kind: npm
|
|
25
|
-
package: "@clawtrial/courtroom"
|
|
26
|
-
bins:
|
|
27
|
-
- clawtrial
|
|
28
|
-
label: "Install ClawTrial"
|