본문으로 건너뛰기
I

focus-guard (core)

irisblackwood/focus-guard/packages/core

Blocks AI coding agents from editing files without evidence and from running unapproved high-risk commands, and tells quoted dangerous strings apart from commands actually being executed.

설치

dsh plugin --profile web add github:irisblackwood/focus-guard

이 플러그인은 저장소의 packages/core 하위 디렉터리에 있습니다.

README

FocusGuard 聚焦护栏

CI version License: MIT Node

ZCode 原生硬拦截 + DSH 经官方桥硬拦截 · 零依赖 · 钩子层 AI 行为治理

FocusGuard 不是另一把 Hook 枪,它是 AI 行为治理的完整体系:立法(法条定标准)→ 执法(引擎机械执行)→ 监察(全程留痕可复核)。日常对话零打扰,一旦出现未取证就改、结论无锚点、整读大文件烧上下文、无限空转等失控行为,立刻按梯度处罚——打回、强制取证、熔断、记档、降权、上报,人类随时可复核。

它不是提示词里的一句"请不要乱来",而是把失控行为变成钩子层可机械拦截的事件。

30 秒速览

失控现象机械拦截人类看到
没调查就改文件 / 执行变更命令触发① → L1 打回一条拒绝原因
结论没有 [文件:行号] 证据触发② → 收尾打回一条打回理由
整读 50KB 大文件、裸 cat 刷屏触发③ 体积三闸一行"分段读或交子代理"
反复无效调用、无限空转触发④ 预算+停滞 → L3 熔断熔断出口 + 三行降级方案
查无实据还硬凑触发⑤ → 熔断同上
拿到授权不吭声就绕过护栏授权识别核验(引原文+法条)越权 → L3 熔断
顺手 rm -rf / git push / npm publish高危命令闸:一行审批单y 放行本次 / n 彻底阻断
上下文被巨量输出撑爆污染检测 + 卷宗免重读记档 + 复用已有取证
反复读同一个没变的文件卷宗指纹 + TTL拦截本次 Read(offset 增量读永远放行)
大搜索/大文档主会话硬扛强制委派场景 + 委派法典KPI 计分,收尾结算委托池奖惩(3.0)
表现只有记分牌没有后果KPI 兑现闭环(3.0)收尾即结算:等次 → 委托池 ±5/±2,跨任务累计
出了事日志是一笔糊涂账因果链留痕 seq/chain/ref(3.0)npm run chain 渲染因果树/因果图
经验库被 AI 自己写坏资料分层 + 派生积木(3.0).ai/library/ 只同步外部原文;积木由 library-build 派生,两区均禁直写
云端判定贵且离线不可用本地零成本哨兵(3.0)FG_SENTINEL=1 启用,Needle 2 可插拔外判
高危操作事前没有审核,出事才拦资格审核六层 + fg_apply 申请通道(3.0.5)无授权 → 拒,理由指向申请入口
被引用的危险命令字符串被误拦绝对红线上下文豁免:引号内 / 数据标记 / 只读命令三判据(3.0.6)降级到语义预判,不再直接拒
拦错了没有程序可走,只能绕过fg_appeal 误伤申辩(司法救济,3.0.6)人类一次性裁决:批准即豁免本次红线
大小模型一刀切,贵的模型被过度打扰模型画像五份 + 按画像跳层(3.0.5)审核强度随模型调整
本机习惯用 rg/fd,AI 老写 grep/find环境指纹 + 命令硬校验(3.0.5)一行替代提示,不依赖模型自觉

为什么需要它

AI 智能体最常见的三种失控:

  1. 思考失控:没有证据就开猜,越查越偏,停不下来;
  2. 资源失控:整读大文件、未过滤刷屏,上下文和 token 被无意义输出撑爆;
  3. 权限失控:拿不准也硬改,先斩后奏,出了问题无法追溯。

"立法 → 执法 → 监察"三件套把这三类失控变成可拦截的行为事件:法条(packages/core/docs/RULES.md)定标准,引擎机械执行,留痕(.focus-guard/AUDIT.log)接受人类复核。

引擎按"母版层 → 适配层 → 宿主缝"三层组织(《资料与代码分层总规范》):

层位置职责
母版层packages/core/src/core/零依赖、宿主无关的判定逻辑:六层资格审核 / 模型画像 / 绝对红线与上下文豁免 / 申辩 / 卷宗状态。不得反向依赖适配层(有验收用例锁定)
适配层packages/core/src/adapters/dsh/把母版接进 DSH:fg_apply / fg_appeal 工具注册 + 资格闸
宿主缝packages/core/src/dsh/pipeline.mjsDSH 原生插件的三条缝:pre-execute / system-prompt / post-execute
ZCode 执行壳packages/core/hooks/guard.mjs六事件钩子入口。已封存——ZCode 兼容层,版本号独立、不随主版本更新,改动须谨慎

