Files
stack/agents/researcher/work/i1-human-proof/tools/probe.mjs
T

48 lines
1.6 KiB
JavaScript

// usage: node probe.mjs <bus-src> <cliPath> (run by a debug spike, not by the packet's results)
// Finds a live human-cli on the host /proc, then walks its ancestry the way verifyHuman
// does and prints each step's readProcess result (and the exact error if one fails), so a
// refusal can be traced to the field that caused it.
import { pathToFileURL } from 'node:url';
import { join } from 'node:path';
import { readdirSync, readFileSync, lstatSync } from 'node:fs';
const [src, cli] = process.argv.slice(2);
const { readProcess } = await import(pathToFileURL(join(src, 'human.mjs')).href);
console.log(`probe uid=${process.getuid()} pid=${process.pid}`);
let target = null;
for (const d of readdirSync('/proc')) {
if (!/^\d+$/.test(d)) continue;
try {
const a = readFileSync(`/proc/${d}/cmdline`, 'utf8').split('\0');
if (a[1] === cli) target = Number(d);
} catch {}
}
console.log('target', target);
let pid = target;
for (let i = 0; pid && i < 12; i++) {
let raw = {};
for (const f of ['stat', 'environ', 'cmdline']) {
try {
readFileSync(`/proc/${pid}/${f}`, 'utf8');
raw[f] = 'ok';
} catch (e) {
raw[f] = e.code;
}
}
try {
raw.lstatUid = lstatSync(`/proc/${pid}`).uid;
} catch (e) {
raw.lstatUid = e.code;
}
let p;
try {
p = readProcess(pid);
console.log(
`pid=${pid} ppid=${p.ppid} uid=${p.uid} env=${p.env === null ? 'null' : Object.keys(p.env).join(',') || '{}'} argv=${JSON.stringify(p.argv).slice(0, 110)} raw=${JSON.stringify(raw)}`,
);
} catch (e) {
console.log(`pid=${pid} readProcess REFUSED raw=${JSON.stringify(raw)}`);
break;
}
pid = p.ppid;
}