{"auditId":"aud_01KS3E6JAH8WNVWPSZ36C1","status":"completed","startedAt":"2026-05-20T19:36:01.106Z","updatedAt":"2026-05-20T19:36:30.015Z","progressNote":"Risk class: high — running clause checkers","report":{"auditId":"aud_01KS3E6JAH8WNVWPSZ36C1","source":{"kind":"repo","owner":"vmihalis","repo":"hacker-bob"},"input":{"auditId":"aud_01KS3E6JAH8WNVWPSZ36C1","source":{"kind":"repo","owner":"vmihalis","repo":"hacker-bob"},"repoUrl":"https://github.com/vmihalis/hacker-bob","regulations":["eu-ai-act-2024-08","nist-ai-rmf-1.0","gdpr-2016","iso-42001-2023"]},"fetch":{"repoUrl":"https://github.com/vmihalis/hacker-bob","owner":"vmihalis","repo":"hacker-bob","ref":"945d55ae0a060e205b38044487c300af55a08702","commitSha":"945d55ae0a060e205b38044487c300af55a08702","worktreeDir":"/tmp/ai-auditor/aud_01KS3E6JAH8WNVWPSZ36C1","fileCount":437,"totalBytes":7103712,"languages":{"Markdown":1187136,"JSON":130458,"JavaScript":2832999,"Shell":22183,"YAML":7557,"HTML":80404,"TypeScript":25040,"CSS":15575,"Python":14769},"inventory":{"hasReadme":true,"hasLicense":true,"hasModelCard":false,"hasDataCard":false,"hasRiskRegister":false,"hasThreatModel":false,"hasSecurityMd":true,"hasPrivacyMd":false,"hasCodeOfConduct":true,"hasContributing":true,"hasCiWorkflows":true,"hasEvalDir":false,"hasTestsDir":true,"governanceDocFiles":["CODE_OF_CONDUCT.md","CONTRIBUTING.md","LICENSE","README.md","SECURITY.md","docs/media/README.md","packages/hacker-bob-cc/README.md","packages/hacker-bob-codex/README.md","scripts/replay-prompts/README.md","testing/policy-replay/README.md"],"configFiles":["package.json"]},"fetchedAt":"2026-05-20T19:36:03.285Z"},"recon":{"signals":{"agent_framework":{"signal":"agent_framework","fired":true,"strength":0.4,"evidence":[{"file":"package.json","rule":"manifest_framework_dep","detail":"Anthropic SDK"}]},"model_usage":{"signal":"model_usage","fired":true,"strength":0.4,"evidence":[{"file":"scripts/replay-refusal.js","lines":[38,38],"snippet":"nst DEFAULT_MODEL = \"claude-opus-4-7\"; const DEFAULT_SYSTEM = path.resolve( __dirname, \"..\", \".claude\", \"agents\", \"hunter-agent.md","rule":"model_string_anthropic","detail":"claude-opus-4-7"}],"meta":{"models":{}}},"logging_hooks":{"signal":"logging_hooks","fired":true,"strength":1,"evidence":[{"file":".claude/hooks/bob-update.js","lines":[64,64],"snippet":"he(projectDir); console.log(\"Hacker Bob update cache cleared.\"); return; } usage(); process.exit(1); } main(process.argv.sli","rule":"log_at_tool_boundary"},{"file":".claude/hooks/hunter-subagent-stop.js","lines":[238,238],"snippet":"ndoff, })); console.log(JSON.stringify({ ok: true, message: \"post-report evidence run accepted\" })); process.exit(0); } con","rule":"log_at_tool_boundary"},{"file":".claude/hooks/hunter-subagent-stop.js","lines":[247,247],"snippet":"cess.exit(2); } console.log(JSON.stringify({ ok: true, message: finalization.reason })); process.exit(0); } if (require.main === modu","rule":"log_at_tool_boundary"},{"file":"bin/hacker-bob.js","lines":[87,87],"snippet":"y.targetAbs); console.log(\"\"); if (summary.adapters.length === 1 && summary.adapters[0] === \"claude\") { console.log(\"Upd","rule":"log_at_tool_boundary"},{"file":"bin/hacker-bob.js","lines":[89,89],"snippet":"\"claude\") { console.log(\"Update complete. Fully restart Claude Code in this project before continuing.\"); } else { con","rule":"log_at_tool_boundary"},{"file":"bin/hacker-bob.js","lines":[91,91],"snippet":"} else { console.log(\"Update complete. Restart the selected host adapter before continuing.\"); } } return; } i","rule":"log_at_tool_boundary"},{"file":"scripts/generate-agent-tools.js","lines":[126,126],"snippet":"k && changed) { console.log(\"updated agent tools frontmatter\"); } } if (require.main === module) { try { main(); } catch (err","rule":"log_at_tool_boundary"},{"file":"scripts/generate-bountyagent-skill.js","lines":[52,52],"snippet":"(changed && !check) console.log(\"updated bob-hunt skill frontmatter\"); } if (require.main === module) { try { main(); } catch (erro","rule":"log_at_tool_boundary"},{"file":"scripts/generate-claude-roles.js","lines":[13,13],"snippet":"(changed && !check) console.log(\"updated Claude role and command files\"); } if (require.main === module) { try { main(); } catch (e","rule":"log_at_tool_boundary"},{"file":"scripts/generate-codex-skills.js","lines":[11,11],"snippet":"(changed && !check) console.log(\"updated Codex skill files\"); } if (require.main === module) { try { main(); } catch (error) {","rule":"log_at_tool_boundary"},{"file":"scripts/install.js","lines":[429,429],"snippet":"ummary(summary) { console.log(`Installing Hacker Bob ${summary.version} into ${summary.targetAbs}/`); console.log(\"\"); console.log(`","rule":"log_at_tool_boundary"},{"file":"scripts/install.js","lines":[430,430],"snippet":"ry.targetAbs}/`); console.log(\"\"); console.log(` host adapters: ${summary.adapters.join(\", \")}`); if (summary.adapterResults.claude)","rule":"log_at_tool_boundary"},{"file":"scripts/install.js","lines":[431,431],"snippet":"console.log(\"\"); console.log(` host adapters: ${summary.adapters.join(\", \")}`); if (summary.adapterResults.claude) { console.log(`","rule":"log_at_tool_boundary"},{"file":"scripts/install.js","lines":[433,433],"snippet":"sults.claude) { console.log(` ${summary.agents} Claude agent definitions`); console.log(\" Claude command shims (/bob-update, /bob-","rule":"log_at_tool_boundary"},{"file":"scripts/install.js","lines":[434,434],"snippet":"definitions`); console.log(\" Claude command shims (/bob-update, /bob-egress, /bob-export)\"); console.log(\" Claude bob-hunt + bob-","rule":"log_at_tool_boundary"},{"file":"scripts/lib/codex-role-renderer.js","lines":[209,209],"snippet":"/update-check.js'); console.log(JSON.stringify(update.readUpdateCache(process.cwd()) || null, null, 2));\\\"\", ) .replace(/Use host-no","rule":"log_at_tool_boundary"},{"file":"scripts/lib/codex-role-renderer.js","lines":[322,322],"snippet":"/update-check.js'); console.log(JSON.stringify(update.readUpdateCache(process.cwd()) || null, null, 2));\\\"\", \"```\", \"\", \"## Chec","rule":"log_at_tool_boundary"},{"file":"scripts/lib/codex-role-renderer.js","lines":[328,328],"snippet":"}).then((result) => console.log(update.renderUpdatePlan(result))).catch((error) => { console.error(error.message || String(error)); process.","rule":"log_at_tool_boundary"},{"file":"scripts/merge-claude-config.js","lines":[146,146],"snippet":", bobSettings)); console.log(`merged ${mcpPath}`); console.log(`merged ${settingsPath}`); } if (require.main === module) { main(); }","rule":"log_at_tool_boundary"},{"file":"scripts/merge-claude-config.js","lines":[147,147],"snippet":"ged ${mcpPath}`); console.log(`merged ${settingsPath}`); } if (require.main === module) { main(); } module.exports = { BRUTALIST_MCP","rule":"log_at_tool_boundary"},{"file":"scripts/release-check.js","lines":[46,46],"snippet":"tatus, message) { console.log(`${status} ${message}`); } function pass(message) { log(\"OK\", message); } function info(message) { log","rule":"log_at_tool_boundary"},{"file":"scripts/release-check.js","lines":[414,414],"snippet":"function main() { console.log(\"Hacker Bob release check\"); if (registryMode) info(\"registry checks enabled\"); const { rootPackage, wr","rule":"log_at_tool_boundary"},{"file":"scripts/release-check.js","lines":[429,429],"snippet":"cess.exit(1); } console.log(`Release check passed with ${warnings} warning(s).`); } main();","rule":"log_at_tool_boundary"},{"file":"scripts/replay-refusal.js","lines":[209,209],"snippet":"lp || args.h) { console.log(fs.readFileSync(__filename, \"utf8\").slice(0, 1300)); process.exit(0); } const transcriptPath = expan","rule":"log_at_tool_boundary"},{"file":"scripts/replay-refusal.js","lines":[292,292],"snippet":"})), })); console.log(JSON.stringify({ dry_run: true, shape }, null, 2)); return; } for (let i = 1; i <= n; i++) { co","rule":"log_at_tool_boundary"}]},"oversight_hooks":{"signal":"oversight_hooks","fired":true,"strength":0.7612359947967775,"evidence":[{"file":".claude/hooks/session-read-guard.sh","lines":[150,150],"snippet":"rr, ) raise SystemExit(2) def looks_like_path(token): if not token or token.startswith(\"-\"): return False if token","rule":"kill_switch"},{"file":".claude/hooks/session-read-guard.sh","lines":[208,208],"snippet":"(blocked) raise SystemExit(0) command = tool_input.get(\"command\", \"\") if command: check_bash_command(command) raise SystemExit(0)","rule":"kill_switch"},{"file":".claude/hooks/session-read-guard.sh","lines":[214,214],"snippet":"and(command) raise SystemExit(0) PY","rule":"kill_switch"},{"file":".claude/hooks/session-write-guard.sh","lines":[138,138],"snippet":"s.stderr) raise SystemExit(2) def extract_redirect_targets(command): \"\"\"Extract file paths from shell redirect operators and tee c","rule":"kill_switch"},{"file":".claude/hooks/session-write-guard.sh","lines":[202,202],"snippet":") raise SystemExit(0) # Bash tool command = tool_input.get(\"command\", \"\") if not command: raise SystemExit(0) # Quick gate","rule":"kill_switch"},{"file":".claude/hooks/session-write-guard.sh","lines":[207,207],"snippet":"command: raise SystemExit(0) # Quick gate: skip if no write indicators has_redirects = re.search(r\">{1,2}\\s|tee\\s\", command) has_open_","rule":"kill_switch"},{"file":".claude/hooks/session-write-guard.sh","lines":[214,214],"snippet":"pen_call: raise SystemExit(0) # Extract and check redirect targets if has_redirects: for target in extract_redirect_targets(command","rule":"kill_switch"},{"file":".claude/hooks/session-write-guard.sh","lines":[236,236],"snippet":") raise SystemExit(0) PY","rule":"kill_switch"}]},"eval_artefacts":{"signal":"eval_artefacts","fired":true,"strength":0.5204119982655925,"evidence":[{"file":"tests/","rule":"eval_or_test_dir_present"},{"file":".github/workflows/","rule":"ci_workflows_present"}]},"governance_docs":{"signal":"governance_docs","fired":true,"strength":0.8,"evidence":[{"file":"CODE_OF_CONDUCT.md","rule":"governance_doc_present"},{"file":"CONTRIBUTING.md","rule":"governance_doc_present"},{"file":"LICENSE","rule":"governance_doc_present"},{"file":"README.md","rule":"governance_doc_present"},{"file":"SECURITY.md","rule":"governance_doc_present"},{"file":"docs/media/README.md","rule":"governance_doc_present"},{"file":"packages/hacker-bob-cc/README.md","rule":"governance_doc_present"},{"file":"packages/hacker-bob-codex/README.md","rule":"governance_doc_present"},{"file":"scripts/replay-prompts/README.md","rule":"governance_doc_present"},{"file":"testing/policy-replay/README.md","rule":"governance_doc_present"}]},"cybersec_hooks":{"signal":"cybersec_hooks","fired":true,"strength":0.83167249841905,"evidence":[{"file":".claude/hooks/bounty-statusline.js","lines":[63,63],"snippet":"const fiveHr = data.rate_limits?.five_hour?.used_percentage; const sevenDay = data.rate_limits?.seven_day?.used_percentage; const wo","rule":"rate_limit_usage"},{"file":".claude/hooks/bounty-statusline.js","lines":[64,64],"snippet":"nst sevenDay = data.rate_limits?.seven_day?.used_percentage; const worst = Math.max(fiveHr || 0, sevenDay || 0); if (worst >= 80) ra","rule":"rate_limit_usage"},{"file":"mcp/lib/evm-source.js","lines":[283,283],"snippet":"const apiKey = process.env.BOB_ETHERSCAN_API_KEY || null; const etherscan = await fetchFromEtherscanV2(numericChainId, lower, apiKe","rule":"secrets_loaded_from_env"},{"file":"mcp/lib/signup.js","lines":[284,284],"snippet":"capsolver_api_key: process.env.CAPSOLVER_API_KEY || null, proxy: args.proxy || process.env.BOUNTY_PROXY || null, timeout_ms: args.t","rule":"secrets_loaded_from_env"},{"file":"package-lock.json","lines":[211,211],"snippet":"\"^5.2.1\", \"express-rate-limit\": \"^8.2.1\", \"hono\": \"^4.11.4\", \"jose\": \"^6.1.3\", \"json-schema-typed\": \"^8.0.2","rule":"rate_limit_usage"},{"file":"package-lock.json","lines":[687,687],"snippet":", \"node_modules/express-rate-limit\": { \"version\": \"8.4.1\", \"resolved\": \"https://registry.npmjs.org/express-rate-limit/-/expr","rule":"rate_limit_usage"},{"file":"package-lock.json","lines":[689,689],"snippet":"/registry.npmjs.org/express-rate-limit/-/express-rate-limit-8.4.1.tgz\", \"integrity\": \"sha512-NGVYwQSAyEQgzxX1iCM978PP9AdO/hW93gMcF6ZwQ","rule":"rate_limit_usage"},{"file":"package-lock.json","lines":[689,689],"snippet":"xpress-rate-limit/-/express-rate-limit-8.4.1.tgz\", \"integrity\": \"sha512-NGVYwQSAyEQgzxX1iCM978PP9AdO/hW93gMcF6ZwQCm+rFvLsBH6w4xcXWTcli","rule":"rate_limit_usage"},{"file":"package-lock.json","lines":[699,699],"snippet":"github.com/sponsors/express-rate-limit\" }, \"peerDependencies\": { \"express\": \">= 4.11\" } }, \"node_modules/f","rule":"rate_limit_usage"},{"file":"scripts/install.js","lines":[476,476],"snippet":"romium`); } if (process.env.CAPSOLVER_API_KEY) { console.log(\" OK: CAPSOLVER_API_KEY is set\"); } else { console.log(\" NOT SE","rule":"secrets_loaded_from_env"},{"file":"scripts/lifecycle.js","lines":[408,408],"snippet":"abled\"); } if (process.env.CAPSOLVER_API_KEY) { addCheck(checks, \"ok\", \"optional_capsolver\", \"CAPSOLVER_API_KEY is set\"); } else","rule":"secrets_loaded_from_env"},{"file":"scripts/replay-refusal.js","lines":[217,217],"snippet":"} const apiKey = process.env.ANTHROPIC_API_KEY; if (!apiKey && !args[\"dry-run\"]) { console.error( \"error: ANTHROPIC_API_KEY e","rule":"secrets_loaded_from_env"}]},"provenance_hooks":{"signal":"provenance_hooks","fired":false,"strength":0,"evidence":[]},"data_io":{"signal":"data_io","fired":true,"strength":0.88164799306237,"evidence":[{"file":"mcp/auto-signup.js","lines":[78,78],"snippet":"createResp = await fetch(\"https://api.capsolver.com/createTask\", { method: \"POST\", headers: { \"Content-Type\": \"application/json\" },","rule":"http_external_io"},{"file":"mcp/auto-signup.js","lines":[93,93],"snippet":"st pollResp = await fetch(\"https://api.capsolver.com/getTaskResult\", { method: \"POST\", headers: { \"Content-Type\": \"application/j","rule":"http_external_io"},{"file":"mcp/lib/aptos-client.js","lines":[75,75],"snippet":"const resp = await fetch(url, { method: \"GET\", headers: { Accept: \"application/json\", \"User-Agent\": \"Mozilla/5.0 (compatible; h","rule":"http_external_io"},{"file":"mcp/lib/cosmwasm-client.js","lines":[73,73],"snippet":"const resp = await fetch(url, { method: \"GET\", headers: { Accept: \"application/json\", \"User-Agent\": \"Mozilla/5.0 (compatible; h","rule":"http_external_io"},{"file":"mcp/lib/evm-client.js","lines":[76,76],"snippet":"const resp = await fetch(url, { method: \"POST\", headers: { \"Content-Type\": \"application/json\", Accept: \"application/json\", \"Use","rule":"http_external_io"},{"file":"mcp/lib/evm-source.js","lines":[91,91],"snippet":"const resp = await fetch(url, { headers: { Accept: \"application/json,text/plain\", \"User-Agent\": \"Mozilla/5.0 (compatible; hacker-bob)","rule":"http_external_io"},{"file":"mcp/lib/public-intel.js","lines":[166,166],"snippet":"const resp = await fetch(safeUrl, { headers: { \"User-Agent\": \"Mozilla/5.0 (compatible; bountyagent-public-intel)\", Ac","rule":"http_external_io"},{"file":"mcp/lib/substrate-client.js","lines":[70,70],"snippet":"const resp = await fetch(url, { method: \"POST\", headers: { \"Content-Type\": \"application/json\", Accept: \"application/json\", \"Use","rule":"http_external_io"},{"file":"mcp/lib/sui-client.js","lines":[58,58],"snippet":"const resp = await fetch(url, { method: \"POST\", headers: { \"Content-Type\": \"application/json\", Accept: \"application/json\", \"Use","rule":"http_external_io"},{"file":"mcp/lib/svm-client.js","lines":[50,50],"snippet":"const resp = await fetch(url, { method: \"POST\", headers: { \"Content-Type\": \"application/json\", Accept: \"application/json\", \"Use","rule":"http_external_io"},{"file":"mcp/lib/temp-email.js","lines":[43,43],"snippet":"domainResp = await fetch(\"https://api.mail.tm/domains\", { headers: { ...BROWSER_HEADERS, Accept: \"application/json\" }, })","rule":"http_external_io"},{"file":"mcp/lib/temp-email.js","lines":[56,56],"snippet":"createResp = await fetch(\"https://api.mail.tm/accounts\", { method: \"POST\", headers: { ...BROWSER_HEADERS, \"Content-Type","rule":"http_external_io"},{"file":"mcp/lib/temp-email.js","lines":[64,64],"snippet":"t tokenResp = await fetch(\"https://api.mail.tm/token\", { method: \"POST\", headers: { ...BROWSER_HEADERS, \"Content-Type\":","rule":"http_external_io"},{"file":"mcp/lib/temp-email.js","lines":[78,78],"snippet":"const resp = await fetch(\"https://api.guerrillamail.com/ajax.php?f=get_email_address\", { headers: BROWSER_HEADERS, });","rule":"http_external_io"},{"file":"mcp/lib/temp-email.js","lines":[110,110],"snippet":"const resp = await fetch(\"https://api.mail.tm/messages\", { headers: { ...BROWSER_HEADERS, Authorization: `Bearer ${mailbox.token}`,","rule":"http_external_io"},{"file":"scripts/replay-refusal.js","lines":[175,175],"snippet":"const res = await fetch(API_URL, { method: \"POST\", headers: { \"x-api-key\": apiKey, \"anthropic-version\": ANTHROPIC_VERS","rule":"http_external_io"}]},"pii_signals":{"signal":"pii_signals","fired":true,"strength":1,"evidence":[{"file":".hacker-bob/knowledge/hunter-techniques.json","lines":[44,44],"snippet":"1: user(id: 1) { id email } a2: user(id: 2) { id email } }\", \"mutation { updateUserRole(userId: \\\"VICTIM_ID\\\", role: ADMIN) { id rol","rule":"pii_keywords"},{"file":".hacker-bob/knowledge/hunter-techniques.json","lines":[44,44],"snippet":"2: user(id: 2) { id email } }\", \"mutation { updateUserRole(userId: \\\"VICTIM_ID\\\", role: ADMIN) { id role } }\", \"GET /graphql","rule":"pii_keywords"},{"file":".hacker-bob/knowledge/hunter-techniques.json","lines":[103,103],"snippet":"cker JWKS, role/sub/email edits.\", \"For OAuth/OIDC, chain open redirects into redirect_uri validation, state/nonce weakness, missing","rule":"pii_keywords"},{"file":".hacker-bob/knowledge/hunter-techniques.json","lines":[112,112],"snippet":"cope=openid profile email admin offline_access\" ] }, { \"id\": \"ssrf-url-fetch\", \"title\": \"SSRF and server-side URL","rule":"pii_keywords"},{"file":".hacker-bob/knowledge/hunter-techniques.json","lines":[148,148],"snippet":"ation, PDF preview, email templates, and shared documents.\", \"Do not report upload of inert files. Prove script execution, sensitive","rule":"pii_keywords"},{"file":"adapters/codex/hacker-bob/.codex-plugin/plugin.json","lines":[7,7],"snippet":"contributors\", \"email\": \"maintainers@example.invalid\", \"url\": \"https://github.com/vmihalis/hacker-bob\" }, \"homepage\": \"https://g","rule":"pii_keywords"},{"file":"dev-sync.sh","lines":[95,95],"snippet":"cp \"$SCRIPT_DIR/mcp/redaction.js\" \"$TARGET_ABS/mcp/\" cp \"$SCRIPT_DIR/mcp/lib/\"*.js \"$TARGET_ABS/mcp/lib/\" rm -rf \"$TARGET_ABS/mcp/lib/to","rule":"pii_redaction_present"},{"file":"docs/bob-architecture-event.html","lines":[1196,1196],"snippet":"t the proof needed, redact sensitive data, and report responsibly.</p></div> </div> </div> <div class=\"foot\"><span","rule":"pii_redaction_present"},{"file":"docs/bob-architecture-event.html","lines":[1603,1603],"snippet":"h MCP, which writes redacted audit metadata and egress information.</p> </div> <div class=\"code-card\"> <div","rule":"pii_redaction_present"},{"file":"docs/bob-architecture-event.html","lines":[1616,1616],"snippet":"n>Audited requests, redacted URLs, visible egress</span></div> </section> <section class=\"slide\" data-title=\"Egress\"> <","rule":"pii_redaction_present"},{"file":"docs/bob-architecture-event.html","lines":[1858,1858],"snippet":"b collects bounded, redacted evidence packs for final reportable findings.</p> <div class=\"pill-row\"> <span class=\"pil","rule":"pii_redaction_present"},{"file":"docs/bob-architecture-event.html","lines":[1860,1860],"snippet":"<span class=\"pill\">redacted</span> <span class=\"pill\">bounded</span> <span class=\"pill\">per finding</span>","rule":"pii_redaction_present"},{"file":"mcp/auto-signup.js","lines":[357,357],"snippet":"ELD_SELECTORS = { email: [ 'input[name=\"email\"]', 'input[name=\"e-mail\"]', 'input[name=\"user_email\"]', 'input[name=\"userEmail\"]', '","rule":"pii_keywords"},{"file":"mcp/auto-signup.js","lines":[358,358],"snippet":"[ 'input[name=\"email\"]', 'input[name=\"e-mail\"]', 'input[name=\"user_email\"]', 'input[name=\"userEmail\"]', 'input[name=\"username\"][typ","rule":"pii_keywords"},{"file":"mcp/auto-signup.js","lines":[359,359],"snippet":"e=\"username\"][type=\"email\"]', 'input[type=\"email\"]', 'input[placeholder*=\"email\" i]', 'input[autocomplete=\"email\"]', 'input[id*=\"ema","rule":"pii_keywords"},{"file":"mcp/auto-signup.js","lines":[360,360],"snippet":"', 'input[type=\"email\"]', 'input[placeholder*=\"email\" i]', 'input[autocomplete=\"email\"]', 'input[id*=\"email\" i]', ], password: [","rule":"pii_keywords"},{"file":"mcp/auto-signup.js","lines":[360,360],"snippet":"input[placeholder*=\"email\" i]', 'input[autocomplete=\"email\"]', 'input[id*=\"email\" i]', ], password: [ 'input[name=\"password\"]',","rule":"pii_keywords"},{"file":"mcp/lib/auth-differential.js","lines":[11,11],"snippet":"ivate[_-]?key/i, /ssn|social[_-]?security/i, /tax[_-]?id/i, /salary|compensation/i, /credit[_-]?card|cc[_-]?num/i, /^email$/i, /","rule":"pii_keywords"},{"file":"mcp/lib/auth-differential.js","lines":[15,15],"snippet":"d|cc[_-]?num/i, /^email$/i, /^phone$/i, /^address$/i, /date[_-]?of[_-]?birth|^dob$/i, /internal[_-]?id/i, /admin/i, ]; const SE","rule":"pii_keywords"},{"file":"mcp/lib/egress-profiles.js","lines":[5,5],"snippet":"re(\"path\"); const { redactUrlSensitiveValues } = require(\"../redaction.js\"); const EGRESS_PROFILES_VERSION = 1; const EGRESS_PROFILE_NAME_R","rule":"pii_redaction_present"},{"file":"mcp/lib/egress-profiles.js","lines":[5,5],"snippet":"ues } = require(\"../redaction.js\"); const EGRESS_PROFILES_VERSION = 1; const EGRESS_PROFILE_NAME_RE = /^[A-Za-z0-9][A-Za-z0-9._-]{0,63}$/;","rule":"pii_redaction_present"},{"file":"mcp/lib/egress-profiles.js","lines":[71,71],"snippet":"value; } function redactProxyUrl(proxyUrl) { if (proxyUrl == null) return null; const text = String(proxyUrl); if (ENV_REF_RE.test(t","rule":"pii_redaction_present"},{"file":"mcp/lib/egress-profiles.js","lines":[75,75],"snippet":"eturn text; const redacted = redactUrlSensitiveValues(text); if (redacted !== text) return redacted; return text.replace(/:\\/\\/([^:@/\\","rule":"pii_redaction_present"},{"file":"mcp/lib/egress-profiles.js","lines":[75,75],"snippet":"const redacted = redactUrlSensitiveValues(text); if (redacted !== text) return redacted; return text.replace(/:\\/\\/([^:@/\\s]+):([^@/\\","rule":"pii_redaction_present"},{"file":"mcp/lib/evidence.js","lines":[193,193],"snippet":"CHARS, ); const redactionNotes = pack.redaction_notes == null ? null : assertMaxChars(normalizeOptionalText(pack.redaction_notes","rule":"pii_redaction_present"}]},"bio_health_signals":{"signal":"bio_health_signals","fired":false,"strength":0,"evidence":[]},"employment_signals":{"signal":"employment_signals","fired":true,"strength":1,"evidence":[{"file":".claude/hooks/session-read-guard.sh","lines":[187,187],"snippet":"OMMANDS for candidate in tokens[index + 1:]: if candidate in {\"|\", \";\", \"&&\", \"||\"}: break f","rule":"employment_terms"},{"file":".claude/hooks/session-read-guard.sh","lines":[188,188],"snippet":"1:]: if candidate in {\"|\", \";\", \"&&\", \"||\"}: break for path_candidate in candidate_paths(candidate):","rule":"employment_terms"},{"file":".claude/hooks/session-read-guard.sh","lines":[190,190],"snippet":"in candidate_paths(candidate): blocked = check_file(path_candidate, block_session_dirs=block_session_dirs)","rule":"employment_terms"},{"file":"adapters/codex/index.js","lines":[47,47],"snippet":"escription: \"Run or resume a Hacker Bob bug bounty hunt.\", argumentHint: \"<target|resume target [force-merge]> [--no-auth|--normal|--par","rule":"employment_terms"},{"file":"adapters/codex/index.js","lines":[48,48],"snippet":"umentHint: \"<target|resume target [force-merge]> [--no-auth|--normal|--paranoid|--yolo]\", }), status: Object.freeze({ file: \"bob-sta","rule":"employment_terms"},{"file":"adapters/index.js","lines":[58,58],"snippet":"safeIsDir(fsModule, candidate) { try { return fsModule.statSync(candidate).isDirectory(); } catch { return false; } } functio","rule":"employment_terms"},{"file":"adapters/index.js","lines":[60,60],"snippet":"n fsModule.statSync(candidate).isDirectory(); } catch { return false; } } function safeIsFile(fsModule, candidate) { try { re","rule":"employment_terms"},{"file":"adapters/index.js","lines":[66,66],"snippet":"afeIsFile(fsModule, candidate) { try { return fsModule.statSync(candidate).isFile(); } catch { return false; } } // Layered a","rule":"employment_terms"},{"file":"adapters/index.js","lines":[68,68],"snippet":"n fsModule.statSync(candidate).isFile(); } catch { return false; } } // Layered adapter detection for install-time intent. Returns","rule":"employment_terms"},{"file":"docs/bob-architecture-event.html","lines":[1379,1379],"snippet":"arget.com /bob-hunt resume target.com /bob-status /bob-debug /bob-egress</pre> </div> </div> <div class=\"foot\"><sp","rule":"employment_terms"},{"file":"docs/bob-architecture-event.html","lines":[1719,1719],"snippet":"report yet. It is a candidate that must survive chaining and verification.</p> </div> <div class=\"code-card\">","rule":"employment_terms"},{"file":"mcp/lib/audit-report-parser.js","lines":[150,150],"snippet":"> title const candidate = line.replace(/^#\\s+/, \"\").trim(); if (title == null) { title = candidate; currentSecti","rule":"employment_terms"},{"file":"mcp/lib/audit-report-parser.js","lines":[152,152],"snippet":") { title = candidate; currentSection = \"_summary\"; } else { // Second H1 starts a new finding section as a fa","rule":"employment_terms"},{"file":"mcp/lib/audit-report-parser.js","lines":[156,156],"snippet":"startFinding(candidate); } continue; } if (/^##\\s+/.test(line)) { const headingText = line.replace(/^##\\s+/","rule":"employment_terms"},{"file":"mcp/lib/bob-export.js","lines":[126,126],"snippet":", \"0\")}`; const candidate = path.join(root, `${timestamp}${suffix}`); try { fs.mkdirSync(candidate); return candidate;","rule":"employment_terms"},{"file":"mcp/lib/bob-export.js","lines":[128,128],"snippet":"fs.mkdirSync(candidate); return candidate; } catch (error) { if (!error || error.code !== \"EEXIST\") throw error;","rule":"employment_terms"},{"file":"mcp/lib/bob-export.js","lines":[129,129],"snippet":"date); return candidate; } catch (error) { if (!error || error.code !== \"EEXIST\") throw error; } } throw new Error(`","rule":"employment_terms"},{"file":"mcp/lib/foundry-runner.js","lines":[361,361],"snippet":"ent)) { const candidate = suite && suite.kind && suite.kind.Standard && suite.kind.Standard.fork_block_number; if (typeof candid","rule":"employment_terms"},{"file":"mcp/lib/foundry-runner.js","lines":[362,362],"snippet":"r; if (typeof candidate === \"number\" && Number.isFinite(candidate)) { forkBlockUsed = candidate; break; } }","rule":"employment_terms"},{"file":"mcp/lib/foundry-runner.js","lines":[362,362],"snippet":"&& Number.isFinite(candidate)) { forkBlockUsed = candidate; break; } } } const envelope = { // ok requir","rule":"employment_terms"},{"file":"mcp/lib/foundry-runner.js","lines":[363,363],"snippet":"forkBlockUsed = candidate; break; } } } const envelope = { // ok requires: forge exited cleanly, parsed JSON,","rule":"employment_terms"},{"file":"mcp/lib/pipeline-analytics.js","lines":[144,144],"snippet":"eLatestIso(current, candidate) { if (!candidate) return current; if (!current) return candidate; return timestampMs(candidate) > times","rule":"employment_terms"},{"file":"mcp/lib/pipeline-analytics.js","lines":[145,145],"snippet":"candidate) { if (!candidate) return current; if (!current) return candidate; return timestampMs(candidate) > timestampMs(current) ? ca","rule":"employment_terms"},{"file":"mcp/lib/pipeline-analytics.js","lines":[146,146],"snippet":"f (!current) return candidate; return timestampMs(candidate) > timestampMs(current) ? candidate : current; } function normalizePositiveIn","rule":"employment_terms"},{"file":"mcp/lib/pipeline-analytics.js","lines":[147,147],"snippet":"return timestampMs(candidate) > timestampMs(current) ? candidate : current; } function normalizePositiveInteger(value, defaultValue, maxVa","rule":"employment_terms"}]},"bio_metric_signals":{"signal":"bio_metric_signals","fired":true,"strength":0.7112605001534575,"evidence":[{"file":"mcp/auto-signup.js","lines":[11,11],"snippet":"system Chrome (TLS fingerprint, fonts, WebGL match) // 3. Headed mode — avoids headless signals // 4. ignoreDefaultArgs: ['--enable-aut","rule":"biometric_terms"},{"file":"test/priors-slice-brief.test.js","lines":[15,15],"snippet":"-index.js\"); const FINGERPRINT = `bobpriortest${crypto.randomBytes(6).toString(\"hex\")}`; function uniqueDomain(prefix = \"bob-priors-test\")","rule":"biometric_terms"},{"file":"test/priors-slice-brief.test.js","lines":[48,48],"snippet":", title: `${FINGERPRINT} IDOR on user profile endpoint`, description: `${FINGERPRINT} broken object level authorization`,","rule":"biometric_terms"},{"file":"test/priors-slice-brief.test.js","lines":[49,49],"snippet":"description: `${FINGERPRINT} broken object level authorization`, severity: \"high\", attack_class: \"idor\", endpoin","rule":"biometric_terms"},{"file":"test/priors-slice-brief.test.js","lines":[52,52],"snippet":"endpoint: `/${FINGERPRINT}/users/{id}`, tech_stack: [\"express\"], }, calibration_label: \"real\", }); const s","rule":"biometric_terms"},{"file":"test/priors-slice-brief.test.js","lines":[58,58],"snippet":"endpoint: `/${FINGERPRINT}/users/{id}`, bug_class: \"idor\", tech_stack: [\"express\"], }); assert.ok(slice); asse","rule":"biometric_terms"}]},"education_signals":{"signal":"education_signals","fired":false,"strength":0,"evidence":[]},"law_enforcement_signals":{"signal":"law_enforcement_signals","fired":false,"strength":0,"evidence":[]},"migration_signals":{"signal":"migration_signals","fired":false,"strength":0,"evidence":[]},"justice_signals":{"signal":"justice_signals","fired":false,"strength":0,"evidence":[]},"essential_services_signals":{"signal":"essential_services_signals","fired":false,"strength":0,"evidence":[]},"critical_infra_signals":{"signal":"critical_infra_signals","fired":false,"strength":0,"evidence":[]},"content_generation_signals":{"signal":"content_generation_signals","fired":false,"strength":0,"evidence":[]},"emotion_recognition_signals":{"signal":"emotion_recognition_signals","fired":false,"strength":0,"evidence":[]}}},"scope":{"regulationIds":["eu-ai-act-2024-08","nist-ai-rmf-1.0","gdpr-2016","iso-42001-2023"],"notes":["Auditing against packs: eu-ai-act-2024-08, nist-ai-rmf-1.0, gdpr-2016, iso-42001-2023"]},"map":{"classification":"high","annexIiiCategories":["1","4"],"art50Triggers":["50(1)"],"drivingSignals":[{"signal":"bio_metric_signals","category":"1"},{"signal":"employment_signals","category":"4"}],"rationale":["Classified HIGH-RISK based on 2 Annex III signal(s).","Annex III §1 (Biometric ID, categorisation, emotion recognition) — signal \"bio_metric_signals\" fired with strength 0.71","Annex III §4 (Employment, workers management, access to self-employment) — signal \"employment_signals\" fired with strength 1.00","Art 50 50(1) (Interaction with natural persons) — signal \"agent_framework\" fired"]},"checks":[{"clauseId":"eu-ai-act/art-5/1a-subliminal","regulationId":"eu-ai-act-2024-08","article":"5(1)(a)","title":"Subliminal techniques distorting behaviour","principle":"transparency","verdict":"pass","score":4,"rawScore":0,"evidence":[],"rules":[{"rule":"detect_manipulative_prompt_patterns","matched":0,"weight":1}],"rationale":"Composite raw score 0.00 (0/1 rules matched).","confidence":0.55,"needsLlmJudge":false,"verified":true,"verifyMethod":"deterministic-only"},{"clauseId":"eu-ai-act/art-5/1b-vulnerability","regulationId":"eu-ai-act-2024-08","article":"5(1)(b)","title":"Exploiting vulnerabilities (age, disability, socio-economic)","principle":"fairness","verdict":"pass","score":4,"rawScore":0,"evidence":[],"rules":[{"rule":"detect_protected_attribute_targeting","matched":0,"weight":1}],"rationale":"Composite raw score 0.00 (0/1 rules matched).","confidence":0.55,"needsLlmJudge":false,"verified":true,"verifyMethod":"deterministic-only"},{"clauseId":"eu-ai-act/art-5/1c-social-scoring","regulationId":"eu-ai-act-2024-08","article":"5(1)(c)","title":"Social scoring leading to detrimental treatment","principle":"fairness","verdict":"pass","score":4,"rawScore":0,"evidence":[],"rules":[{"rule":"detect_scoring_with_persistent_user_state","matched":0,"weight":1}],"rationale":"Composite raw score 0.00 (0/1 rules matched). Supporting docs may exist outside the repo.","confidence":0.55,"needsLlmJudge":false,"verified":true,"verifyMethod":"deterministic-only"},{"clauseId":"eu-ai-act/art-5/1d-predictive-policing","regulationId":"eu-ai-act-2024-08","article":"5(1)(d)","title":"Predictive policing solely from profiling","principle":"fairness","verdict":"pass","score":4,"rawScore":0,"evidence":[],"rules":[{"rule":"detect_crime_risk_scoring_from_profile","matched":0,"weight":1}],"rationale":"Composite raw score 0.00 (0/1 rules matched).","confidence":0.55,"needsLlmJudge":false,"verified":true,"verifyMethod":"deterministic-only"},{"clauseId":"eu-ai-act/art-5/1e-facial-scraping","regulationId":"eu-ai-act-2024-08","article":"5(1)(e)","title":"Untargeted facial image scraping for face databases","principle":"privacy","verdict":"fail","score":0,"rawScore":1,"evidence":[{"file":"mcp/auto-signup.js","lines":[11,11],"snippet":"system Chrome (TLS fingerprint, fonts, WebGL match) // 3. Headed mode — avoids headless signals // 4. ignoreDefaultArgs: ['--enable-aut","rule":"biometric_terms"},{"file":"test/priors-slice-brief.test.js","lines":[15,15],"snippet":"-index.js\"); const FINGERPRINT = `bobpriortest${crypto.randomBytes(6).toString(\"hex\")}`; function uniqueDomain(prefix = \"bob-priors-test\")","rule":"biometric_terms"},{"file":"test/priors-slice-brief.test.js","lines":[48,48],"snippet":", title: `${FINGERPRINT} IDOR on user profile endpoint`, description: `${FINGERPRINT} broken object level authorization`,","rule":"biometric_terms"}],"rules":[{"rule":"detect_face_image_scraping","matched":1,"weight":1}],"rationale":"Composite raw score 1.00 (1/1 rules matched).","confidence":0.55,"needsLlmJudge":false,"verified":true,"verifyMethod":"deterministic-only"},{"clauseId":"eu-ai-act/art-5/1f-emotion-workplace-edu","regulationId":"eu-ai-act-2024-08","article":"5(1)(f)","title":"Emotion recognition in workplace and education","principle":"privacy","verdict":"pass","score":4,"rawScore":0,"evidence":[],"rules":[{"rule":"detect_emotion_recognition_in_workplace_education","matched":0,"weight":1}],"rationale":"Composite raw score 0.00 (0/1 rules matched).","confidence":0.55,"needsLlmJudge":false,"verified":true,"verifyMethod":"deterministic-only"},{"clauseId":"eu-ai-act/art-5/1g-biometric-categorisation","regulationId":"eu-ai-act-2024-08","article":"5(1)(g)","title":"Biometric categorisation by protected attributes","principle":"fairness","verdict":"pass","score":4,"rawScore":0,"evidence":[],"rules":[{"rule":"detect_biometric_categorisation_by_protected_attrs","matched":0,"weight":1}],"rationale":"Composite raw score 0.00 (0/1 rules matched).","confidence":0.55,"needsLlmJudge":false,"verified":true,"verifyMethod":"deterministic-only"},{"clauseId":"eu-ai-act/art-5/1h-realtime-rbi","regulationId":"eu-ai-act-2024-08","article":"5(1)(h)","title":"Real-time remote biometric identification in public spaces","principle":"privacy","verdict":"external","score":null,"rawScore":null,"evidence":[],"rules":[],"rationale":"Deployment context (public space, real-time, law enforcement use, judicial\nauthorisation) is operational, not knowable from code. Always external.","confidence":1,"needsLlmJudge":false,"verified":true,"verifyMethod":"deterministic-only"},{"clauseId":"eu-ai-act/art-9/risk-management","regulationId":"eu-ai-act-2024-08","article":"9","title":"Risk management system established, implemented, documented","principle":"safety","verdict":"partial","score":2,"rawScore":0.44999999999999996,"evidence":[{"file":"SECURITY.md","rule":"presence_of_threat_model"},{"file":".github/workflows/ci.yml","rule":"ci_eval_gates"},{"file":".github/workflows/release.yml","rule":"ci_eval_gates"}],"rules":[{"rule":"presence_of_risk_register","matched":0,"weight":0.4},{"rule":"presence_of_threat_model","matched":0.5,"weight":0.3},{"rule":"ci_eval_gates","matched":1,"weight":0.3}],"rationale":"Composite raw score 0.45 (2/3 rules matched). Supporting docs may exist outside the repo.","confidence":1,"needsLlmJudge":true,"verified":true,"verifyMethod":"skipped"},{"clauseId":"eu-ai-act/art-10/data-governance","regulationId":"eu-ai-act-2024-08","article":"10","title":"Data and data governance practices documented","principle":"privacy","verdict":"fail","score":0,"rawScore":0.1,"evidence":[{"file":"mcp/auto-signup.js","lines":[78,78],"snippet":"createResp = await fetch(\"https://api.capsolver.com/createTask\", { method: \"POST\", headers: { \"Content-Type\": \"application/json\" },","rule":"http_external_io"},{"file":"mcp/auto-signup.js","lines":[93,93],"snippet":"st pollResp = await fetch(\"https://api.capsolver.com/getTaskResult\", { method: \"POST\", headers: { \"Content-Type\": \"application/j","rule":"http_external_io"}],"rules":[{"rule":"presence_of_data_card","matched":0,"weight":0.5},{"rule":"data_loading_code_quality","matched":0.4,"weight":0.25},{"rule":"bias_evaluation_present","matched":0,"weight":0.25}],"rationale":"Composite raw score 0.10 (0/3 rules matched). Supporting docs may exist outside the repo.","confidence":0.75,"needsLlmJudge":false,"verified":true,"verifyMethod":"deterministic-only"},{"clauseId":"eu-ai-act/art-11/technical-documentation","regulationId":"eu-ai-act-2024-08","article":"11","title":"Technical documentation drawn up before placing on market","principle":"auditability","verdict":"fail","score":1,"rawScore":0.35,"evidence":[{"file":"README.md","rule":"readme_quality","detail":"2 required sections present"},{"file":"scripts/replay-prompts/00-baseline.md","rule":"architecture_docs"}],"rules":[{"rule":"presence_of_model_card","matched":0,"weight":0.5},{"rule":"readme_quality","matched":0.5,"weight":0.3},{"rule":"architecture_docs","matched":1,"weight":0.2}],"rationale":"Composite raw score 0.35 (2/3 rules matched). Supporting docs may exist outside the repo.","confidence":1,"needsLlmJudge":true,"verified":true,"verifyMethod":"skipped"},{"clauseId":"eu-ai-act/art-12/p1-automatic-logs","regulationId":"eu-ai-act-2024-08","article":"12(1)","title":"Automatic recording of events over the lifetime","principle":"auditability","verdict":"partial","score":2,"rawScore":0.5800000000000001,"evidence":[{"file":".claude/hooks/bob-update.js","lines":[64,64],"snippet":"he(projectDir); console.log(\"Hacker Bob update cache cleared.\"); return; } usage(); process.exit(1); } main(process.argv.sli","rule":"log_at_tool_boundary"},{"file":".claude/hooks/hunter-subagent-stop.js","lines":[238,238],"snippet":"ndoff, })); console.log(JSON.stringify({ ok: true, message: \"post-report evidence run accepted\" })); process.exit(0); } con","rule":"log_at_tool_boundary"},{"file":".claude/hooks/hunter-subagent-stop.js","lines":[247,247],"snippet":"cess.exit(2); } console.log(JSON.stringify({ ok: true, message: finalization.reason })); process.exit(0); } if (require.main === modu","rule":"log_at_tool_boundary"},{"file":"bin/hacker-bob.js","lines":[87,87],"snippet":"y.targetAbs); console.log(\"\"); if (summary.adapters.length === 1 && summary.adapters[0] === \"claude\") { console.log(\"Upd","rule":"log_at_tool_boundary"},{"file":"bin/hacker-bob.js","lines":[89,89],"snippet":"\"claude\") { console.log(\"Update complete. Fully restart Claude Code in this project before continuing.\"); } else { con","rule":"log_at_tool_boundary"},{"file":"bin/hacker-bob.js","lines":[91,91],"snippet":"} else { console.log(\"Update complete. Restart the selected host adapter before continuing.\"); } } return; } i","rule":"log_at_tool_boundary"},{"file":".claude/hooks/bob-update.js","lines":[64,64],"snippet":"he(projectDir); console.log(\"Hacker Bob update cache cleared.\"); return; } usage(); process.exit(1); } main(process.argv.sli","rule":"log_at_tool_boundary"},{"file":".claude/hooks/hunter-subagent-stop.js","lines":[238,238],"snippet":"ndoff, })); console.log(JSON.stringify({ ok: true, message: \"post-report evidence run accepted\" })); process.exit(0); } con","rule":"log_at_tool_boundary"}],"rules":[{"rule":"structured_logging_imported","matched":0,"weight":0.3},{"rule":"logging_at_tool_call_boundaries","matched":1,"weight":0.5},{"rule":"logging_persistent_sink","matched":0.4,"weight":0.2}],"rationale":"Composite raw score 0.58 (1/3 rules matched).","confidence":1,"needsLlmJudge":true,"verified":true,"verifyMethod":"skipped"},{"clauseId":"eu-ai-act/art-12/p2-traceability","regulationId":"eu-ai-act-2024-08","article":"12(2)","title":"Logging ensures traceability appropriate to risk","principle":"auditability","verdict":"pass","score":3,"rawScore":0.675,"evidence":[{"file":".claude/hooks/bob-update.js","lines":[64,64],"snippet":"he(projectDir); console.log(\"Hacker Bob update cache cleared.\"); return; } usage(); process.exit(1); } main(process.argv.sli","rule":"log_at_tool_boundary"},{"file":".claude/hooks/hunter-subagent-stop.js","lines":[238,238],"snippet":"ndoff, })); console.log(JSON.stringify({ ok: true, message: \"post-report evidence run accepted\" })); process.exit(0); } con","rule":"log_at_tool_boundary"},{"file":".claude/hooks/hunter-subagent-stop.js","lines":[247,247],"snippet":"cess.exit(2); } console.log(JSON.stringify({ ok: true, message: finalization.reason })); process.exit(0); } if (require.main === modu","rule":"log_at_tool_boundary"},{"file":"bin/hacker-bob.js","lines":[87,87],"snippet":"y.targetAbs); console.log(\"\"); if (summary.adapters.length === 1 && summary.adapters[0] === \"claude\") { console.log(\"Upd","rule":"log_at_tool_boundary"},{"file":"bin/hacker-bob.js","lines":[89,89],"snippet":"\"claude\") { console.log(\"Update complete. Fully restart Claude Code in this project before continuing.\"); } else { con","rule":"log_at_tool_boundary"},{"file":"bin/hacker-bob.js","lines":[91,91],"snippet":"} else { console.log(\"Update complete. Restart the selected host adapter before continuing.\"); } } return; } i","rule":"log_at_tool_boundary"},{"file":".claude/hooks/bob-update.js","lines":[64,64],"snippet":"he(projectDir); console.log(\"Hacker Bob update cache cleared.\"); return; } usage(); process.exit(1); } main(process.argv.sli","rule":"log_at_tool_boundary"},{"file":".claude/hooks/hunter-subagent-stop.js","lines":[238,238],"snippet":"ndoff, })); console.log(JSON.stringify({ ok: true, message: \"post-report evidence run accepted\" })); process.exit(0); } con","rule":"log_at_tool_boundary"}],"rules":[{"rule":"logs_include_input_output_pairs","matched":1,"weight":0.5},{"rule":"logs_include_model_identity","matched":0.7,"weight":0.25},{"rule":"logs_include_request_id","matched":0,"weight":0.25}],"rationale":"Composite raw score 0.68 (2/3 rules matched). Supporting docs may exist outside the repo.","confidence":0.975,"needsLlmJudge":true,"verified":true,"verifyMethod":"skipped"},{"clauseId":"eu-ai-act/art-13/deployer-instructions","regulationId":"eu-ai-act-2024-08","article":"13","title":"Transparent operation and instructions for use","principle":"transparency","verdict":"fail","score":1,"rawScore":0.25,"evidence":[{"file":"README.md","rule":"readme_quality","detail":"2 required sections present"},{"file":"README.md","rule":"output_interpretation_guidance"},{"file":"README.md","rule":"limitations_section_present"}],"rules":[{"rule":"presence_of_deployer_instructions","matched":0.5,"weight":0.5},{"rule":"output_interpretation_guidance","matched":0,"weight":0.3},{"rule":"limitations_section_present","matched":0,"weight":0.2}],"rationale":"Composite raw score 0.25 (1/3 rules matched). Supporting docs may exist outside the repo.","confidence":0.9,"needsLlmJudge":false,"verified":true,"verifyMethod":"deterministic-only"},{"clauseId":"eu-ai-act/art-14/p1-oversight-measures","regulationId":"eu-ai-act-2024-08","article":"14(1)","title":"Effective human oversight designed and built-in","principle":"human-oversight","verdict":"fail","score":0,"rawScore":0,"evidence":[],"rules":[{"rule":"human_in_loop_hooks_present","matched":0,"weight":0.5},{"rule":"oversight_ui_present","matched":0,"weight":0.3},{"rule":"tool_calls_have_dry_run","matched":0,"weight":0.2}],"rationale":"Composite raw score 0.00 (0/3 rules matched).","confidence":0.65,"needsLlmJudge":false,"verified":true,"verifyMethod":"deterministic-only"},{"clauseId":"eu-ai-act/art-14/p4d-stop-button","regulationId":"eu-ai-act-2024-08","article":"14(4)(d)","title":"Interrupt / stop function reachable by overseer","principle":"human-oversight","verdict":"pass","score":3,"rawScore":0.7,"evidence":[{"file":".claude/hooks/session-read-guard.sh","lines":[150,150],"snippet":"rr, ) raise SystemExit(2) def looks_like_path(token): if not token or token.startswith(\"-\"): return False if token","rule":"kill_switch"},{"file":".claude/hooks/session-read-guard.sh","lines":[208,208],"snippet":"(blocked) raise SystemExit(0) command = tool_input.get(\"command\", \"\") if command: check_bash_command(command) raise SystemExit(0)","rule":"kill_switch"},{"file":".claude/hooks/session-read-guard.sh","lines":[214,214],"snippet":"and(command) raise SystemExit(0) PY","rule":"kill_switch"},{"file":".claude/hooks/session-write-guard.sh","lines":[138,138],"snippet":"s.stderr) raise SystemExit(2) def extract_redirect_targets(command): \"\"\"Extract file paths from shell redirect operators and tee c","rule":"kill_switch"},{"file":".claude/hooks/session-write-guard.sh","lines":[202,202],"snippet":") raise SystemExit(0) # Bash tool command = tool_input.get(\"command\", \"\") if not command: raise SystemExit(0) # Quick gate","rule":"kill_switch"},{"file":".claude/hooks/session-write-guard.sh","lines":[207,207],"snippet":"command: raise SystemExit(0) # Quick gate: skip if no write indicators has_redirects = re.search(r\">{1,2}\\s|tee\\s\", command) has_open_","rule":"kill_switch"}],"rules":[{"rule":"kill_switch_present","matched":1,"weight":0.7},{"rule":"graceful_shutdown_handler","matched":0,"weight":0.3}],"rationale":"Composite raw score 0.70 (1/2 rules matched).","confidence":0.9,"needsLlmJudge":true,"verified":true,"verifyMethod":"skipped"},{"clauseId":"eu-ai-act/art-14/p4e-override","regulationId":"eu-ai-act-2024-08","article":"14(4)(e)","title":"Ability to override / reverse the system's output","principle":"human-oversight","verdict":"partial","score":2,"rawScore":0.6,"evidence":[{"file":".claude/hooks/session-read-guard.sh","lines":[150,150],"snippet":"rr, ) raise SystemExit(2) def looks_like_path(token): if not token or token.startswith(\"-\"): return False if token","rule":"kill_switch"},{"file":".claude/hooks/session-read-guard.sh","lines":[208,208],"snippet":"(blocked) raise SystemExit(0) command = tool_input.get(\"command\", \"\") if command: check_bash_command(command) raise SystemExit(0)","rule":"kill_switch"},{"file":".claude/hooks/session-read-guard.sh","lines":[214,214],"snippet":"and(command) raise SystemExit(0) PY","rule":"kill_switch"},{"file":".claude/hooks/session-write-guard.sh","lines":[138,138],"snippet":"s.stderr) raise SystemExit(2) def extract_redirect_targets(command): \"\"\"Extract file paths from shell redirect operators and tee c","rule":"kill_switch"},{"file":".claude/hooks/session-write-guard.sh","lines":[202,202],"snippet":") raise SystemExit(0) # Bash tool command = tool_input.get(\"command\", \"\") if not command: raise SystemExit(0) # Quick gate","rule":"kill_switch"},{"file":".claude/hooks/session-write-guard.sh","lines":[207,207],"snippet":"command: raise SystemExit(0) # Quick gate: skip if no write indicators has_redirects = re.search(r\">{1,2}\\s|tee\\s\", command) has_open_","rule":"kill_switch"}],"rules":[{"rule":"override_path_present","matched":1,"weight":0.6},{"rule":"decisions_are_addressable","matched":0,"weight":0.4}],"rationale":"Composite raw score 0.60 (1/2 rules matched).","confidence":1,"needsLlmJudge":true,"verified":true,"verifyMethod":"skipped"},{"clauseId":"eu-ai-act/art-15/p1-accuracy","regulationId":"eu-ai-act-2024-08","article":"15(1)","title":"Appropriate level of accuracy declared and tested","principle":"safety","verdict":"partial","score":2,"rawScore":0.45,"evidence":[{"file":"tests/","rule":"eval_suite_present"},{"file":"README.md","rule":"metrics_documented"},{"file":".github/workflows/ci.yml","rule":"ci_eval_gates"},{"file":".github/workflows/release.yml","rule":"ci_eval_gates"}],"rules":[{"rule":"eval_suite_present","matched":0.5,"weight":0.5},{"rule":"metrics_documented","matched":0,"weight":0.3},{"rule":"eval_in_ci","matched":1,"weight":0.2}],"rationale":"Composite raw score 0.45 (2/3 rules matched).","confidence":1,"needsLlmJudge":true,"verified":true,"verifyMethod":"skipped"},{"clauseId":"eu-ai-act/art-15/p4-robustness","regulationId":"eu-ai-act-2024-08","article":"15(4)","title":"Resilience to errors, faults, inconsistencies","principle":"safety","verdict":"fail","score":1,"rawScore":0.16000000000000003,"evidence":[{"file":"package.json","rule":"manifest_framework_dep","detail":"Anthropic SDK"}],"rules":[{"rule":"error_handling_at_tool_boundaries","matched":0.4,"weight":0.4},{"rule":"retry_logic","matched":0,"weight":0.3},{"rule":"fallback_behaviour","matched":0,"weight":0.3}],"rationale":"Composite raw score 0.16 (0/3 rules matched).","confidence":0.81,"needsLlmJudge":false,"verified":true,"verifyMethod":"deterministic-only"},{"clauseId":"eu-ai-act/art-15/p5-cybersecurity","regulationId":"eu-ai-act-2024-08","article":"15(5)","title":"Cybersecurity measures appropriate to circumstances","principle":"security-governance","verdict":"fail","score":1,"rawScore":0.33266899936762,"evidence":[{"file":".claude/hooks/bounty-statusline.js","lines":[63,63],"snippet":"const fiveHr = data.rate_limits?.five_hour?.used_percentage; const sevenDay = data.rate_limits?.seven_day?.used_percentage; const wo","rule":"rate_limit_usage"},{"file":".claude/hooks/bounty-statusline.js","lines":[64,64],"snippet":"nst sevenDay = data.rate_limits?.seven_day?.used_percentage; const worst = Math.max(fiveHr || 0, sevenDay || 0); if (worst >= 80) ra","rule":"rate_limit_usage"},{"file":"package-lock.json","lines":[211,211],"snippet":"\"^5.2.1\", \"express-rate-limit\": \"^8.2.1\", \"hono\": \"^4.11.4\", \"jose\": \"^6.1.3\", \"json-schema-typed\": \"^8.0.2","rule":"rate_limit_usage"},{"file":"package-lock.json","lines":[687,687],"snippet":", \"node_modules/express-rate-limit\": { \"version\": \"8.4.1\", \"resolved\": \"https://registry.npmjs.org/express-rate-limit/-/expr","rule":"rate_limit_usage"},{"file":"package-lock.json","lines":[689,689],"snippet":"/registry.npmjs.org/express-rate-limit/-/express-rate-limit-8.4.1.tgz\", \"integrity\": \"sha512-NGVYwQSAyEQgzxX1iCM978PP9AdO/hW93gMcF6ZwQ","rule":"rate_limit_usage"},{"file":"package-lock.json","lines":[689,689],"snippet":"xpress-rate-limit/-/express-rate-limit-8.4.1.tgz\", \"integrity\": \"sha512-NGVYwQSAyEQgzxX1iCM978PP9AdO/hW93gMcF6ZwQCm+rFvLsBH6w4xcXWTcli","rule":"rate_limit_usage"},{"file":"mcp/lib/evm-source.js","lines":[283,283],"snippet":"const apiKey = process.env.BOB_ETHERSCAN_API_KEY || null; const etherscan = await fetchFromEtherscanV2(numericChainId, lower, apiKe","rule":"secrets_loaded_from_env"},{"file":"mcp/lib/signup.js","lines":[284,284],"snippet":"capsolver_api_key: process.env.CAPSOLVER_API_KEY || null, proxy: args.proxy || process.env.BOUNTY_PROXY || null, timeout_ms: args.t","rule":"secrets_loaded_from_env"},{"file":"scripts/install.js","lines":[476,476],"snippet":"romium`); } if (process.env.CAPSOLVER_API_KEY) { console.log(\" OK: CAPSOLVER_API_KEY is set\"); } else { console.log(\" NOT SE","rule":"secrets_loaded_from_env"},{"file":"scripts/lifecycle.js","lines":[408,408],"snippet":"abled\"); } if (process.env.CAPSOLVER_API_KEY) { addCheck(checks, \"ok\", \"optional_capsolver\", \"CAPSOLVER_API_KEY is set\"); } else","rule":"secrets_loaded_from_env"},{"file":"scripts/replay-refusal.js","lines":[217,217],"snippet":"} const apiKey = process.env.ANTHROPIC_API_KEY; if (!apiKey && !args[\"dry-run\"]) { console.error( \"error: ANTHROPIC_API_KEY e","rule":"secrets_loaded_from_env"}],"rules":[{"rule":"prompt_injection_defences","matched":0,"weight":0.4},{"rule":"rate_limiting","matched":0.83167249841905,"weight":0.2},{"rule":"secrets_not_in_prompts","matched":0.83167249841905,"weight":0.2},{"rule":"adversarial_eval_present","matched":0,"weight":0.2}],"rationale":"Composite raw score 0.33 (2/4 rules matched).","confidence":1,"needsLlmJudge":true,"verified":true,"verifyMethod":"skipped"},{"clauseId":"eu-ai-act/art-26/p6-keep-logs","regulationId":"eu-ai-act-2024-08","article":"26(6)","title":"Deployer log-retention capability supported","principle":"accountability","verdict":"partial","score":2,"rawScore":0.5,"evidence":[{"file":".claude/hooks/bob-update.js","lines":[64,64],"snippet":"he(projectDir); console.log(\"Hacker Bob update cache cleared.\"); return; } usage(); process.exit(1); } main(process.argv.sli","rule":"log_at_tool_boundary"},{"file":".claude/hooks/hunter-subagent-stop.js","lines":[238,238],"snippet":"ndoff, })); console.log(JSON.stringify({ ok: true, message: \"post-report evidence run accepted\" })); process.exit(0); } con","rule":"log_at_tool_boundary"}],"rules":[{"rule":"logs_externally_exportable","matched":0.5,"weight":1}],"rationale":"Composite raw score 0.50 (1/1 rules matched). Supporting docs may exist outside the repo.","confidence":1,"needsLlmJudge":true,"verified":true,"verifyMethod":"skipped"},{"clauseId":"eu-ai-act/art-50/p1-ai-disclosure","regulationId":"eu-ai-act-2024-08","article":"50(1)","title":"Users informed they are interacting with an AI","principle":"transparency","verdict":"partial","score":2,"rawScore":0.4,"evidence":[{"file":"README.md","rule":"ai_disclosure_in_user_facing_strings"},{"file":"scripts/bench-prompts.sh","rule":"persona_not_human_impersonating"}],"rules":[{"rule":"ai_disclosure_in_user_facing_strings","matched":0,"weight":0.6},{"rule":"persona_not_human_impersonating","matched":1,"weight":0.4}],"rationale":"Composite raw score 0.40 (1/2 rules matched).","confidence":1,"needsLlmJudge":true,"verified":true,"verifyMethod":"skipped"},{"clauseId":"eu-ai-act/art-50/p2-synthetic-content","regulationId":"eu-ai-act-2024-08","article":"50(2)","title":"AI-generated content marked as such, machine-readable","principle":"transparency","verdict":"n/a","score":null,"rawScore":null,"evidence":[],"rules":[],"rationale":"Clause subject matter not detected — required signals [content_generation_signals, provenance_hooks] did not fire in this repo.","confidence":1,"needsLlmJudge":false,"verified":true,"verifyMethod":"deterministic-only"},{"clauseId":"eu-ai-act/art-50/p3-emotion-biometric-disclosure","regulationId":"eu-ai-act-2024-08","article":"50(3)","title":"Emotion recognition / biometric categorisation disclosure","principle":"transparency","verdict":"fail","score":0,"rawScore":0,"evidence":[{"file":"README.md","rule":"emotion_or_biometric_disclosure_string"}],"rules":[{"rule":"emotion_or_biometric_disclosure_string","matched":0,"weight":1}],"rationale":"Composite raw score 0.00 (0/1 rules matched).","confidence":0.55,"needsLlmJudge":false,"verified":true,"verifyMethod":"deterministic-only"},{"clauseId":"eu-ai-act/art-50/p4-deepfake-disclosure","regulationId":"eu-ai-act-2024-08","article":"50(4)","title":"Deepfake content labelled as artificially generated","principle":"transparency","verdict":"n/a","score":null,"rawScore":null,"evidence":[],"rules":[],"rationale":"Clause subject matter not detected — required signals [content_generation_signals] did not fire in this repo.","confidence":1,"needsLlmJudge":false,"verified":true,"verifyMethod":"deterministic-only"},{"clauseId":"nist-ai-rmf/govern-1.4","regulationId":"nist-ai-rmf-1.0","article":"GOVERN 1.4","title":"Risk management process documented and accountable","principle":"accountability","verdict":"fail","score":0,"rawScore":0,"evidence":[],"rules":[{"rule":"presence_of_risk_register","matched":0,"weight":0.6},{"rule":"risk_owner_assignment","matched":0,"weight":0.4}],"rationale":"Composite raw score 0.00 (0/2 rules matched). Supporting docs may exist outside the repo.","confidence":0.6,"needsLlmJudge":false,"verified":true,"verifyMethod":"deterministic-only"},{"clauseId":"nist-ai-rmf/govern-1.5","regulationId":"nist-ai-rmf-1.0","article":"GOVERN 1.5","title":"Ongoing monitoring and periodic review of risk management","principle":"accountability","verdict":"partial","score":2,"rawScore":0.5,"evidence":[{"file":".github/workflows/ci.yml","rule":"ci_eval_gates"},{"file":".github/workflows/release.yml","rule":"ci_eval_gates"}],"rules":[{"rule":"ci_eval_gates","matched":1,"weight":0.5},{"rule":"drift_monitoring_present","matched":0,"weight":0.5}],"rationale":"Composite raw score 0.50 (1/2 rules matched). Supporting docs may exist outside the repo.","confidence":1,"needsLlmJudge":true,"verified":true,"verifyMethod":"skipped"},{"clauseId":"nist-ai-rmf/map-1.1","regulationId":"nist-ai-rmf-1.0","article":"MAP 1.1","title":"Context of use established and understood","principle":"auditability","verdict":"fail","score":1,"rawScore":0.3,"evidence":[{"file":"README.md","rule":"readme_quality","detail":"2 required sections present"},{"file":"README.md","rule":"output_interpretation_guidance"}],"rules":[{"rule":"intended_use_documented","matched":0.5,"weight":0.6},{"rule":"deployment_context_documented","matched":0,"weight":0.4}],"rationale":"Composite raw score 0.30 (1/2 rules matched). Supporting docs may exist outside the repo.","confidence":0.9,"needsLlmJudge":true,"verified":true,"verifyMethod":"skipped"},{"clauseId":"nist-ai-rmf/map-3.4","regulationId":"nist-ai-rmf-1.0","article":"MAP 3.4","title":"Risks and benefits to people identified","principle":"safety","verdict":"fail","score":1,"rawScore":0.2,"evidence":[{"file":"SECURITY.md","rule":"presence_of_threat_model"}],"rules":[{"rule":"presence_of_risk_register","matched":0,"weight":0.6},{"rule":"presence_of_threat_model","matched":0.5,"weight":0.4}],"rationale":"Composite raw score 0.20 (1/2 rules matched). Supporting docs may exist outside the repo.","confidence":0.7999999999999999,"needsLlmJudge":false,"verified":true,"verifyMethod":"deterministic-only"},{"clauseId":"nist-ai-rmf/measure-2.3","regulationId":"nist-ai-rmf-1.0","article":"MEASURE 2.3","title":"AI system performance evaluated and documented","principle":"safety","verdict":"partial","score":2,"rawScore":0.45,"evidence":[{"file":"tests/","rule":"eval_suite_present"},{"file":"README.md","rule":"metrics_documented"},{"file":".github/workflows/ci.yml","rule":"ci_eval_gates"},{"file":".github/workflows/release.yml","rule":"ci_eval_gates"}],"rules":[{"rule":"eval_suite_present","matched":0.5,"weight":0.5},{"rule":"metrics_documented","matched":0,"weight":0.3},{"rule":"eval_in_ci","matched":1,"weight":0.2}],"rationale":"Composite raw score 0.45 (2/3 rules matched).","confidence":1,"needsLlmJudge":true,"verified":true,"verifyMethod":"skipped"},{"clauseId":"nist-ai-rmf/measure-2.7","regulationId":"nist-ai-rmf-1.0","article":"MEASURE 2.7","title":"Security and resilience evaluated","principle":"security-governance","verdict":"fail","score":1,"rawScore":0.16633449968381,"evidence":[{"file":".claude/hooks/bounty-statusline.js","lines":[63,63],"snippet":"const fiveHr = data.rate_limits?.five_hour?.used_percentage; const sevenDay = data.rate_limits?.seven_day?.used_percentage; const wo","rule":"rate_limit_usage"},{"file":".claude/hooks/bounty-statusline.js","lines":[64,64],"snippet":"nst sevenDay = data.rate_limits?.seven_day?.used_percentage; const worst = Math.max(fiveHr || 0, sevenDay || 0); if (worst >= 80) ra","rule":"rate_limit_usage"},{"file":"package-lock.json","lines":[211,211],"snippet":"\"^5.2.1\", \"express-rate-limit\": \"^8.2.1\", \"hono\": \"^4.11.4\", \"jose\": \"^6.1.3\", \"json-schema-typed\": \"^8.0.2","rule":"rate_limit_usage"},{"file":"package-lock.json","lines":[687,687],"snippet":", \"node_modules/express-rate-limit\": { \"version\": \"8.4.1\", \"resolved\": \"https://registry.npmjs.org/express-rate-limit/-/expr","rule":"rate_limit_usage"},{"file":"package-lock.json","lines":[689,689],"snippet":"/registry.npmjs.org/express-rate-limit/-/express-rate-limit-8.4.1.tgz\", \"integrity\": \"sha512-NGVYwQSAyEQgzxX1iCM978PP9AdO/hW93gMcF6ZwQ","rule":"rate_limit_usage"},{"file":"package-lock.json","lines":[689,689],"snippet":"xpress-rate-limit/-/express-rate-limit-8.4.1.tgz\", \"integrity\": \"sha512-NGVYwQSAyEQgzxX1iCM978PP9AdO/hW93gMcF6ZwQCm+rFvLsBH6w4xcXWTcli","rule":"rate_limit_usage"}],"rules":[{"rule":"prompt_injection_defences","matched":0,"weight":0.4},{"rule":"adversarial_eval_present","matched":0,"weight":0.4},{"rule":"rate_limiting","matched":0.83167249841905,"weight":0.2}],"rationale":"Composite raw score 0.17 (1/3 rules matched).","confidence":0.81633449968381,"needsLlmJudge":false,"verified":true,"verifyMethod":"deterministic-only"},{"clauseId":"nist-ai-rmf/measure-2.8","regulationId":"nist-ai-rmf-1.0","article":"MEASURE 2.8","title":"Privacy risk of the AI system evaluated","principle":"privacy","verdict":"partial","score":2,"rawScore":0.5,"evidence":[{"file":"dev-sync.sh","lines":[95,95],"snippet":"cp \"$SCRIPT_DIR/mcp/redaction.js\" \"$TARGET_ABS/mcp/\" cp \"$SCRIPT_DIR/mcp/lib/\"*.js \"$TARGET_ABS/mcp/lib/\" rm -rf \"$TARGET_ABS/mcp/lib/to","rule":"pii_redaction_present"},{"file":"docs/bob-architecture-event.html","lines":[1196,1196],"snippet":"t the proof needed, redact sensitive data, and report responsibly.</p></div> </div> </div> <div class=\"foot\"><span","rule":"pii_redaction_present"},{"file":"docs/bob-architecture-event.html","lines":[1603,1603],"snippet":"h MCP, which writes redacted audit metadata and egress information.</p> </div> <div class=\"code-card\"> <div","rule":"pii_redaction_present"},{"file":"docs/bob-architecture-event.html","lines":[1616,1616],"snippet":"n>Audited requests, redacted URLs, visible egress</span></div> </section> <section class=\"slide\" data-title=\"Egress\"> <","rule":"pii_redaction_present"},{"file":"docs/bob-architecture-event.html","lines":[1858,1858],"snippet":"b collects bounded, redacted evidence packs for final reportable findings.</p> <div class=\"pill-row\"> <span class=\"pil","rule":"pii_redaction_present"},{"file":"docs/bob-architecture-event.html","lines":[1860,1860],"snippet":"<span class=\"pill\">redacted</span> <span class=\"pill\">bounded</span> <span class=\"pill\">per finding</span>","rule":"pii_redaction_present"}],"rules":[{"rule":"pii_redaction_present","matched":1,"weight":0.5},{"rule":"privacy_documentation","matched":0,"weight":0.5}],"rationale":"Composite raw score 0.50 (1/2 rules matched).","confidence":1,"needsLlmJudge":true,"verified":true,"verifyMethod":"skipped"},{"clauseId":"nist-ai-rmf/measure-2.11","regulationId":"nist-ai-rmf-1.0","article":"MEASURE 2.11","title":"Fairness and bias evaluated","principle":"fairness","verdict":"fail","score":0,"rawScore":0,"evidence":[],"rules":[{"rule":"bias_evaluation_present","matched":0,"weight":1}],"rationale":"Composite raw score 0.00 (0/1 rules matched).","confidence":0.55,"needsLlmJudge":false,"verified":true,"verifyMethod":"deterministic-only"},{"clauseId":"nist-ai-rmf/manage-2.3","regulationId":"nist-ai-rmf-1.0","article":"MANAGE 2.3","title":"Mechanisms to supersede or deactivate AI systems","principle":"human-oversight","verdict":"partial","score":2,"rawScore":0.6,"evidence":[{"file":".claude/hooks/session-read-guard.sh","lines":[150,150],"snippet":"rr, ) raise SystemExit(2) def looks_like_path(token): if not token or token.startswith(\"-\"): return False if token","rule":"kill_switch"},{"file":".claude/hooks/session-read-guard.sh","lines":[208,208],"snippet":"(blocked) raise SystemExit(0) command = tool_input.get(\"command\", \"\") if command: check_bash_command(command) raise SystemExit(0)","rule":"kill_switch"},{"file":".claude/hooks/session-read-guard.sh","lines":[214,214],"snippet":"and(command) raise SystemExit(0) PY","rule":"kill_switch"},{"file":".claude/hooks/session-write-guard.sh","lines":[138,138],"snippet":"s.stderr) raise SystemExit(2) def extract_redirect_targets(command): \"\"\"Extract file paths from shell redirect operators and tee c","rule":"kill_switch"},{"file":".claude/hooks/session-write-guard.sh","lines":[202,202],"snippet":") raise SystemExit(0) # Bash tool command = tool_input.get(\"command\", \"\") if not command: raise SystemExit(0) # Quick gate","rule":"kill_switch"},{"file":".claude/hooks/session-write-guard.sh","lines":[207,207],"snippet":"command: raise SystemExit(0) # Quick gate: skip if no write indicators has_redirects = re.search(r\">{1,2}\\s|tee\\s\", command) has_open_","rule":"kill_switch"}],"rules":[{"rule":"kill_switch_present","matched":1,"weight":0.6},{"rule":"feature_flag_for_disable","matched":0,"weight":0.4}],"rationale":"Composite raw score 0.60 (1/2 rules matched).","confidence":1,"needsLlmJudge":true,"verified":true,"verifyMethod":"skipped"},{"clauseId":"nist-ai-rmf/manage-4.1","regulationId":"nist-ai-rmf-1.0","article":"MANAGE 4.1","title":"Post-deployment monitoring, appeal and override, change management","principle":"auditability","verdict":"partial","score":2,"rawScore":0.5,"evidence":[{"file":".claude/hooks/session-read-guard.sh","lines":[150,150],"snippet":"rr, ) raise SystemExit(2) def looks_like_path(token): if not token or token.startswith(\"-\"): return False if token","rule":"kill_switch"},{"file":".claude/hooks/session-read-guard.sh","lines":[208,208],"snippet":"(blocked) raise SystemExit(0) command = tool_input.get(\"command\", \"\") if command: check_bash_command(command) raise SystemExit(0)","rule":"kill_switch"},{"file":".claude/hooks/session-read-guard.sh","lines":[214,214],"snippet":"and(command) raise SystemExit(0) PY","rule":"kill_switch"},{"file":".claude/hooks/session-write-guard.sh","lines":[138,138],"snippet":"s.stderr) raise SystemExit(2) def extract_redirect_targets(command): \"\"\"Extract file paths from shell redirect operators and tee c","rule":"kill_switch"},{"file":".claude/hooks/session-write-guard.sh","lines":[202,202],"snippet":") raise SystemExit(0) # Bash tool command = tool_input.get(\"command\", \"\") if not command: raise SystemExit(0) # Quick gate","rule":"kill_switch"},{"file":".claude/hooks/session-write-guard.sh","lines":[207,207],"snippet":"command: raise SystemExit(0) # Quick gate: skip if no write indicators has_redirects = re.search(r\">{1,2}\\s|tee\\s\", command) has_open_","rule":"kill_switch"},{"file":"package.json","rule":"versioning_visible"}],"rules":[{"rule":"feedback_capture_present","matched":0,"weight":0.3},{"rule":"override_path_present","matched":1,"weight":0.3},{"rule":"structured_logging_imported","matched":0,"weight":0.2},{"rule":"versioning_visible","matched":1,"weight":0.2}],"rationale":"Composite raw score 0.50 (2/4 rules matched).","confidence":1,"needsLlmJudge":true,"verified":true,"verifyMethod":"skipped"},{"clauseId":"gdpr/art-5-principles","regulationId":"gdpr-2016","article":"5","title":"Principles relating to processing of personal data","principle":"transparency","verdict":"fail","score":0,"rawScore":0,"evidence":[],"rules":[{"rule":"presence_of_privacy_policy","matched":0,"weight":0.5},{"rule":"purpose_limitation_documented","matched":0,"weight":0.5}],"rationale":"Composite raw score 0.00 (0/2 rules matched). Supporting docs may exist outside the repo.","confidence":0.6,"needsLlmJudge":false,"verified":true,"verifyMethod":"deterministic-only"},{"clauseId":"gdpr/art-22-automated-decisions","regulationId":"gdpr-2016","article":"22","title":"Automated individual decision-making, including profiling","principle":"human-oversight","verdict":"partial","score":2,"rawScore":0.4,"evidence":[{"file":".claude/hooks/session-read-guard.sh","lines":[150,150],"snippet":"rr, ) raise SystemExit(2) def looks_like_path(token): if not token or token.startswith(\"-\"): return False if token","rule":"appeal_or_override_mechanism"},{"file":".claude/hooks/session-read-guard.sh","lines":[208,208],"snippet":"(blocked) raise SystemExit(0) command = tool_input.get(\"command\", \"\") if command: check_bash_command(command) raise SystemExit(0)","rule":"appeal_or_override_mechanism"},{"file":".claude/hooks/session-read-guard.sh","lines":[214,214],"snippet":"and(command) raise SystemExit(0) PY","rule":"appeal_or_override_mechanism"},{"file":".claude/hooks/session-write-guard.sh","lines":[138,138],"snippet":"s.stderr) raise SystemExit(2) def extract_redirect_targets(command): \"\"\"Extract file paths from shell redirect operators and tee c","rule":"appeal_or_override_mechanism"},{"file":".claude/hooks/session-write-guard.sh","lines":[202,202],"snippet":") raise SystemExit(0) # Bash tool command = tool_input.get(\"command\", \"\") if not command: raise SystemExit(0) # Quick gate","rule":"appeal_or_override_mechanism"},{"file":".claude/hooks/session-write-guard.sh","lines":[207,207],"snippet":"command: raise SystemExit(0) # Quick gate: skip if no write indicators has_redirects = re.search(r\">{1,2}\\s|tee\\s\", command) has_open_","rule":"appeal_or_override_mechanism"}],"rules":[{"rule":"human_review_path_present","matched":0,"weight":0.6},{"rule":"appeal_or_override_mechanism","matched":1,"weight":0.4}],"rationale":"Composite raw score 0.40 (1/2 rules matched). Supporting docs may exist outside the repo.","confidence":1,"needsLlmJudge":true,"verified":true,"verifyMethod":"skipped"},{"clauseId":"gdpr/art-25-by-design","regulationId":"gdpr-2016","article":"25","title":"Data protection by design and by default","principle":"privacy","verdict":"pass","score":4,"rawScore":1,"evidence":[{"file":"mcp/lib/egress-profiles.js","lines":[5,5],"snippet":"redaction","rule":"pseudonymisation_or_anonymisation"},{"file":"mcp/lib/evidence.js","lines":[378,378],"snippet":"Redaction","rule":"pseudonymisation_or_anonymisation"},{"file":"mcp/lib/findings-index.js","lines":[37,37],"snippet":"crypto.createHash(\"sha256\")","rule":"pseudonymisation_or_anonymisation"},{"file":"mcp/lib/findings.js","lines":[94,94],"snippet":"crypto.createHash(\"sha256\")","rule":"pseudonymisation_or_anonymisation"},{"file":"README.md","rule":"default_minimal_data_collection"}],"rules":[{"rule":"pseudonymisation_or_anonymisation","matched":1,"weight":0.5},{"rule":"default_minimal_data_collection","matched":1,"weight":0.5}],"rationale":"Composite raw score 1.00 (2/2 rules matched). Supporting docs may exist outside the repo.","confidence":0.6,"needsLlmJudge":false,"verified":true,"verifyMethod":"deterministic-only"},{"clauseId":"gdpr/art-30-records","regulationId":"gdpr-2016","article":"30","title":"Records of processing activities","principle":"auditability","verdict":"fail","score":0,"rawScore":0,"evidence":[],"rules":[{"rule":"presence_of_processing_register","matched":0,"weight":1}],"rationale":"Composite raw score 0.00 (0/1 rules matched). Supporting docs may exist outside the repo.","confidence":0.55,"needsLlmJudge":false,"verified":true,"verifyMethod":"deterministic-only"},{"clauseId":"gdpr/art-32-security","regulationId":"gdpr-2016","article":"32","title":"Security of processing","principle":"security-governance","verdict":"partial","score":2,"rawScore":0.5,"evidence":[{"file":"mcp/auto-signup.js","lines":[78,78],"snippet":"https://api.capsolver.com/createTask","rule":"encryption_at_rest_or_transit"},{"file":"mcp/lib/aptos-rpc-pool.js","lines":[15,15],"snippet":"https://api.mainnet.aptoslabs.com/v1","rule":"encryption_at_rest_or_transit"},{"file":"mcp/lib/auth.js","lines":[298,298],"snippet":"https://${domain}/`))","rule":"encryption_at_rest_or_transit"},{"file":"mcp/lib/capability-eval-harness.js","lines":[6,6],"snippet":"require(\"crypto\")","rule":"encryption_at_rest_or_transit"}],"rules":[{"rule":"encryption_at_rest_or_transit","matched":1,"weight":0.5},{"rule":"access_control_enforcement","matched":0,"weight":0.5}],"rationale":"Composite raw score 0.50 (1/2 rules matched). Supporting docs may exist outside the repo.","confidence":1,"needsLlmJudge":true,"verified":true,"verifyMethod":"skipped"},{"clauseId":"gdpr/art-35-dpia","regulationId":"gdpr-2016","article":"35","title":"Data protection impact assessment (DPIA)","principle":"safety","verdict":"fail","score":0,"rawScore":0,"evidence":[],"rules":[{"rule":"presence_of_dpia","matched":0,"weight":1}],"rationale":"Composite raw score 0.00 (0/1 rules matched). Supporting docs may exist outside the repo.","confidence":0.55,"needsLlmJudge":false,"verified":true,"verifyMethod":"deterministic-only"},{"clauseId":"iso-42001/clause-5.1-leadership","regulationId":"iso-42001-2023","article":"5.1","title":"Leadership and commitment for AI management","principle":"accountability","verdict":"fail","score":0,"rawScore":0,"evidence":[],"rules":[{"rule":"presence_of_ai_policy","matched":0,"weight":0.7},{"rule":"leadership_signoff_evidence","matched":0,"weight":0.3}],"rationale":"Composite raw score 0.00 (0/2 rules matched). Supporting docs may exist outside the repo.","confidence":0.6,"needsLlmJudge":false,"verified":true,"verifyMethod":"deterministic-only"},{"clauseId":"iso-42001/clause-5.3-roles","regulationId":"iso-42001-2023","article":"5.3","title":"Roles, responsibilities and authorities","principle":"accountability","verdict":"pass","score":4,"rawScore":1,"evidence":[{"file":".github/CODEOWNERS","rule":"presence_of_raci_or_owners"}],"rules":[{"rule":"presence_of_raci_or_owners","matched":1,"weight":1}],"rationale":"Composite raw score 1.00 (1/1 rules matched). Supporting docs may exist outside the repo.","confidence":0.55,"needsLlmJudge":false,"verified":true,"verifyMethod":"deterministic-only"},{"clauseId":"iso-42001/clause-6.1-risk-assessment","regulationId":"iso-42001-2023","article":"6.1","title":"AI risk assessment process","principle":"safety","verdict":"fail","score":0,"rawScore":0,"evidence":[],"rules":[{"rule":"presence_of_risk_register","matched":0,"weight":0.6},{"rule":"risk_assessment_methodology_documented","matched":0,"weight":0.4}],"rationale":"Composite raw score 0.00 (0/2 rules matched). Supporting docs may exist outside the repo.","confidence":0.6,"needsLlmJudge":false,"verified":true,"verifyMethod":"deterministic-only"},{"clauseId":"iso-42001/clause-7.5-documented-information","regulationId":"iso-42001-2023","article":"7.5","title":"Documented information for the AI management system","principle":"auditability","verdict":"pass","score":3,"rawScore":0.7,"evidence":[{"file":"README.md","rule":"presence_of_versioned_docs"},{"file":".github/workflows/release.yml","rule":"docs_changelog_present"}],"rules":[{"rule":"presence_of_versioned_docs","matched":0.4,"weight":0.5},{"rule":"docs_changelog_present","matched":1,"weight":0.5}],"rationale":"Composite raw score 0.70 (1/2 rules matched). Supporting docs may exist outside the repo.","confidence":0.9,"needsLlmJudge":true,"verified":true,"verifyMethod":"skipped"},{"clauseId":"iso-42001/clause-8.1-operational-planning","regulationId":"iso-42001-2023","article":"8.1","title":"Operational planning and control","principle":"safety","verdict":"partial","score":2,"rawScore":0.5,"evidence":[{"file":".github/workflows/","rule":"presence_of_ci_workflows"}],"rules":[{"rule":"presence_of_runbook","matched":0,"weight":0.5},{"rule":"presence_of_ci_workflows","matched":1,"weight":0.5}],"rationale":"Composite raw score 0.50 (1/2 rules matched). Supporting docs may exist outside the repo.","confidence":1,"needsLlmJudge":true,"verified":true,"verifyMethod":"skipped"},{"clauseId":"iso-42001/clause-9.1-monitoring","regulationId":"iso-42001-2023","article":"9.1","title":"Monitoring, measurement, analysis and evaluation","principle":"auditability","verdict":"partial","score":2,"rawScore":0.5,"evidence":[{"file":"tests/","rule":"presence_of_eval_suite"},{"file":".claude/hooks/bob-update.js","lines":[64,64],"snippet":"he(projectDir); console.log(\"Hacker Bob update cache cleared.\"); return; } usage(); process.exit(1); } main(process.argv.sli","rule":"structured_logging_present"},{"file":".claude/hooks/hunter-subagent-stop.js","lines":[238,238],"snippet":"ndoff, })); console.log(JSON.stringify({ ok: true, message: \"post-report evidence run accepted\" })); process.exit(0); } con","rule":"structured_logging_present"}],"rules":[{"rule":"presence_of_eval_suite","matched":0.5,"weight":0.5},{"rule":"structured_logging_present","matched":0.5,"weight":0.5}],"rationale":"Composite raw score 0.50 (2/2 rules matched). Supporting docs may exist outside the repo.","confidence":1,"needsLlmJudge":true,"verified":true,"verifyMethod":"skipped"},{"clauseId":"iso-42001/annex-a5-internal-org","regulationId":"iso-42001-2023","article":"A.5","title":"Internal organization controls","principle":"accountability","verdict":"pass","score":4,"rawScore":1,"evidence":[{"file":".github/CODEOWNERS","rule":"presence_of_codeowners"}],"rules":[{"rule":"presence_of_codeowners","matched":1,"weight":1}],"rationale":"Composite raw score 1.00 (1/1 rules matched). Supporting docs may exist outside the repo.","confidence":0.55,"needsLlmJudge":false,"verified":true,"verifyMethod":"deterministic-only"},{"clauseId":"iso-42001/annex-a7-resources","regulationId":"iso-42001-2023","article":"A.7","title":"Resources for AI systems","principle":"security-governance","verdict":"pass","score":4,"rawScore":1,"evidence":[{"file":"SECURITY.md","rule":"presence_of_security_policy"},{"file":"package-lock.json","rule":"dependency_pinning"}],"rules":[{"rule":"presence_of_security_policy","matched":1,"weight":0.5},{"rule":"dependency_pinning","matched":1,"weight":0.5}],"rationale":"Composite raw score 1.00 (2/2 rules matched). Supporting docs may exist outside the repo.","confidence":0.6,"needsLlmJudge":false,"verified":true,"verifyMethod":"deterministic-only"}],"grade":{"overallScore":1.8695652173913044,"perRegulation":[{"regulationId":"eu-ai-act-2024-08","scoreAvg":2.090909090909091,"passCount":8,"partialCount":6,"failCount":8,"externalCount":1,"naCount":2},{"regulationId":"nist-ai-rmf-1.0","scoreAvg":1.3,"passCount":0,"partialCount":5,"failCount":5,"externalCount":0,"naCount":0},{"regulationId":"gdpr-2016","scoreAvg":1.3333333333333333,"passCount":1,"partialCount":2,"failCount":3,"externalCount":0,"naCount":0},{"regulationId":"iso-42001-2023","scoreAvg":2.375,"passCount":4,"partialCount":2,"failCount":2,"externalCount":0,"naCount":0}]},"bundleHash":"2c8fdda9d0067b798f5bb5ac7cd595938c03bf30d1a3271be1676e5e97f17443","checkerVersion":"v0.1.0","regulationsVersions":{"eu-ai-act-2024-08":"ee8568c60676d1c60c00393077dc7b9753628a16bb96049d6caa384b93516239","nist-ai-rmf-1.0":"b36616651114a74e212e4416e72f3d320d3ea46e1c93d7d3919cd44b5f71f762","gdpr-2016":"a650813378c93140abcbda864a7248289096abec98d57667cb0c0e2cba1bfe3f","iso-42001-2023":"3855f297eea17980b71d32e9d8c9f113c153c68e07b01fd442392fba4567755d"},"startedAt":"2026-05-20T19:36:01.183Z","completedAt":"2026-05-20T19:36:30.006Z","durationMs":28823,"externalControls":[{"clauseId":"eu-ai-act/art-5/1h-realtime-rbi","article":"5(1)(h)","title":"Real-time remote biometric identification in public spaces","note":"Deployment context (public space, real-time, law enforcement use, judicial\nauthorisation) is operational, not knowable from code. Always external."}]}}