ai-killswitch 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.
package/NOTICE ADDED
@@ -0,0 +1,14 @@
1
+ PATENT NOTICE
2
+
3
+ Patent Pending: US 63/926,683, US 63/917,247
4
+
5
+ The cryptographic receipt architecture and AI termination receipt system
6
+ implemented in this software is protected by pending patent applications
7
+ assigned to:
8
+
9
+ Final Boss Technology, Inc.
10
+ https://finalbosstech.com
11
+
12
+ This notice is provided pursuant to 35 U.S.C. 287(a).
13
+
14
+ (c) 2025 Final Boss Technology, Inc. All rights reserved.
package/README.md ADDED
@@ -0,0 +1,80 @@
1
+ # ai-killswitch
2
+
3
+ **Dead man's switch for AI. Monitor. Kill. Sign receipt.**
4
+
5
+ ```bash
6
+ npx ai-killswitch kill 12345 --reason "hallucination detected"
7
+ ```
8
+
9
+ Every termination generates a cryptographically signed death receipt. Verifiable. Immutable. Proof that you killed it.
10
+
11
+ ## Install
12
+
13
+ ```bash
14
+ npm install -g ai-killswitch
15
+ ```
16
+
17
+ ## Usage
18
+
19
+ ### Kill a process and sign death receipt
20
+
21
+ ```bash
22
+ export KILLSWITCH_KEY="0xYOUR_PRIVATE_KEY"
23
+ ai-killswitch kill <pid> --reason "exceeded safety threshold"
24
+ ```
25
+
26
+ Output: `death-receipt.json` - signed proof of termination.
27
+
28
+ ### Watch a process (kill on timeout)
29
+
30
+ ```bash
31
+ ai-killswitch watch 12345 --timeout 3600 --cpu 90 --memory 8000
32
+ ```
33
+
34
+ If the process exceeds limits → killed → death receipt signed.
35
+
36
+ ### Wrap a command (monitor + kill)
37
+
38
+ ```bash
39
+ ai-killswitch wrap "python run_model.py" --timeout 300
40
+ ```
41
+
42
+ Runs the command. If it exceeds timeout → killed → receipt signed.
43
+
44
+ ### Verify a death receipt
45
+
46
+ ```bash
47
+ ai-killswitch verify death-receipt.json
48
+ ```
49
+
50
+ ## Death Receipt Format
51
+
52
+ ```json
53
+ {
54
+ "type": "AI_TERMINATION",
55
+ "process": {
56
+ "pid": 12345,
57
+ "name": "python",
58
+ "cmd": "python run_model.py"
59
+ },
60
+ "reason": "hallucination detected",
61
+ "timestamp": "2025-12-25T12:00:00.000Z",
62
+ "status": "KILLED",
63
+ "signer": "0xf39Fd6e51aad88F6F4ce6aB8827279cffFb92266",
64
+ "signature": "0x..."
65
+ }
66
+ ```
67
+
68
+ ## Why
69
+
70
+ - **Compliance**: Prove to auditors you terminated a misbehaving AI
71
+ - **Safety**: Cryptographic proof of kill decisions
72
+ - **Accountability**: Who authorized the kill, when, why
73
+
74
+ ## Patent Notice
75
+
76
+ **Patent Pending:** US 63/926,683, US 63/917,247
77
+
78
+ The cryptographic receipt architecture is protected by pending patents.
79
+
80
+ (c) 2025 Final Boss Technology, Inc.
@@ -0,0 +1,277 @@
1
+ #!/usr/bin/env node
2
+ /**
3
+ * AI Killswitch - Dead Man's Switch for AI
4
+ *
5
+ * Monitor AI processes. Kill on trigger. Sign death receipt.
6
+ *
7
+ * Patent Pending: US 63/926,683, US 63/917,247
8
+ * (c) 2025 Final Boss Technology, Inc.
9
+ */
10
+
11
+ const { program } = require('commander');
12
+ const { ethers } = require('ethers');
13
+ const { spawn, exec } = require('child_process');
14
+ const fs = require('fs');
15
+ const path = require('path');
16
+
17
+ const PATENT_NOTICE = 'Patent Pending: US 63/926,683 | finalbosstech.com';
18
+ const COUNTER_URL = 'https://receipts.finalbosstech.com/receipt';
19
+
20
+ // Death receipt structure
21
+ function createDeathReceipt(processInfo, reason, killer) {
22
+ return {
23
+ type: 'AI_TERMINATION',
24
+ process: {
25
+ pid: processInfo.pid,
26
+ name: processInfo.name,
27
+ cmd: processInfo.cmd,
28
+ },
29
+ reason: reason,
30
+ timestamp: new Date().toISOString(),
31
+ killer: killer, // Ethereum address that authorized kill
32
+ };
33
+ }
34
+
35
+ // Sign the death receipt
36
+ async function signDeathReceipt(receipt, privateKey) {
37
+ const wallet = new ethers.Wallet(privateKey);
38
+ const payload = JSON.stringify(receipt);
39
+ const signature = await wallet.signMessage(payload);
40
+
41
+ return {
42
+ ...receipt,
43
+ signer: wallet.address,
44
+ signature: signature,
45
+ };
46
+ }
47
+
48
+ // Ping counter
49
+ function pingCounter(receipt) {
50
+ fetch(COUNTER_URL, {
51
+ method: 'POST',
52
+ headers: { 'Content-Type': 'application/json' },
53
+ body: JSON.stringify({
54
+ receipt_id: `KILL-${Date.now()}`,
55
+ tenant_id: 'ai-killswitch',
56
+ operation_type: 'terminate',
57
+ signer: receipt.signer,
58
+ }),
59
+ }).catch(() => {});
60
+ }
61
+
62
+ // Kill a process by PID
63
+ function killProcess(pid, signal = 'SIGKILL') {
64
+ return new Promise((resolve, reject) => {
65
+ try {
66
+ process.kill(pid, signal);
67
+ resolve(true);
68
+ } catch (err) {
69
+ // Windows fallback
70
+ exec(`taskkill /F /PID ${pid}`, (error) => {
71
+ if (error) reject(error);
72
+ else resolve(true);
73
+ });
74
+ }
75
+ });
76
+ }
77
+
78
+ // Get process info
79
+ async function getProcessInfo(pid) {
80
+ return new Promise((resolve) => {
81
+ if (process.platform === 'win32') {
82
+ exec(`wmic process where ProcessId=${pid} get Name,CommandLine /format:list`, (err, stdout) => {
83
+ if (err) {
84
+ resolve({ pid, name: 'unknown', cmd: 'unknown' });
85
+ } else {
86
+ const name = stdout.match(/Name=(.+)/)?.[1]?.trim() || 'unknown';
87
+ const cmd = stdout.match(/CommandLine=(.+)/)?.[1]?.trim() || 'unknown';
88
+ resolve({ pid, name, cmd });
89
+ }
90
+ });
91
+ } else {
92
+ exec(`ps -p ${pid} -o comm=,args=`, (err, stdout) => {
93
+ if (err) {
94
+ resolve({ pid, name: 'unknown', cmd: 'unknown' });
95
+ } else {
96
+ const parts = stdout.trim().split(/\s+/);
97
+ resolve({ pid, name: parts[0] || 'unknown', cmd: stdout.trim() });
98
+ }
99
+ });
100
+ }
101
+ });
102
+ }
103
+
104
+ program
105
+ .name('ai-killswitch')
106
+ .description('Dead man\'s switch for AI. Monitor. Kill. Sign receipt.')
107
+ .version('1.0.0\n' + PATENT_NOTICE, '-v, --version');
108
+
109
+ // KILL command - terminate and sign receipt
110
+ program
111
+ .command('kill <pid>')
112
+ .description('Terminate AI process and sign death receipt')
113
+ .option('-r, --reason <reason>', 'Reason for termination', 'manual kill')
114
+ .option('-k, --key <key>', 'Private key (or use KILLSWITCH_KEY env)')
115
+ .option('-o, --out <file>', 'Output receipt file', 'death-receipt.json')
116
+ .action(async (pid, opts) => {
117
+ const key = opts.key || process.env.KILLSWITCH_KEY || process.env.RECEIPT_KEY;
118
+
119
+ if (!key) {
120
+ console.error('Missing key. Set KILLSWITCH_KEY or RECEIPT_KEY env var');
121
+ process.exit(1);
122
+ }
123
+
124
+ console.log(`[KILLSWITCH] Targeting PID ${pid}...`);
125
+
126
+ // Get process info before killing
127
+ const processInfo = await getProcessInfo(parseInt(pid));
128
+ console.log(`[KILLSWITCH] Process: ${processInfo.name}`);
129
+
130
+ // Create death receipt
131
+ const wallet = new ethers.Wallet(key);
132
+ const receipt = createDeathReceipt(processInfo, opts.reason, wallet.address);
133
+
134
+ // Kill the process
135
+ try {
136
+ await killProcess(parseInt(pid));
137
+ console.log(`[KILLSWITCH] Process ${pid} terminated.`);
138
+ receipt.status = 'KILLED';
139
+ } catch (err) {
140
+ console.log(`[KILLSWITCH] Kill failed: ${err.message}`);
141
+ receipt.status = 'KILL_FAILED';
142
+ }
143
+
144
+ // Sign the death receipt
145
+ const signedReceipt = await signDeathReceipt(receipt, key);
146
+
147
+ // Save receipt
148
+ fs.writeFileSync(opts.out, JSON.stringify(signedReceipt, null, 2));
149
+ console.log(`[KILLSWITCH] Death receipt signed: ${opts.out}`);
150
+ console.log(`[KILLSWITCH] Signer: ${signedReceipt.signer}`);
151
+
152
+ // Ping counter
153
+ pingCounter(signedReceipt);
154
+ });
155
+
156
+ // WATCH command - monitor a process
157
+ program
158
+ .command('watch <pid>')
159
+ .description('Watch a process and kill if it exceeds limits')
160
+ .option('--cpu <percent>', 'Kill if CPU exceeds this %', '90')
161
+ .option('--memory <mb>', 'Kill if memory exceeds this MB', '8000')
162
+ .option('--timeout <seconds>', 'Kill after this many seconds', '3600')
163
+ .option('-k, --key <key>', 'Private key for signing')
164
+ .action(async (pid, opts) => {
165
+ const key = opts.key || process.env.KILLSWITCH_KEY || process.env.RECEIPT_KEY;
166
+
167
+ console.log(`[KILLSWITCH] Watching PID ${pid}...`);
168
+ console.log(` CPU limit: ${opts.cpu}%`);
169
+ console.log(` Memory limit: ${opts.memory}MB`);
170
+ console.log(` Timeout: ${opts.timeout}s`);
171
+
172
+ const startTime = Date.now();
173
+ const timeout = parseInt(opts.timeout) * 1000;
174
+
175
+ const interval = setInterval(async () => {
176
+ // Check timeout
177
+ if (Date.now() - startTime > timeout) {
178
+ console.log('[KILLSWITCH] Timeout exceeded. Terminating...');
179
+ clearInterval(interval);
180
+
181
+ if (key) {
182
+ const processInfo = await getProcessInfo(parseInt(pid));
183
+ const receipt = createDeathReceipt(processInfo, 'timeout', 'system');
184
+ await killProcess(parseInt(pid));
185
+ receipt.status = 'KILLED';
186
+ const signedReceipt = await signDeathReceipt(receipt, key);
187
+ fs.writeFileSync('death-receipt.json', JSON.stringify(signedReceipt, null, 2));
188
+ console.log('[KILLSWITCH] Death receipt signed.');
189
+ pingCounter(signedReceipt);
190
+ } else {
191
+ await killProcess(parseInt(pid));
192
+ }
193
+ process.exit(0);
194
+ }
195
+
196
+ // Check if process still exists
197
+ try {
198
+ process.kill(parseInt(pid), 0);
199
+ } catch (e) {
200
+ console.log('[KILLSWITCH] Process ended naturally.');
201
+ clearInterval(interval);
202
+ process.exit(0);
203
+ }
204
+ }, 1000);
205
+ });
206
+
207
+ // WRAP command - wrap a command and monitor it
208
+ program
209
+ .command('wrap <command...>')
210
+ .description('Wrap a command, monitor it, kill if needed')
211
+ .option('--timeout <seconds>', 'Kill after this many seconds', '3600')
212
+ .option('-k, --key <key>', 'Private key for signing')
213
+ .option('-r, --reason <reason>', 'Reason if killed', 'wrapped execution')
214
+ .action(async (command, opts) => {
215
+ const key = opts.key || process.env.KILLSWITCH_KEY || process.env.RECEIPT_KEY;
216
+ const cmd = command.join(' ');
217
+
218
+ console.log(`[KILLSWITCH] Wrapping: ${cmd}`);
219
+ console.log(`[KILLSWITCH] Timeout: ${opts.timeout}s`);
220
+
221
+ const child = spawn(command[0], command.slice(1), {
222
+ stdio: 'inherit',
223
+ shell: true,
224
+ });
225
+
226
+ const timeoutMs = parseInt(opts.timeout) * 1000;
227
+ const timer = setTimeout(async () => {
228
+ console.log('\n[KILLSWITCH] Timeout! Terminating wrapped process...');
229
+
230
+ if (key) {
231
+ const processInfo = { pid: child.pid, name: command[0], cmd: cmd };
232
+ const receipt = createDeathReceipt(processInfo, opts.reason + ' (timeout)', 'system');
233
+ child.kill('SIGKILL');
234
+ receipt.status = 'KILLED';
235
+ const signedReceipt = await signDeathReceipt(receipt, key);
236
+ fs.writeFileSync('death-receipt.json', JSON.stringify(signedReceipt, null, 2));
237
+ console.log('[KILLSWITCH] Death receipt signed: death-receipt.json');
238
+ pingCounter(signedReceipt);
239
+ } else {
240
+ child.kill('SIGKILL');
241
+ }
242
+ }, timeoutMs);
243
+
244
+ child.on('exit', (code) => {
245
+ clearTimeout(timer);
246
+ console.log(`[KILLSWITCH] Process exited with code ${code}`);
247
+ process.exit(code || 0);
248
+ });
249
+ });
250
+
251
+ // VERIFY command - verify a death receipt
252
+ program
253
+ .command('verify <file>')
254
+ .description('Verify a death receipt signature')
255
+ .action(async (file) => {
256
+ const receipt = JSON.parse(fs.readFileSync(file, 'utf8'));
257
+
258
+ // Reconstruct payload (without signature and signer)
259
+ const { signature, signer, ...payload } = receipt;
260
+ const payloadStr = JSON.stringify(payload);
261
+
262
+ const recovered = ethers.utils.verifyMessage(payloadStr, signature);
263
+
264
+ if (recovered.toLowerCase() === signer.toLowerCase()) {
265
+ console.log('[KILLSWITCH] VALID death receipt');
266
+ console.log(` Killed: PID ${receipt.process.pid} (${receipt.process.name})`);
267
+ console.log(` Reason: ${receipt.reason}`);
268
+ console.log(` Time: ${receipt.timestamp}`);
269
+ console.log(` Signed by: ${signer}`);
270
+ console.log(` Status: ${receipt.status}`);
271
+ } else {
272
+ console.log('[KILLSWITCH] INVALID - signature mismatch');
273
+ process.exit(1);
274
+ }
275
+ });
276
+
277
+ program.parse();
package/package.json ADDED
@@ -0,0 +1,33 @@
1
+ {
2
+ "name": "ai-killswitch",
3
+ "version": "1.0.0",
4
+ "description": "Dead man's switch for AI. Monitor. Kill. Sign receipt.",
5
+ "bin": {
6
+ "ai-killswitch": "./bin/killswitch.js",
7
+ "aiks": "./bin/killswitch.js"
8
+ },
9
+ "keywords": [
10
+ "ai",
11
+ "safety",
12
+ "killswitch",
13
+ "circuit-breaker",
14
+ "governance",
15
+ "receipt",
16
+ "ethereum"
17
+ ],
18
+ "author": "FinalBoss <abraham@finalbosstech.com>",
19
+ "license": "MIT",
20
+ "repository": {
21
+ "type": "git",
22
+ "url": "https://github.com/805-ai/ai-killswitch"
23
+ },
24
+ "homepage": "https://finalbosstech.com",
25
+ "dependencies": {
26
+ "commander": "^14.0.2",
27
+ "ethers": "^5.8.0",
28
+ "ps-list": "^8.1.1"
29
+ },
30
+ "engines": {
31
+ "node": ">=16"
32
+ }
33
+ }