/** * BSO M9-4 — guard session 状态(in-memory,sidecar 内驻) * * Refs: docs/prd/PRD-BSO-M9-HARNESS-HOOKS.md §3.4 * * 跟踪每个 harness session 的 brain_run 调用状态: * - harness SessionStart hook 调 POST /internal/guard/session-start → 登记 session * - agent 走 /brain/run → 触发 markSessionBrainRun(session_id? 或 fallback global last-at) * - harness PreToolUse hook 调 GET /internal/guard/check → 判定是否 "recent brain_run" * * MVP 限制(协议层冻结:不能给 /brain/run 加 session_id 参数): * - /brain/run 并不知道当前 harness session_id(agent 不传) * - 所以 markSessionBrainRun 只打 global `lastBrainRunAt` * - check 逻辑:如果 session 存在且 (last_brain_run_at within windowMs) → 放行 * * 后续迭代(M9.5+)可以加 per-session 精确追踪(当 MCP 协议允许带 session_id 时)。 */ export interface GuardSession { session_id: string; harness?: string; cwd?: string; started_at: number; /** 本 session 期间是否有过 brain_run(false 时 check 看 global fallback) */ brain_run_called_locally: boolean; last_tool_check_at?: number; last_pre_tool_blocked_at?: number; pre_tool_blocked_count: number; } export interface GuardStateSnapshot { sessions: GuardSession[]; last_brain_run_at: number | null; last_brain_run_skill_id: string | null; brain_run_window_ms: number; } export declare class GuardState { private readonly now; private readonly windowMs; private sessions; private lastBrainRunAt; private lastBrainRunSkillId; constructor(now?: () => number, windowMs?: number); startSession(opts: { session_id: string; harness?: string; cwd?: string; }): GuardSession; /** /brain/run 调用后调。因协议层没带 session_id,这里只更新 global;若 caller 知道 sid 可传入 */ markBrainRun(skill_id: string | null, session_id?: string): void; /** * PreToolUse 的核心决策。 * * 放行条件(任一命中即可): * A) session 存在,且该 session 本地记录过 brain_run * B) 没 session 级记录,但 global lastBrainRunAt 在 windowMs 内 * C) session 存在且 harness 在 fail-open 白名单(目前无) * * 拦截:session 不存在 → 放行(hook 层可能在 SessionStart 之前触发) * session 存在但两个条件都不满足 → 拦截 */ checkPreToolUse(opts: { session_id: string; tool?: string; }): { allow: boolean; reason: string; hint?: string; }; /** PostToolUse:纯 audit,不阻断 */ recordPostToolUse(opts: { session_id: string; tool?: string; outcome?: 'ok' | 'error'; }): void; snapshot(): GuardStateSnapshot; /** 测试/诊断用:清空状态 */ reset(): void; } /** 单例(sidecar 进程内共享) */ export declare const guardState: GuardState; //# sourceMappingURL=state.d.ts.map