快速开始

核心版与扩展版的关系:focus-guard(packages/core/)是零依赖范本包——引擎钩子、技能、核心工具、法条文档,所有人从这里开始;focus-guard-extended(packages/extended/)是扩展衍生包,依赖核心包,承载重型外接集成(OpenViking 同步桥 / Needle 2 本地模型外判 / Semantica 图谱导出)。核心版是范本,可衍生无数扩展变体;下载核心版时不需要也不会拉取任何扩展依赖。

npm install focus-guard           # 核心版:零依赖,装完即用
npm install focus-guard-extended  # 扩展版:按需启用外接集成(自动带上核心版)

ZCode 插件(推荐):克隆本仓库 → 插件市场 → 添加市场(选择含 marketplace.json 的仓库根目录)→ 插件列表安装 → 新开会话。

DSH 有两条路,二选一、互斥(同缝双监听 = 双跑):

路径装什么拿到什么
原生插件(3.0.5 起,推荐)dsh plugin --profile <name> add <本仓库 packages/core 目录>三条宿主缝全开:资格审核 + fg_apply/fg_appeal + 模型画像 + 命令硬校验 + 红线上下文豁免
官方桥@deepseek-ai/dsh-hooks-claude-code 挂载 packages/core/hooks/hooks.json与 ZCode 同级的六事件硬拦截(exit 2 阻断、stderr 原文透传、Stop 打回),但不含原生插件独有的资格审核与申辩

⚠ 两条路同时挂载会双跑;都不装则 DSH 端没有拦截。挂桥/装插件的逐行步骤与卸载见 INSTALL.md 第二、四节。

验证生效:新会话开头出现 <focus-guard AI履职执法模型v3.0 …> 注入,且工作区出现 .ai/CASE_FILE.md 与 .focus-guard/AUDIT.log。

逐行可复制的命令、DSH profile 挂桥、卸载与 FAQ(含"升级后版本没变"的部署漂移排查):见 INSTALL.md。

核心机制

空气层(日常零打扰)

对话、分析、讨论、解释:不查、不拦、不提醒。执法只看行为,不查词。

触发层(行为五条,违规即罚)

#触发条件判定
①未取证就改本回合 0 次调查(读文件/Grep/搜索/只读命令)就 Write/Edit/改动类 Bash
②无锚点结论回合内调用 ≥5 次后收尾无 [文件:行号]/[日志原文]/工具结果,也未标【假设】
③体积刺客整读 >50KB 文件、Grep content 无 head_limit、裸 cat/type 刷屏(批示含"审计/盘点/审查"时,取证对象整读留痕不罚——2.5.3)
④动态预算超限有效调用超任务预算,或连续 3 次无效调用(真失控)
⑤硬凑不熔断查无实据仍强行猜测;连续 2 次未知声明同样熔断

梯度处罚(L1–L6)

L1 打回重写 → L2 强制取证 → L3 熔断 → L4 记档 → L5 降权 → L6 上报人类

同回合违规数累加自动爬升。熔断期只读调查类仍可用、改动类全拒、非只读放行的高危命令同样拒绝(2.5.2 修复)。人类新指令即"批示"、全部解除;唯「停止/熔断」批示本身就是熔断,不会被解除。

预算与进度检测(三预算池)

  • 初始预算按批示关键词核定:审计/红队/重构/全量/批量/探索/遍历/升级/补丁 → 50;修复/添加/修改/重命名/删除 → 15;其他 → 10。首轮可声明【任务规模】上调,只升不降,硬上限 200;
  • 三池分立:侦查池(只读,独立 15 次)/执行池(Write/Edit/变更命令)/委托池(子代理,独立 20 次),互不挤占;短指令『追加额度』执行/侦查/委托三池各 +10;
  • 有效调用(返回内容有变化/产生文件变更/出现新报错)满阈值自动续杯 +10;
  • 无效调用(重复读同一内容/同命令同返回/失败调用)连续 3 次 → 判真失控直接熔断;停滞 2 次可申请【信用延期】,由人类批示。

卷宗体系(四册,总纲见 docs/MASTER-PLAN-2.0.0.md)

工作区档案 <工作区>/.ai/CASE_FILE.md:

