#!/usr/bin/env node // PreToolUse guard:人格鎖驗證 + 跨人格資料隔離。 // // 定位:**防漂移的護欄,不是對抗性沙箱**。它擋的是「模型在正常工作中不小心讀到、 // 寫到別的人格」——對模型會自然寫出來的形式一律 deny;它不擋一個知道 guard 存在、 // 刻意要繞過去的對手(直譯器逃逸、逐段 cd、引號切割 token 都繞得過,這條路用正則 // 補不完)。詳見 README 的〈guard 擋得住什麼、擋不住什麼〉。 // // 擋下的情形: // * 讀寫非「本 session 當前人格」的人格目錄(Read/Write/Edit/LS 的路徑欄位、 // Glob/Grep 的 path 與樣式欄位、沒給 path 時的 cwd、Bash 指令裡直接出現的路徑) // * guest(persona-guest sub agent)寫入任何人格檔案,或換讀別的人格 // * CLI 帶假的 --session(冒用其他程序身分)/主程序冒用 guest 或 sleeper 身分 // * 目標人格的鎖屬於其他還活著的程序 // // 身分類的判定 CLI 自己也會再驗一次,不把最後一道關卡放在 hook 上—— // hook 認得出這支 CLI 靠的是檔名,改個名字就整路不表態了。 import { readEvent, respond } from "./_hook.mjs"; import * as pl from "../scripts/persona-lib.mjs"; const event = readEvent(); if (!event) process.exit(0); let result; try { result = pl.guardDecide(event); } catch (err) { // guard 自己壞掉不該擋住整個 session process.stderr.write(`persona guard 內部錯誤:${err.message}\n`); process.exit(0); } if (result.decision !== "deny") process.exit(0); respond({ hookSpecificOutput: { hookEventName: "PreToolUse", permissionDecision: "deny", permissionDecisionReason: `[jsc-persona 隔離] ${result.reason}`, }, });