bookworm-smart-assistant/hooks/agent-claim-observer.js.bak-p01.1777279385170
Bookworm Admin b7a8e29d21 release: v6.7.0 - OTA E2E test release
- VERSION file as authoritative version source
- export.mjs reads VERSION with package.json fallback
- bw-ota.ps1 DryRun mode for safe testing
- auto-setup.ps1 bumped to v3.2.0 (Phase 8 OTA)
2026-04-27 17:59:44 +08:00

88 lines
2.4 KiB
JavaScript

#!/usr/bin/env node
/**
* agent-claim-observer.js — P0 被动审计观察者 (v6.6-rc2)
* AGENT_CLAIM_OBSERVER_P0
*
* SubagentStop 钩子 · 纯观察 · 不阻断 · fail-open
* 记录 Agent 返回元数据到 debug/agent-returns.jsonl
* 字段: {ts, traceId, session_id, agent_type, agent_id, text_length, pid}
*
* P0 观察期目标: 累积真实 Agent 返回数据, 为 P1 verifier 决策提供基线.
*/
'use strict';
const fs = require('fs');
const path = require('path');
let CLAUDE_ROOT;
try {
CLAUDE_ROOT = require('./lib/root.js');
} catch {
CLAUDE_ROOT = path.dirname(__dirname);
}
const LOG_FILE = path.join(CLAUDE_ROOT, 'debug', 'agent-returns.jsonl');
const WATCHDOG_MS = 3000;
function readStdinSync() {
try {
return JSON.parse(fs.readFileSync(0, 'utf8'));
} catch {
return null;
}
}
function extractText(tr) {
if (!tr) return '';
if (typeof tr === 'string') return tr;
if (typeof tr.content === 'string') return tr.content;
if (Array.isArray(tr.content)) {
return tr.content
.filter(b => b && b.type === 'text' && typeof b.text === 'string')
.map(b => b.text)
.join('\n');
}
return '';
}
function extractTraceId(input, text) {
// 正则有界 (8-64 hex-like), 防 ReDoS
const re = /<trace>(bwr-[A-Za-z0-9-]{8,64})<\/trace>/;
const prompt = (input && input.tool_input && input.tool_input.prompt) || '';
const m1 = re.exec(prompt);
if (m1) return m1[1];
const m2 = re.exec(text);
if (m2) return m2[1];
return '';
}
function main() {
const wdt = setTimeout(() => process.exit(0), WATCHDOG_MS);
wdt.unref();
try {
const input = readStdinSync();
if (input) {
const text = extractText(input.tool_response);
const traceId = extractTraceId(input, text);
const record = {
ts: new Date().toISOString(),
traceId: traceId,
session_id: input.session_id || '',
agent_type: (input.tool_input && input.tool_input.subagent_type) || '',
agent_id: input.agent_id || input.tool_use_id || '',
text_length: text.length,
pid: process.pid,
};
try { fs.mkdirSync(path.dirname(LOG_FILE), { recursive: true }); } catch {}
fs.appendFileSync(LOG_FILE, JSON.stringify(record) + '\n');
}
} catch {
// fail-open: 观察者异常不阻断主流程
}
clearTimeout(wdt);
process.exit(0);
}
if (require.main === module) main();
module.exports = { extractText, extractTraceId };