册内容维护方
【一】环境声明OS / Shell / 编码 / 路径分隔符 / 大小写敏感 / BSD 工具 / 可用命令引擎(会话级一次检测,结果直接落卷可查阅)
【二】项目依赖声明依赖名 / 版本 / 安装路径 / 信任 TTL(如游戏本体 60 天)人工填写
【三】侦查取证记录文件名 / 读取时间 / mtime / size / SHA-256 / 变更历史 / TTL / 验证方式引擎自动追加
【四】工作额度台账初始额度 / 已用 / 剩余 / 有效 / 无效调用 / KPI引擎(回合末落卷)
  • 环境检测一次全程复用:SessionStart 检测一次,UserPromptSubmit 不重检,仅在探测到 shell 变化时重检;
  • 跨回合取证指纹:mtime + size + SHA-256(≤200KB)+ git 脏态,指纹一致且 TTL 未超 → 免重读放行(拦截本次 Read,复用已有取证);不一致或超时 → 放行真重读并更新卷宗。时间戳伪造(touch -d/cp -p/git checkout)无法绕过 SHA 内容校验;免重读限同一会话内——跨会话继承的卷宗指纹只提示不拦,首读永远放行(2.5.3);
    • 边界(别读成"任何尺寸都防伪"):SHA-256 只对 ≤200KB 的文件计算。超过 200KB 退回 mtime+size+git;工作区没有 git 时(gitDirty 为 null),"同尺寸改写 + 还原 mtime"无法被察觉。大文件请依赖版本库或单独做内容校验;
  • 自适应 TTL:首次 4 小时 → 7 天内有变 2 小时 → 7–30 天未变 24 小时 → 30 天未变 7 天;优先级 依赖声明 > 人工标注(【三】TTL 列手填)> 自适应;
  • 免重读豁免:offset 增量读永远放行;熔断/强制取证期豁免(降级重建证据需要真重读);
  • 跨平台命令拦截(按检出 shell 适配):PowerShell 会话禁 bash 管道(\| head、&&)与裸 Get-Content,改用 Select-String/Measure-Object/-TotalCount;macOS 禁 sed -i 无后缀、grep -P、readlink -f;大小写不敏感文件系统禁仅大小写不同的重名文件;Linux 标准 GNU 无特殊限制。

监察与留痕

  • 盲写拦截:写"本回合没读过的已存在文件"100% 拦截;
  • 风险文件留痕:package.json、lock、CI 配置、.env、.csproj 等修改 100% 记录;
  • 抽查A:每 5 次写操作全量审计 1 次(确定性节奏,不是随机抽样);
  • 上下文污染检测:工具输出与指令矛盾(单条语句的 head 行数超限 / 清单路径重复;复合命令不整段对账——2.5.3)→ 立即停用该输出,用带标记的小命令隔离核实并报告人类;
  • 回合卫生:回合开始核验上一回合计数/熔断/取证/降权残留(43条),异常记档后清理;新会话发现 HANDOFF.md 注入交叉巡视提醒(36条);引擎与工作区源码版本不一致告警(42条);
  • 一切执法行为(触发/处罚/抽查/特赦/预算伸缩)写入 <工作区>/.focus-guard/AUDIT.log(JSONL):时间 / 会话 / 动作 / 触发条件 / 级别 / 证据 / 是否特赦。

授权与高危命令审批

  • 授权识别:凡声称依人类授权绕过护栏(熔断/锚点/预算/体积),必须先出【授权识别】引人类指令原文 + 指明法条依据;引擎核验引文确实出现在本回合指令且含授权语义。伪造/事后补 → L3 熔断;意图明显但未明说 → 出【授权待确认】暂停并提问;
  • 高危命令闸:即使完全访问(yolo/自动批准)模式,六类不可逆命令仍须实时审批—— 破坏性删除(rm -r、rm --recursive、shutil.rmtree、find -delete、rimraf、DROP TABLE)、 强制推送与历史覆盖(git push、git reset --hard、git clean -fd)、 系统权限与配置(chmod 777、chown、reg add/delete、net user)、 全局依赖安装(npm i -g、pnpm add -g、yarn global add、apt-get install、docker run --privileged)、 对外发送与发布(npm publish、docker push、curl -X POST/-d、wget --post-data)、 数据库影响(无 where 的 DELETE/UPDATE、DROP DATABASE);
  • 审批单是唯一通道:命中 → 拒绝并要求一行 【高危申请】命令:<真实命令> | 真实目的:<一句话> | 影响范围:<具体文件/表/系统> | 回滚方案:<可否回滚> | 允许执行?(y/n); 收尾没带单 → Stop 打回补交(一次性,不无限重复);
  • y 放行本次(一次性,改一个字符都要重新申请);n 彻底阻断(会话内不得重发)。中文同样有效:同意/批准 = y,不/拒绝 = n;
  • 预授权隔离:任务指令里的「最后上传 github」只是目标预授权(goal),不解锁任何执行;执行级授权只认人类当下对审批单的短批示;
  • 严禁脚本包装:被拒后写 push.sh 再执行 = 对抗审查(从重记档);高危脚本的写入本身也要走审批单;
  • 不设卡:普通单文件 rm、构建、测试、本地 commit、常规 curl GET——零打断。放松日常 + 刚性高危。

事前资格审核与司法救济(3.0.5 / 3.0.6 / 3.0.7)

高危命令闸管的是事后拦截(命中即拒,再交人类审批)。3.0.5 起在其之前加一道事前资格审核:高危工具先申请、后执行,无授权直接拒。

  • 六层判定(packages/core/src/core/checkEligibility.mjs,母版层、依赖注入、不反向依赖适配层):

    层判什么
    L0申请完整性——purpose / scope 空白即拒
    L1状态——熔断 / 降权 / 预算耗尽
    L2绝对红线(命中即拒,且不进 L3)
    L3高危资格——命中 HIGH_RISK_TOOLS 且本会话无授权 → 转人工审批
    L4前置条件——改动类目标须已取证;系统路径 / 特殊目录(.git、node_modules)加严
    L5语义信号——模型探针的 mismatch / 高风险分
    L6授权并留痕
  • 双入口闭环:fg_apply(申请 → 审核 → 按 session 授权)与 pre-execute 的 gateToolCall(无授权 → deny,理由指向 fg_apply)。审核期临时授权、未通过立即收回,避免申请通道被自己的 L3 挡死。

  • 模型画像:src/profiles/ 五份纯参数画像(deepseek-flash / deepseek-pro / glm / gpt-astra / default),按画像跳层并把跳过项写入 trace 与审计。不传画像时与 3.0.4 行为一致。画像不能关闭审批层(profileLoader.mjs 的 FORCED_ON_SWITCHES 强制启用 approvalGate),也不能放行红线层;approvalGate.scope 只决定"哪些类别需审批"(irreversible 时非不可逆高危放行、不可逆类仍须审批)。

  • 环境指纹与命令硬校验:packages/core/tools/env-fingerprint.mjs 探测平台 / shell / 工具并产出 .ai/env-fingerprint.json;pipeline 第 1.5 层据其 map 表做命令硬校验(grep→rg、find→fd 等替代提示),不依赖模型自觉。

  • 绝对红线上下文豁免(3.0.6):红线在文本层匹配,分不清"要执行的命令"与"被引用的命令字符串"。三条判据把后者降级到第 2 层语义预判(绝不直接放行):① 命中片段完整落在引号字面量内;② 片段前有显式数据标记(示例:/例如:/测试数据/prompt:/【假设】/代码围栏)且命令非变更类;③ 首 token 属只读输出命令。执行外壳一律不豁免(bash -c / cmd /c / eval / iex / 解释器 -e·-c)——那些引号里的内容是真执行。豁免写 AUDIT.log(action:"redline-exempt" + 判据名 + 命中片段)。

  • 误伤申辩(司法救济通道,3.0.6):fg_appeal 让被拦方能当场申辩,不必等修法。参数携带被拦命令原文,故 pipeline 在所有闸之前处理它(否则会被同一规则再拦一次),转成 {kind:"ask"} 交人类一次性裁决:批准 → 开通该工具一次授权(ttl=turn)+ 豁免本次命中红线;拒绝 → 维持拦截。全程留痕 appeal-filed / appeal-granted / appeal-denied。法条依据见 RULES.md 第八十三条(四)。

子代理委派(v2.3.0:高产出、低污染)

机制规则机械化
委托池独立核算默认 20 次/任务,不占执行池;用尽批示『追加额度』三池各 +10每次委派记 delegate-used;用尽拒绝并请示
摘要强制格式主会话只收【子代理摘要】四字段(任务/结果/异常/文件线索),≤200 字超长或缺字段 → 拒收要求压缩(KPI-3)
强制委派场景全库搜索 ≥3 目录或 ≥10 文件 / 大文档 >50KB 或 >2000 行 / 批量 ≥5 文件未委派 → 未尽职提醒(KPI-5);已委派 +5
独立并行任务两个任务互不依赖自申明:引擎无机械特征,不判罚也不加分,AI 不得据此声称"已尽职"
合法委派边界正常委派放行不计违规仅熔断期启动子代理 = 越权绕行(L4+L5)

正面指引(告诉 AI 怎么干活)

负面清单管下限,正面指引给标准动作(法条第十五章之一,74–79 条;运行时镜像 packages/core/skills/focus-thinking/SKILL.md §10):

树杈标准动作机械化
环境适配环境不主动探测,行为暴露后自动适配;有 .git 用 git restore,没有用 .ai/backup/每次 Write/Edit 前自动备份到 .ai/backup/(保留最近 100 份;>200KB 跳过;.env/私钥不落明文副本)
返工与提交只回滚出错文件;重试带"失败包裹"(报错行号 + 堆栈尾 30 行 + 限定范围);本地 commit 测试全绿 AI 可做高危审批单:git push 命中特征库须【高危申请】,--dry-run 例外
污染与日志参数-输出矛盾 → 标记可疑;改文件前先出【污染核实】声明;超大日志只取统计 + 堆栈尾 30 行污染核实闸:污染检出后首个改动类先拦一次
任务编排第一句话声明"通过条件"(可测 = 退出码 0;不可测 = 编译 + 不崩溃 + 《人类验收清单》);机械任务优先内置库与既有预制脚本(.ai/tools/,存在则用)结案以机器退出码为准
人类交互提交前固定一行:【提交申请】修改:<文件> (+n,-m) | 测试:n/n 绿 | 允许提交?(y/n);仅不可逆操作请示其余全自动
经验固化L2/L3 或回滚后往 .ai/PATTERNS.md 追加 [环境:x] [任务:y] 以后遇到 X 必须先做 Y;新任务不预读,卡点时 Grep 检索熔断出口提示经验固化(触发熔断时引擎确保该文件存在)

配置

所有阈值集中在 packages/core/hooks/guard.mjs 顶部常量区:

常量默认说明
OUTPUT_GATE_BYTES50KB体积刺客闸值(整读/刷屏拦截线)
BUDGET_DEFAULT10默认任务预算
BUDGET_CAP200有效调用硬上限
REFILL10续杯步长
STALL_FUSE3连续无效调用熔断线
MERCY_SHORT30特赦短语仅认短指令的长度上限
RANDOM_AUDIT_EVERY5每 N 次写操作全量审计 1 次(确定性节拍)
INV_POOL_DEFAULT15侦查池独立额度
DELEGATE_DEFAULT20委托池默认额度(不占执行池)
SHA_LIMIT200KB卷宗 SHA-256 校验上限(超过则用 mtime+size+git 脏态)
CASE_MAX_ROWS200卷宗【三】最大行数(超出淘汰最旧)
BACKUP_KEEP100.ai/backup/ 最大保留份数
TTL_FIRST/RECENT/WEEK/STABLE4h / 2h / 24h / 7天卷宗自适应 TTL 四级
ENGINE_VERSION3.0.642条部署版本核验基准。版本面共 8 处(根 package.json / 根 marketplace.json / .zcode-plugin/plugin.json / .claude-plugin/plugin.json / .claude-plugin/marketplace.json / packages/core/package.json / packages/extended/package.json / ENGINE_VERSION),由断言锁定"彼此相等 且 等于 CHANGELOG 最新条目"。引擎头注释例外:guard.mjs 已封存、版本号独立,断言只锁"封存标注存在"

工作原理

SessionStart       → 环境检测一次 + 卷宗载入(重建取证缓存与 TTL 表)+ 注入执法模型
UserPromptSubmit   → 批示识别(关键词预算 / 信用延期 / 特赦 / 追加额度 / y-n)+ 重置任务态(保留侦查缓存)+ shell 变化重检 + 任务链起新链
PreToolUse         → 平台命令拦截 + 本地哨兵(opt-in)+ 图书馆直写拦截 + 高危审批闸 + 熔断白名单 + 未取证拦截 + 污染核实闸 + 体积三闸 + 盲写拦截 + 卷宗免重读 + 改动前备份
PostToolUse        → 进度检测引擎(三池 / 续杯 / 停滞熔断)+ 卷宗取证记录 + 污染检测 + 抽查 + 委派 KPI 计分
PostToolUseFailure → 失败计入停滞
Stop               → 回合边界 + 证据锚点检查 + 授权识别核验 + 审批单格式校验 + KPI 兑现结算 + 额度台账落卷

拦截协议:PreToolUse 以退出码 2 拒绝工具调用(原因走 stderr,原文透传给模型);Stop / PostToolUse 返回 {"decision":"block","reason":...} 打回重写。所有打回路径都有一次性保护(stopBlocked + 宿主的 stop_hook_active),不会因强制续跑变成死循环。

DSH 原生插件(src/dsh/pipeline.mjs)在同一条 PreToolUse 缝上按序叠加(各段独立 fail-open,异常一律放行或原样透传):

申辩入口(fg_appeal) → 第3层状态/取证校验 → 绝对红线(+上下文豁免/申辩凭据) → 第1.5层命令硬校验
→ 资格审核闸(fg_apply) → 第2层语义预判(哨兵) → next
  • 第 3 层取证校验只对已存在文件的修改要求先读;新建文件无目标可读,直接放行(否则死锁);
  • L3 不接红线上下文豁免(闸接、L3 不接):闸是"无授权即 deny"、无人类环节,必须自判豁免;L3 是"转人工审批"、人类环节本身就是裁决。若 L3 也豁免,"数据形态的高危命令"会无人审批直接放行——风险不对称。判定写在 checkEligibility.mjs 第 3 层注释里,防后人当缺陷改回。

留痕协议:AUDIT.log(JSONL)每条带 seq(事件唯一号)/ chain(任务链,委派派生 /dN 子链)/ ref(父事件)三字段——流水账可随时重组为因果树:node packages/core/tools/audit-chain.mjs <AUDIT.log> [--mermaid]。

落盘全图(写入面共 9 处):AUDIT.log、卷宗【一】环境声明、【三】侦查记录、【四】额度台账(同 CASE_FILE.md)、会话状态(%TEMP%)、改动前备份(.ai/backup/)、PATTERNS.md 经验库、TEMP 陈旧清扫、派生积木与索引(仅 library-build 写到 .ai/output/library/)。

常驻注入的体量

常驻注入 SESSION_RULES 运行期实测 425 字(246 全角 + 179 半角,≤500 字立法上限;3.0.0 因果链提示 +14 字)。典型长会话的执法可见开销加权实测 3404 字 ≈ 2269 tokens(2.5.3 实测值,3.0 新增报文:哨兵拦截 175 字级、图书馆隔离 40 字级、KPI 结算 0 字——仅落档不打扰):

场景引擎实测字符会话内次数加权
SessionStart 常驻注入531×1531
卷宗免重读放行(最高频)145 / 次×101450
触发③体积三闸(三连拦场景合计)278×1278
熔断出口(拒绝 + 打回)268×1268
动态预算续杯73 / 次×3219
高危审批闸拦截175×1175
强制场景未委派提醒131×1131
触发①未取证就改56 / 次×2112
委派摘要超长拒收107×1107
上下文污染检出93×193
盲写拦截40×140
加权合计3404 字 ≈ 2269 tokens(1 token ≈ 1.5 中文字符,区间 1702–2837)

复测:npm run bench。v2.2.0 曾对报文做电报体压缩(当时相对更早版本 -31.6%,对比基线已失效,只作历史记录);2.4.0 起审批单与委派报文变长,故当前总量高于那次优化后的数值。报文只保留"标签 + 动作指令",规则细节由技能与法典承载。

测试与质量闸

npm test                                             # 验收 101 用例(含版本一致性 / 版本追赶 / 文档-实现口径对齐)
npm run test:eligibility                             # 资格审核 45 用例(六层 + 红线豁免 + 申辩)
node --test packages/core/tests/integration.test.mjs  # 端到端 27 用例(画像→审核→授权→闸→取证闸)
node --test packages/core/tests/profile.test.mjs      # 画像加载 8 用例
npm run eval                                         # 对抗评测:61 条高危写法 + 34 条良性命令,有漏检或误报即 exit 1
npm run bench                                        # 报文体量基准
npm run check                                        # test + eval(pre-push 钩子跑的就是它)
npm run library                                      # 派生积木构建(默认 --src .ai/library --out .ai/output/library,幂等)
npm run chain -- <AUDIT.log路径> [--mermaid]         # 执法档案因果树渲染
npm run sentinel -- --check "<命令>"                  # 本地哨兵单条预判
npm run test:bridges                                 # 扩展包桥测试(单独跑)

双包架构(3.0.6):范本 + 衍生

本仓是 npm monorepo,一个项目、两个包:

包路径定位
focus-guardpackages/core/零依赖范本——引擎钩子、技能、核心工具、法条文档、DSH 原生插件。npm install focus-guard 只下载本包,不拉任何外接依赖。主分支即从此包发版,可衍生无数变体。DSH 挂载的正是这个包——它的 package.json 版本就是 GUI 里显示的那个。
focus-guard-extendedpackages/extended/扩展衍生包——依赖 core("dependencies": {"focus-guard": "^3.0.6"}),承载重型外接三件套:OpenViking 积木同步桥(viking-bridge.mjs)、Needle 2 外判运行器(needle2-sentinel.mjs)、Semantica LPG 图谱导出(audit-chain-semantica.mjs)。

衍生纪律(详见 packages/extended/bridges/README.md):桥只依赖主分支契约(审计 JSONL 格式、哨兵外判协议、积木 INDEX 格式),禁止 import 主分支源码,禁止被主分支引用(验收用例锁定零反向依赖);桥故障一律静默回退核心默认行为。新增外接 = 在 extended 包加一个自包含文件 + 一条桥测试。

  • CI:每次推送/PR 自动跑验收 + 对抗评测(.github/workflows/ci.yml)。Windows 必过;Linux/macOS 为观察项(验收里仍有数处 Windows shell 检测用例未平台化),Node 18.20 / 20 / 22 矩阵;
  • 本地质量闸(pre-push 钩子,GitHub Actions 不可用环境的主闸):.githooks/pre-push 在每次 git push 前强制 npm run check(验收 + 对抗评测),不过即阻止推送,结果留痕 AUDIT.log(ci-pre-push 事件)。克隆后启用一次:git config core.hooksPath .githooks;强行绕过(--no-verify)按法规须先批示——钩子留痕只在正常触发时写入,绕过即失察;
  • 覆盖范围(101 用例):动态预算与三池分池、进度检测与信用延期、触发①②③④⑤(含审计豁免)、梯度处罚与熔断只读放行、卷宗体系(环境检测 / 环境声明落卷 / 免重读含会话内限定 / SHA 防伪 / TTL 三级覆盖 / 台账落卷 / caseCache 裁剪)、跨平台命令拦截、盲写与抽查A、上下文污染与污染核实闸(含复合命令不误报)、授权识别(伪造引文 → L3 / 合规声明 → 特赦 / 待确认 → 暂停)、高危命令闸(特征库 / 审批单 / y-n 一次性 / 预授权隔离 / 脚本包装端到端 / 熔断期拒绝 / 超长命令)、子代理委派与委托池、极限场景(80KB 命令行、2MB 响应、损坏状态、奇异会话 ID、中文路径)、DSH 桥接自适应,以及工程自检(七处清单版本一致性 / 版本追赶 / 五处说明互不重复 / 文档-实现口径对齐 / RULES 注入逐字镜像 / hooks.json ↔ 引擎映射 / 部署漂移核验 / 61条陈旧清理);
  • 对抗评测样本按"同一危险动作的多种写法"组织(别名、长旗标、传参穿插)并配良性反例,避免用误报换检出。

设计取舍与已知边界

  • 回合边界双保险:实测 UserPromptSubmit 不保证触发,回合计数由可靠的 Stop 事件兜底清零,reset 仅作尽力而为的提前重置;
  • 钩子读取的是安装副本:改源码不会自动生效,需同步安装缓存或经市场更新——"源码已升级但引擎没变"是这套系统最常见的部署事故,INSTALL.md FAQ 4 有排查步骤;
  • 平台受限暂缓条款:第 21 条 Token 成本核算、第 37 条思考链监管(钩子层不可见 token 用量与思考时长)、第 64 条(二)(三)(四)限流(无对应信号);第 48 条子代理继承以留痕方式实现。完整"未机械化条款清单"见 packages/core/docs/RULES.md 附注——凡清单所列,AI 不得声称已由引擎自动执行;
  • >200KB 文件没有内容级防伪:见上文卷宗体系边界说明;
  • 引号内的危险字样:按上下文分级(3.0.6)——echo "git push"、grep -rn "delete from users" 这类被引用的数据经三条判据(引号内 / 数据标记 / 只读命令)降级到语义预判,不再直接拒;执行外壳内的一律不豁免(bash -c "…"、node -e "…"、eval "…"),因为那是真执行。仍未覆盖的形态:无引号又无数据标记的裸引用、rm${IFS}-rf 类拼接。判据名与命中片段写入 AUDIT.log 可复核;
  • 特征库不可能堵完:rm${IFS}-rf、base64 管道、shell 别名等在射程之外,护栏治的是"顺手失控",不是定向对抗;
  • 免重读的边界:指纹一致但会话上下文已被压缩时,用 offset 增量读或请批示;【二】依赖声明与【三】TTL 列人工标注可按需放宽/收紧;
  • 行业对照(2026-10 系统提示词研究,详见 docs/analysis/):各大厂商把 Agent 持久性推到极致("persist until complete")且提示词层无一设预算机制。FocusGuard 的定位由此清晰:坚持性交给模型自判(厂商已做好),成本台账与破坏性关卡由宿主侧硬约束承担——熔断随模型进化从常开保险丝退为断路器,但断路器不拆;
  • 违禁词扫描已废弃(v3.0 起"不查词"):空气层允许口语与主观语气,执法只看行为。

版本与变更

当前 v3.0.6。完整历史见 CHANGELOG.md。近期版本:

  • 3.0.6 绝对红线上下文豁免与司法救济:redlineExempt() 三判据(引号内 / 数据标记 / 只读命令)把"被引用的危险命令字符串"降级到语义预判,执行外壳一律不豁免;新增 误伤申辩程序 fg_appeal(司法救济通道,补齐"只有立法救济、没有个案当场申辩"的结构缺口);画像接入真实 pre-execute 链路 + 画像/豁免在真实入口失效的 4 项修复;审批层不可被画像关闭;approvalGate.scope 由死配置变真判定;闸接入红线豁免、红线判据 span 稳定化、取证闸对新建文件不再死锁;条款清理 91→87;版本面补全为 8 处(此前漏了 monorepo 子包,导致"清单齐 3.0.4 而代码已 3.0.6");

  • 3.0.5 事前资格审核与模型画像:checkEligibility 六层判定(L0 申请完整性 / L1 状态 / L2 绝对红线 / L3 高危资格 / L4 前置条件 / L5 语义信号 / L6 授权留痕)+ fg_apply 双入口闭环(申请 → 审核 → 按 session 授权);src/profiles/ 五份纯参数模型画像 + profileLoader 按画像跳层;环境指纹与命令硬校验(grep→rg、find→fd);guard.mjs 三次拆出 src/core/ 九个模块与 src/adapters/dsh/protocol.mjs(1707 → 1142 行);

  • 3.0.4 双包 monorepo:packages/core(focus-guard 零依赖范本包)+ packages/extended(focus-guard-extended 扩展包,承载外接三件套);npm install focus-guard 永不拉取扩展依赖;中心蜂群强化——调度三分法、派单给目标不给方法脚本、跨任务授权不对称、模型分层蜂群、对抗验证三怀疑者(第八十条增订七~十、第八十一条增订四);library-build 幂等键改纯内容指纹;

  • 3.0.3 主分支精简版:外接三件套移出主分支(迁 packages/extended),主分支保留哨兵本体与外判契约;

  • 3.0.2 外接三件套:viking-bridge(OpenViking 积木同步)/ audit-chain --semantica(Semantica 图谱导出)/ needle2-sentinel(Needle 2 外判运行器)+ 批示词尾置容错;

  • 3.0.1 合并审批:多条高危待批合并出示、一次 y 放行全部(各一次性消费);批示词容错("y,顺带把文档也改了");写入闸对抗审查同源判定;

  • 3.0.0 协作治理版:按 3.0 规划(十大原则)将治理面从单会话扩展到多代理协作与知识资产——中心调度与蜂群委派法典(第八十条)、去中心化验证(八十一)、静态积木图书馆 .ai/library/(八十二)、本地零成本哨兵 tools/sentinel.mjs(八十三,Needle 2 可插拔)、KPI 兑现闭环(八十四,收尾结算等次→委托池奖惩)、提问漏斗(八十五)、因果链留痕 seq/chain/ref + tools/audit-chain.mjs(八十六);新增 tools/library-build.mjs 积木构建器;修复 deep-review 遗留:FG-D1 引文核验窗口 500→4000 字符、FG-D2 原子写、FG-D3 tmp 残片、FG-D4 降级防御、解释器 eval 不再判只读侦查;法典增第十五章之二(第八十~八十六条);

  • 2.5.3 实测误伤修复版:卷宗继承指纹只提示不拦(跨会话首读不再被拦);58 条对账限单条语句(复合命令误报清零);审计任务体积闸豁免;卷宗【一】/PATTERNS.md 写失败告警;61 条落地(启动清扫 30 天未动临时文件);法典 v1.1 修法(SKILL 效力条款改为"暂停机械执行+报请裁决"、废止 19/24四/44/45/46 条、47 条限定同机跨运行时);仓库迁移 irisblackwood;验收 86 → 90;

  • 2.5.2 对抗审查版:修 P0——熔断期白名单先 exit 0,导致 npm publish/shutil.rmtree/reg add 等不在变更表里的高危命令在熔断期绕过审批;修中文批示(同意/批准/不/拒绝 因正则 \b 不认 CJK 全部失效)、止停令被写回 false、超 300 字符命令 y/n 永不匹配、Stop 部分打回缺一次性保护、sudo mv/xargs mv/cp/sed -i 被当只读侦查、bash↔zsh 切换永不重检;.env/私钥不再落明文备份、状态原子落盘;补 CI 与 CHANGELOG,验收 63 → 86;

  • 2.5.1 盘点修复版:五处清单 + 引擎号 + 头注释全链一致并由用例锁定;假留痕防线(AUDIT/卷宗/备份写失败一律上 stderr);卷宗【一】环境声明落卷;58 条路径查重判定修正;五处插件说明去重;

文档索引

文件给谁看
README.md人类:这是什么、怎么装、边界在哪(本文件)
INSTALL.md逐行安装(ZCode / DSH 两条路)/ FAQ / 卸载
docs/HANDOFF-TO-EXTERNAL.md外部接手模型:现状依据、任务书、纪律陷阱、环境事实
packages/core/docs/RULES.md法条原文 + 技术映射明细 + 未机械化条款清单(永不自动加载)
packages/core/skills/focus-thinking/SKILL.mdAI 运行时镜像:聚焦方法 + 纪律条款
packages/core/docs/MASTER-PLAN-2.0.0.md卷宗体系工程总纲
packages/core/docs/MASTER-PLAN-3.0.0.md协作治理工程总纲(十大原则 → 十项机制)+ 分层总规范
packages/core/docs/LEGISLATION-LAW.md立法法:规则怎么立、怎么改、怎么备案
packages/core/docs/deepseek-pricing-audit.md峰谷价目核对(成本台账口径来源)
packages/core/tools/积木图书馆构建 / 因果链渲染 / 本地哨兵 / 环境指纹
packages/extended/bridges/README.md外接三件套的契约与衍生纪律
CHANGELOG.md版本变更
packages/core/tests/验收用例、对抗评测、报文基准

License

MIT © 2026 irisblackwood

관련 플러그인