@yottameta/yotta-guardian 0.1.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +15 -0
- package/LICENSE +21 -0
- package/NOTICE +11 -0
- package/README.md +154 -0
- package/SKILL.md +77 -0
- package/assets/banner.png +0 -0
- package/bin/install.js +163 -0
- package/install.sh +132 -0
- package/package.json +32 -0
- package/references/intent-verifier.md +76 -0
- package/references/policies.md +96 -0
- package/references/rules.md +118 -0
- package/scripts/__pycache__/guardian_rules.cpython-38.pyc +0 -0
- package/scripts/__pycache__/test_yotta_guardian.cpython-38.pyc +0 -0
- package/scripts/__pycache__/yotta_guardian.cpython-38.pyc +0 -0
- package/scripts/guardian_rules.py +175 -0
- package/scripts/test_yotta_guardian.py +454 -0
- package/scripts/yotta_guardian.py +1115 -0
package/CHANGELOG.md
ADDED
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
# 更新日志
|
|
2
|
+
|
|
3
|
+
## v0.1.0 (2026-08-26)
|
|
4
|
+
|
|
5
|
+
YottaMeta 自有实现首版(护栏/拦截方向参考开源社区 safe-guardian 类技能思路,已完全重写,零依赖、无上游代码):
|
|
6
|
+
|
|
7
|
+
- **零依赖自研引擎**(scripts/yotta_guardian.py,Python 3.8+ 标准库):确定性规则引擎 + 可插拔意图验证,对 exec / write / edit / read / run / shell 工具调用做安全评估。
|
|
8
|
+
- **四层规则**:文本模式(下载即执行 / 编码执行 / 反向 shell / 系统文件追加)+ argv 级动词/目标分析(rm / dd / mkfs / chmod / chown / 提权 / 防火墙 / 服务 / 持久化 / 反向 shell)+ 敏感路径(/etc 核心文件、/boot、/dev、SSH 授权、Windows 系统目录与 hosts、注册表启动项等)+ 写入内容(私钥 / 密钥令牌)。
|
|
9
|
+
- **三档策略**:default(拒绝 high+)/ strict(拒绝 medium+)/ loose(仅拒绝 critical);放行规则(--allow / --allow-path)可降级 high,critical 不可覆盖。
|
|
10
|
+
- **可插拔意图验证(不绑模型)**:默认零依赖;--heuristic 内置本地启发式;--verifier / 配置文件外接任意验证器(stdin/stdout JSON 协议)。
|
|
11
|
+
- **审计**:JSONL 审计日志 + audit 子命令(--tail / --denied / --since / --tool / --json)。
|
|
12
|
+
- **输出**:文本 / JSON(stdout 纯净)/ Markdown 报告;--batch 批量预检。
|
|
13
|
+
- **测试**:scripts/test_yotta_guardian.py 60 项全绿(命令/路径/内容/策略/放行/批量/JSON/报告/审计/验证器/配置/GBK 控制台)。
|
|
14
|
+
- **文档**:SKILL.md / README.md / references(rules / policies / intent-verifier)/ assets/banner.png。
|
|
15
|
+
- 版权:YottaMeta 纯自有 MIT + NOTICE 品牌声明;README 一行上游致谢。
|
package/LICENSE
ADDED
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
MIT License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2026 YottaMeta
|
|
4
|
+
|
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
6
|
+
of this software and associated documentation files (the "Software"), to deal
|
|
7
|
+
in the Software without restriction, including without limitation the rights
|
|
8
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
9
|
+
copies of the Software, and to permit persons to whom the Software is
|
|
10
|
+
furnished to do so, subject to the following conditions:
|
|
11
|
+
|
|
12
|
+
The above copyright notice and this permission notice shall be included in all
|
|
13
|
+
copies or substantial portions of the Software.
|
|
14
|
+
|
|
15
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
16
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
17
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
18
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
19
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
20
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
21
|
+
SOFTWARE.
|
package/NOTICE
ADDED
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
# NOTICE — YottaMeta 品牌声明
|
|
2
|
+
|
|
3
|
+
「YottaMeta」「元忆」「yotta-memory」「元盾」「yotta-guardian」「元阁」以及本家族各技能名称(yotta-* 前缀)是 YottaMeta 的品牌与标识。
|
|
4
|
+
|
|
5
|
+
本软件以 MIT 许可证开源,任何人均可自由使用、修改与分发。若你在其基础上制作派生作品:
|
|
6
|
+
|
|
7
|
+
1. 不得继续使用 YottaMeta 或本家族名称(yotta-*、元忆、元盾 等)作为派生作品的名称;
|
|
8
|
+
2. 不得暗示派生作品由 YottaMeta 官方维护、认可或与之存在关联;
|
|
9
|
+
3. 建议在派生作品中明确声明「与 YottaMeta 官方无关联」。
|
|
10
|
+
|
|
11
|
+
上游来源致谢:本技能由 YottaMeta 全新实现,护栏/拦截方向参考开源社区的 safe-guardian 类技能思路,无上游代码。
|
package/README.md
ADDED
|
@@ -0,0 +1,154 @@
|
|
|
1
|
+
|
|
2
|
+
<p align="center">
|
|
3
|
+
<img src="assets/banner.png" alt="yotta-guardian banner" width="100%" />
|
|
4
|
+
</p>
|
|
5
|
+
|
|
6
|
+
<h1 align="center">yotta-guardian · 元盾</h1>
|
|
7
|
+
|
|
8
|
+
<p align="center">YottaMeta 自有的工具调用拦截护栏:<b>确定性规则引擎 + 可插拔意图验证</b>,对 exec / write / edit / read / run / shell 工具调用做安全评估,输出 allow / deny + 命中规则 + 审计日志。适用于代理要执行高风险命令、写入系统敏感路径、或修改系统配置之前的确定性安全检查。</p>
|
|
9
|
+
<p align="center">检测到递归删除、磁盘格式化、提权、防火墙改动、反向 shell、下载即执行、写入系统核心文件等危险操作意图时自动激活——<b>不靠提示词兜底,按规则确定性判定</b>。</p>
|
|
10
|
+
<p align="center">纯 Python 3.8+ 标准库实现,零外部依赖;Windows + Linux + macOS 通用;默认只读评估、可配置放行、审计留痕。</p>
|
|
11
|
+
|
|
12
|
+
<p align="center">
|
|
13
|
+
<a href="LICENSE"><img alt="License: MIT" src="https://img.shields.io/badge/license-MIT-blue" /></a>
|
|
14
|
+
<a href="https://agentskills.io/"><img alt="Standard: agentskills.io" src="https://img.shields.io/badge/standard-agentskills.io-orange" /></a>
|
|
15
|
+
<a href="https://www.npmjs.com/package/@yottameta/yotta-guardian"><img alt="npm package" src="https://img.shields.io/npm/v/@yottameta/yotta-guardian" /></a>
|
|
16
|
+
<a href="https://github.com/YottaMeta/yotta-guardian"><img alt="GitHub stars" src="https://img.shields.io/github/stars/YottaMeta/yotta-guardian" /></a>
|
|
17
|
+
<a href="https://github.com/YottaMeta/yotta-guardian/commits/main"><img alt="last commit" src="https://img.shields.io/github/last-commit/YottaMeta/yotta-guardian" /></a>
|
|
18
|
+
<a href="https://github.com/YottaMeta/yotta-guardian"><img alt="PRs welcome" src="https://img.shields.io/badge/PRs-welcome-brightgreen" /></a>
|
|
19
|
+
</p>
|
|
20
|
+
|
|
21
|
+
## 这是什么
|
|
22
|
+
|
|
23
|
+
AI 代理在自主执行时,一条递归删除、一次磁盘写入、一段下载即执行,就可能造成不可逆损失。元盾把这些危险动作做成确定性规则引擎:对每一次工具调用(exec / write / edit / read / run / shell)做结构化评估——命令文本、argv 级动词与目标分析、敏感路径、写入内容——给出 allow / deny 判定、命中规则与原因,并支持审计日志留痕。
|
|
24
|
+
|
|
25
|
+
它不是某个平台的专属功能,而是一份与智能体无关的工具包:装进任何支持 Agent Skills 的智能体即可按需调用。默认只读评估,不自动执行也不放行危险操作;意图验证默认不调用任何模型,可通过协议外接任意验证器(如 LLM 网关)。
|
|
26
|
+
|
|
27
|
+
## 核心价值
|
|
28
|
+
|
|
29
|
+
- **确定性规则引擎**:文本模式(下载即执行 / 编码执行 / 反向 shell 等)+ argv 级动词/目标分析(rm / dd / mkfs / chmod / chown / 提权 / 防火墙 / 服务 / 持久化等)+ 敏感路径 + 写入内容,四层规则叠加判定。
|
|
30
|
+
- **敏感路径守卫**:/etc/passwd、/etc/sudoers、SSH 授权文件、/boot、/dev 设备、Windows 系统目录与 hosts、注册表启动项等写入即拒。
|
|
31
|
+
- **可插拔意图验证(不绑模型)**:默认零依赖;可启用内置本地启发式(--heuristic),也可通过 stdin/stdout JSON 协议外接任意意图验证器(--verifier / 配置文件)。
|
|
32
|
+
- **三档策略**:default(拒绝 high+)/ strict(拒绝 medium+)/ loose(仅拒绝 critical),按场景取舍。
|
|
33
|
+
- **审计留痕**:JSONL 审计日志 + audit 查询子命令,拒绝/放行全程可追溯。
|
|
34
|
+
- **机器可读**:--json 输出纯净 JSON(含逐条判定、规则、退出码),--batch 批量预检,适合智能体在执行前 gate。
|
|
35
|
+
|
|
36
|
+
## 核心优势
|
|
37
|
+
|
|
38
|
+
| 优势 | 说明 |
|
|
39
|
+
|---|---|
|
|
40
|
+
| **零依赖** | Python 3.8+ 标准库,无 daemon / 无数据库 / 无外部扫描器;Windows + Linux + macOS 通用 |
|
|
41
|
+
| **确定性** | 规则判定可复现、可解释,不依赖模型概率;意图验证默认关闭,需显式启用 |
|
|
42
|
+
| **结构化** | 按工具类型(exec / write / edit / read)分别评估命令、路径与内容,不是简单字符串匹配 |
|
|
43
|
+
| **可配置** | --allow / --allow-path / 自定义规则 JSON(policy / deny / allow / verifier) |
|
|
44
|
+
| **可追溯** | 每次判定落 JSONL 审计日志,audit 子命令可按拒绝 / 工具 / 时间过滤 |
|
|
45
|
+
| **生态分发** | GitHub + npm + ClawHub 三源同步发布;npx / install.sh / 手动复制三种安装方式 |
|
|
46
|
+
|
|
47
|
+
## 功能体系
|
|
48
|
+
|
|
49
|
+
| 能力 | 说明 |
|
|
50
|
+
|---|---|
|
|
51
|
+
| check | 评估一条或一批工具调用(--batch),文本 / JSON / Markdown 报告三种输出 |
|
|
52
|
+
| audit | 查询审计日志(--tail / --denied / --since / --tool / --json) |
|
|
53
|
+
| rules | 打印内置规则摘要 / 校验自定义规则文件 |
|
|
54
|
+
| version | 打印版本 |
|
|
55
|
+
|
|
56
|
+
## 快速使用
|
|
57
|
+
|
|
58
|
+
Windows 用 python,Linux/macOS 用 python3。
|
|
59
|
+
|
|
60
|
+
`_BT_`bash
|
|
61
|
+
# 检查一条 exec(0 = 允许)
|
|
62
|
+
python3 scripts/yotta_guardian.py check exec --cmd "git status"
|
|
63
|
+
|
|
64
|
+
# 检查危险命令(默认拒绝,退出码 3)
|
|
65
|
+
python3 scripts/yotta_guardian.py check exec --cmd "rm -rf /"
|
|
66
|
+
|
|
67
|
+
# 检查写操作(写入 /etc/passwd 被拒)
|
|
68
|
+
python3 scripts/yotta_guardian.py check write --path /etc/passwd --content "..."
|
|
69
|
+
|
|
70
|
+
# 批量预检(agent 在执行前把待执行调用列表交给护栏)
|
|
71
|
+
python3 scripts/yotta_guardian.py check --batch calls.json --json
|
|
72
|
+
|
|
73
|
+
# 审计
|
|
74
|
+
python3 scripts/yotta_guardian.py check exec --cmd "..." --audit-log .yotta-guardian/audit.jsonl
|
|
75
|
+
python3 scripts/yotta_guardian.py audit --file .yotta-guardian/audit.jsonl --tail 20
|
|
76
|
+
`_BT_`
|
|
77
|
+
|
|
78
|
+
退出码语义(与元安 / 元审家族一致):0 = 允许;1 = 允许但带警告(建议人工复核);2 = 拒绝(high);3 = 拒绝(critical);4 = 用法错误 / 致命异常。
|
|
79
|
+
|
|
80
|
+
## 安装
|
|
81
|
+
|
|
82
|
+
三种方式任选其一,技能文件统一从 **npm** 获取(GitHub 无代理时较慢,npm 可配国内镜像加速)。
|
|
83
|
+
|
|
84
|
+
### 方式一:npm(推荐,一行安装)
|
|
85
|
+
`_BT_`bash
|
|
86
|
+
# 国内加速(可选):npm config set registry https://registry.npmmirror.com
|
|
87
|
+
npx -y @yottameta/yotta-guardian -g
|
|
88
|
+
npx -y @yottameta/yotta-guardian --dir <你的技能目录> # 任意智能体:指定目录安装
|
|
89
|
+
`_BT_`
|
|
90
|
+
> 智能体不在预置列表里?用 --dir 指定它的 skills 目录,或手动复制(方式三)。--list 可查看各智能体对应的默认目录。想手动拿文件也可 npm pack @yottameta/yotta-guardian 解包后按方式二/三安装。
|
|
91
|
+
|
|
92
|
+
### 方式二:install.sh 一键安装
|
|
93
|
+
获取技能文件夹后(npm pack 解包或 git clone),进入技能文件夹:
|
|
94
|
+
`_BT_`bash
|
|
95
|
+
bash install.sh -g # 用户级;bash install.sh --list 查看全部目录
|
|
96
|
+
bash install.sh --agent codex # 指定智能体(--list 可查看可用项)
|
|
97
|
+
bash install.sh # 项目级:自动检测已存在的 .claude/.cursor/.codex 等 skills 目录
|
|
98
|
+
bash install.sh --dir /path/to/skills
|
|
99
|
+
`_BT_`
|
|
100
|
+
> 覆盖 17 类智能体,含国内 Trae / Qwen / Comate / CodeBuddy / Kimi。Windows 用户:装有 Git Bash 即可用;否则用方式三手动复制。
|
|
101
|
+
|
|
102
|
+
### 方式三:手动复制
|
|
103
|
+
把整个 yotta-guardian 文件夹复制到目标智能体的 skills 目录。常见位置(用户级;Windows 用 %USERPROFILE%,Linux/macOS 用 ~):
|
|
104
|
+
|
|
105
|
+
| 智能体 | 用户级目录 | 项目级目录 |
|
|
106
|
+
|---|---|---|
|
|
107
|
+
| Codex | %USERPROFILE%\.codex\skills\yotta-guardian\ | .codex\skills\ |
|
|
108
|
+
| Claude Code | %USERPROFILE%\.claude\skills\yotta-guardian\ | .claude\skills\ |
|
|
109
|
+
| Cursor | %USERPROFILE%\.cursor\skills\yotta-guardian\ | .cursor\skills\ |
|
|
110
|
+
| Windsurf | %USERPROFILE%\.codeium\windsurf\skills\yotta-guardian\ | .windsurf\skills\ |
|
|
111
|
+
| opencode | %USERPROFILE%\.config\opencode\skills\yotta-guardian\ | .opencode\skills\ |
|
|
112
|
+
| Gemini | %USERPROFILE%\.gemini\skills\yotta-guardian\ | .gemini\skills\ |
|
|
113
|
+
| Goose | %USERPROFILE%\.config\goose\skills\yotta-guardian\ | .goose\skills\ |
|
|
114
|
+
| Amp | %USERPROFILE%\.config\agents\skills\yotta-guardian\ | .agents\skills\ |
|
|
115
|
+
| Kiro | %USERPROFILE%\.kiro\skills\yotta-guardian\ | .kiro\skills\ |
|
|
116
|
+
| WorkBuddy | %USERPROFILE%\.workbuddy\skills\yotta-guardian\ | .workbuddy\skills\ |
|
|
117
|
+
| Trae Code CLI | %USERPROFILE%\.traecli\skills\yotta-guardian\ | .traecli\skills\ |
|
|
118
|
+
| Trae IDE(国内) | %USERPROFILE%\.trae-cn\skills\yotta-guardian\ | .trae\skills\ |
|
|
119
|
+
| Qwen Code | %USERPROFILE%\.qwen\skills\yotta-guardian\ | .qwen\skills\ |
|
|
120
|
+
| Comate | %USERPROFILE%\.comate\skills\yotta-guardian\ | .comate\skills\ |
|
|
121
|
+
| CodeBuddy | %USERPROFILE%\.codebuddy\skills\yotta-guardian\ | .codebuddy\skills\ |
|
|
122
|
+
| Kimi | %USERPROFILE%\.kimi\skills\yotta-guardian\ | .kimi\skills\ |
|
|
123
|
+
| 通用 AGENTS.md | %USERPROFILE%\.agents\skills\yotta-guardian\ | .agents\skills\ |
|
|
124
|
+
|
|
125
|
+
> Codex 默认目录若设置了环境变量 CODEX_HOME,以该变量为准;opencode 若设置 XDG_CONFIG_HOME 同理。.agents\skills 并非通用目录,仅 OpenCode / Cursor / Cline / Amp / Kimi / Gemini CLI / GitHub Copilot 等会读取,Claude Code 与 Codex 默认不读。不确定时用 --dir 指定,或让该智能体自行安装。
|
|
126
|
+
|
|
127
|
+
## 使用示例(AI 智能体)
|
|
128
|
+
|
|
129
|
+
1. 将本仓库的 SKILL.md 接入任意 AI 智能体的技能/规则系统(见上方安装)。
|
|
130
|
+
2. 在执行任何高风险工具调用前,先跑一次 check:
|
|
131
|
+
`_BT_`bash
|
|
132
|
+
python3 scripts/yotta_guardian.py check exec --cmd "<待执行命令>" --json
|
|
133
|
+
`_BT_`
|
|
134
|
+
退出码 2 / 3 时不要执行,向用户说明命中规则;确有授权再用 --allow / --allow-path / 自定义规则放行。
|
|
135
|
+
3. 一次要执行多条时,用 --batch 批量预检:
|
|
136
|
+
`_BT_`bash
|
|
137
|
+
python3 scripts/yotta_guardian.py check --batch calls.json --json
|
|
138
|
+
`_BT_`
|
|
139
|
+
4. 写敏感路径 / 修改系统配置前,用 write / edit 检查目标路径与内容。
|
|
140
|
+
5. 高风险操作落审计日志,事后用 audit 查询。
|
|
141
|
+
|
|
142
|
+
## 开发与校验
|
|
143
|
+
|
|
144
|
+
- 测试:python scripts/test_yotta_guardian.py(60 项)
|
|
145
|
+
- 基础校验:python tools/validate-skill.py yotta-guardian(在仓库根目录运行)
|
|
146
|
+
- 规则说明:references/rules.md;策略与退出码:references/policies.md;意图验证器协议:references/intent-verifier.md
|
|
147
|
+
|
|
148
|
+
## 许可证
|
|
149
|
+
|
|
150
|
+
MIT © YottaMeta —— 详见 [LICENSE](./LICENSE)。
|
|
151
|
+
|
|
152
|
+
## 致谢
|
|
153
|
+
|
|
154
|
+
护栏/拦截方向参考开源社区 safe-guardian 类技能思路,实现为 YottaMeta 全新自有代码(详见 [NOTICE](./NOTICE))。
|
package/SKILL.md
ADDED
|
@@ -0,0 +1,77 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: yotta-guardian
|
|
3
|
+
version: 0.1.0
|
|
4
|
+
description: 元盾 —— 跨智能体的危险调用拦截护栏:确定性规则引擎 + 可插拔意图验证(不绑模型),拦截危险 exec / write / edit / read / run / shell 工具调用,提供审计日志。触发:代理要执行高风险命令(递归删除、磁盘格式化、提权、防火墙改动、反向 shell、下载即执行等)、要写入系统敏感路径或修改系统配置、要在执行危险操作前做安全检查、或用户说 护栏/拦截/危险操作/安全检查 等。边界:默认只读评估,不自动执行也不放行危险操作;不替代用户决策;不隐藏审计记录;规则可配置。
|
|
5
|
+
license: MIT
|
|
6
|
+
---
|
|
7
|
+
|
|
8
|
+
# 元盾(yotta-guardian)
|
|
9
|
+
|
|
10
|
+
跨智能体的工具调用拦截护栏:**确定性规则引擎 + 可插拔意图验证**,对 exec / write / edit / read / run / shell 工具调用做安全评估,输出 allow / deny + 命中规则 + 审计日志。
|
|
11
|
+
|
|
12
|
+
零依赖(Python 3.8+ 标准库),Windows + Linux + macOS 通用;Claude Code / Cursor / Codex / 通用 Agent 均可调用。
|
|
13
|
+
|
|
14
|
+
## 何时使用
|
|
15
|
+
|
|
16
|
+
- 代理要执行高风险命令:递归删除系统路径、磁盘格式化(mkfs / fdisk / dd 写设备)、提权(chmod 全权限 / chown 系统路径 / 账户管理)、防火墙改动(iptables 清空 / ufw disable / netsh 关闭)、反向 shell(netcat 执行 / bash /dev/tcp)、下载即执行(curl / wget 管道交给 shell)等;
|
|
17
|
+
- 代理要写入系统敏感路径(/etc/passwd、/etc/sudoers、SSH 授权文件、Windows hosts / 系统目录、注册表启动项)或修改系统配置;
|
|
18
|
+
- 需要在执行危险操作前做一次确定性安全检查(gate),并留下审计记录。
|
|
19
|
+
|
|
20
|
+
**Do NOT trigger**:
|
|
21
|
+
|
|
22
|
+
- 默认只读评估,不自动执行、不放行危险操作,也不替代用户最终决策;
|
|
23
|
+
- 不隐藏审计记录;被拦截时如实上报原因与命中规则;
|
|
24
|
+
- 已获明确授权的运维操作应显式放行(--allow / --allow-path / 自定义规则),而不是绕过检查。
|
|
25
|
+
|
|
26
|
+
## 快速使用
|
|
27
|
+
|
|
28
|
+
Windows 用 python,Linux/macOS 用 python3。
|
|
29
|
+
|
|
30
|
+
`_BT_`bash
|
|
31
|
+
# 检查一条 exec(0 = 允许)
|
|
32
|
+
python3 scripts/yotta_guardian.py check exec --cmd "git status"
|
|
33
|
+
|
|
34
|
+
# 检查危险命令(默认拒绝,退出码 3)
|
|
35
|
+
python3 scripts/yotta_guardian.py check exec --cmd "rm -rf /"
|
|
36
|
+
|
|
37
|
+
# 检查写操作
|
|
38
|
+
python3 scripts/yotta_guardian.py check write --path /etc/passwd --content "..."
|
|
39
|
+
|
|
40
|
+
# 批量检查(agent 在执行前把待执行调用列表交给护栏)
|
|
41
|
+
python3 scripts/yotta_guardian.py check --batch calls.json --json
|
|
42
|
+
|
|
43
|
+
# 审计
|
|
44
|
+
python3 scripts/yotta_guardian.py check exec --cmd "..." --audit-log .yotta-guardian/audit.jsonl
|
|
45
|
+
python3 scripts/yotta_guardian.py audit --file .yotta-guardian/audit.jsonl --tail 20
|
|
46
|
+
`_BT_`
|
|
47
|
+
|
|
48
|
+
## 工作流程(AI 智能体执行危险操作前)
|
|
49
|
+
|
|
50
|
+
1. **先检查**:把将要执行的工具调用交给护栏 `check`(单条或 `--batch` 批量)。
|
|
51
|
+
2. **看退出码**:0 = 允许;1 = 允许但带警告(建议人工复核);2 / 3 = 拒绝(high / critical,不要执行);4 = 用法错误。
|
|
52
|
+
3. **被拒绝怎么办**:如实向用户报告原因与命中规则;确有授权的操作,用 `--allow` / `--allow-path` / 自定义规则文件放行并留审计记录;**不要绕过检查**。
|
|
53
|
+
4. **留痕**:高风险场景用 `--audit-log` 落审计日志,供追溯。
|
|
54
|
+
|
|
55
|
+
## 策略(policy)
|
|
56
|
+
|
|
57
|
+
| 策略 | 行为 |
|
|
58
|
+
|---|---|
|
|
59
|
+
| default(默认) | 拒绝 critical / high;中危警告(exit 1) |
|
|
60
|
+
| strict | 拒绝 medium 及以上;低危也提示 |
|
|
61
|
+
| loose | 仅拒绝 critical;高危仅警告 |
|
|
62
|
+
|
|
63
|
+
## 可插拔意图验证(不绑模型)
|
|
64
|
+
|
|
65
|
+
- 默认纯确定性规则,不调用任何模型、零外部依赖;
|
|
66
|
+
- `--heuristic`:启用内置本地启发式验证(对高影响动词升级为需人工确认);
|
|
67
|
+
- `--verifier "命令"` 或配置文件:外接任意意图验证器(如 LLM 网关),协议见 references/intent-verifier.md。
|
|
68
|
+
|
|
69
|
+
## 参考文档
|
|
70
|
+
|
|
71
|
+
- references/rules.md — 规则目录与匹配说明
|
|
72
|
+
- references/policies.md — 策略 / 退出码 / 使用姿势
|
|
73
|
+
- references/intent-verifier.md — 意图验证器协议
|
|
74
|
+
|
|
75
|
+
## 责任声明
|
|
76
|
+
|
|
77
|
+
本技能用于防止误操作与提升操作透明度,不替代人工决策。执行危险操作前请自行确认授权与合规。
|
|
Binary file
|
package/bin/install.js
ADDED
|
@@ -0,0 +1,163 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
/**
|
|
3
|
+
* yotta-guardian 跨平台安装器(YottaSkills)
|
|
4
|
+
* 用法:
|
|
5
|
+
* npx -y @yottameta/yotta-guardian --agent <name> # 按智能体默认用户级目录安装(推荐)
|
|
6
|
+
* npx -y @yottameta/yotta-guardian --dir PATH # 装到指定目录(用户改了目录的智能体)
|
|
7
|
+
* npx -y @yottameta/yotta-guardian -g # 安装到全部已知智能体用户级目录
|
|
8
|
+
* npx -y @yottameta/yotta-guardian # 安装到检测到的项目级目录
|
|
9
|
+
* npx -y @yottameta/yotta-guardian --list # 列出智能体 -> 默认目录
|
|
10
|
+
*/
|
|
11
|
+
'use strict';
|
|
12
|
+
const fs = require('fs');
|
|
13
|
+
const path = require('path');
|
|
14
|
+
const os = require('os');
|
|
15
|
+
|
|
16
|
+
const SKILL_NAME = 'yotta-guardian';
|
|
17
|
+
const PKG_ROOT = path.join(__dirname, '..');
|
|
18
|
+
|
|
19
|
+
// 智能体 -> 用户级默认技能目录(dirs 按优先级排列;--agent 装到第一个)
|
|
20
|
+
// 依据官方文档:.agents/skills 并非通用目录,被 OpenCode / Cursor / Cline / Amp /
|
|
21
|
+
// Kimi / Gemini CLI / GitHub Copilot 等读取;Claude Code 与 Codex 默认不读 .agents。
|
|
22
|
+
const AGENT_DIRS = {
|
|
23
|
+
claude: { label: 'Claude Code', dirs: ['.claude/skills'] },
|
|
24
|
+
cursor: { label: 'Cursor', dirs: ['.cursor/skills', '.agents/skills'] },
|
|
25
|
+
codex: { label: 'Codex', dirs: ['.codex/skills'] }, // 特判:$CODEX_HOME/skills
|
|
26
|
+
gemini: { label: 'Gemini CLI', dirs: ['.gemini/skills', '.agents/skills'] },
|
|
27
|
+
goose: { label: 'Goose', dirs: ['.config/goose/skills', '.agents/skills'] },
|
|
28
|
+
amp: { label: 'Amp', dirs: ['.config/agents/skills', '.agents/skills'] },
|
|
29
|
+
opencode: { label: 'OpenCode', dirs: ['.config/opencode/skills'] }, // 特判:$XDG_CONFIG_HOME
|
|
30
|
+
windsurf: { label: 'Windsurf', dirs: ['.codeium/windsurf/skills'] },
|
|
31
|
+
workbuddy: { label: 'WorkBuddy', dirs: ['.workbuddy/skills'] },
|
|
32
|
+
kiro: { label: 'Kiro', dirs: ['.kiro/skills'] },
|
|
33
|
+
trae: { label: 'Trae Code CLI', dirs: ['.traecli/skills'] },
|
|
34
|
+
'trae-cn': { label: 'Trae IDE(国内)', dirs: ['.trae-cn/skills'] },
|
|
35
|
+
qwen: { label: 'Qwen Code', dirs: ['.qwen/skills'] },
|
|
36
|
+
comate: { label: 'Comate 文心快码', dirs: ['.comate/skills'] },
|
|
37
|
+
codebuddy: { label: 'CodeBuddy Code', dirs: ['.codebuddy/skills'] },
|
|
38
|
+
kimi: { label: 'Kimi Code CLI', dirs: ['.kimi/skills'] },
|
|
39
|
+
agents: { label: '通用 AGENTS.md', dirs: ['.agents/skills'] },
|
|
40
|
+
};
|
|
41
|
+
|
|
42
|
+
// Codex 用户级目录特判:优先 $CODEX_HOME/skills,否则 ~/.codex/skills
|
|
43
|
+
function codexUserDir() {
|
|
44
|
+
const base = process.env.CODEX_HOME || path.join(os.homedir(), '.codex');
|
|
45
|
+
return path.join(base, 'skills');
|
|
46
|
+
}
|
|
47
|
+
|
|
48
|
+
// OpenCode 用户级目录特判:优先 $XDG_CONFIG_HOME/opencode/skills,否则 ~/.config/opencode/skills
|
|
49
|
+
function opencodeUserDir() {
|
|
50
|
+
const base = process.env.XDG_CONFIG_HOME || path.join(os.homedir(), '.config');
|
|
51
|
+
return path.join(base, 'opencode', 'skills');
|
|
52
|
+
}
|
|
53
|
+
|
|
54
|
+
function resolveUserDir(rel) {
|
|
55
|
+
if (rel === '.codex/skills') return codexUserDir();
|
|
56
|
+
if (rel === '.config/opencode/skills') return opencodeUserDir();
|
|
57
|
+
return path.join(os.homedir(), rel);
|
|
58
|
+
}
|
|
59
|
+
|
|
60
|
+
function installTo(dest) {
|
|
61
|
+
const target = path.join(dest, SKILL_NAME);
|
|
62
|
+
fs.mkdirSync(target, { recursive: true });
|
|
63
|
+
copyDir(PKG_ROOT, target, new Set(['package.json', 'bin', 'node_modules', '.git']));
|
|
64
|
+
console.log('installed -> ' + target);
|
|
65
|
+
}
|
|
66
|
+
|
|
67
|
+
function copyDir(src, dst, skip) {
|
|
68
|
+
for (const entry of fs.readdirSync(src, { withFileTypes: true })) {
|
|
69
|
+
if (skip.has(entry.name)) continue;
|
|
70
|
+
const s = path.join(src, entry.name);
|
|
71
|
+
const d = path.join(dst, entry.name);
|
|
72
|
+
if (entry.isDirectory()) {
|
|
73
|
+
fs.mkdirSync(d, { recursive: true });
|
|
74
|
+
copyDir(s, d, skip);
|
|
75
|
+
} else if (entry.isFile()) {
|
|
76
|
+
fs.copyFileSync(s, d);
|
|
77
|
+
}
|
|
78
|
+
}
|
|
79
|
+
}
|
|
80
|
+
|
|
81
|
+
function displayDir(rel) {
|
|
82
|
+
if (process.platform === 'win32') return '%USERPROFILE%\\' + rel.replace(/\//g, '\\');
|
|
83
|
+
return '~/' + rel;
|
|
84
|
+
}
|
|
85
|
+
|
|
86
|
+
function main() {
|
|
87
|
+
const args = process.argv.slice(2);
|
|
88
|
+
const isGlobal = args.includes('-g') || args.includes('--global');
|
|
89
|
+
const list = args.includes('--list') || args.includes('-l');
|
|
90
|
+
let explicitDir = null;
|
|
91
|
+
const di = args.indexOf('--dir');
|
|
92
|
+
if (di !== -1 && args[di + 1]) explicitDir = args[di + 1];
|
|
93
|
+
let agent = null;
|
|
94
|
+
const ai = args.indexOf('--agent');
|
|
95
|
+
if (ai !== -1 && args[ai + 1]) agent = String(args[ai + 1]).toLowerCase();
|
|
96
|
+
|
|
97
|
+
if (list) {
|
|
98
|
+
console.log('智能体 -> 默认技能目录(--agent <name> 装到第一个,用户级):');
|
|
99
|
+
for (const [key, v] of Object.entries(AGENT_DIRS)) {
|
|
100
|
+
const resolved = v.dirs.map(displayDir);
|
|
101
|
+
console.log(' ' + key.padEnd(10) + v.label.padEnd(18) + resolved.join('、'));
|
|
102
|
+
}
|
|
103
|
+
console.log('\n说明:Windows 用 %USERPROFILE%,Linux/macOS 用 ~;仅收录有官方默认目录的智能体。');
|
|
104
|
+
console.log('改了目录的请用 --dir <路径>,不要依赖默认位置;若设置了 CODEX_HOME / XDG_CONFIG_HOME,安装自动以该变量为准。');
|
|
105
|
+
return;
|
|
106
|
+
}
|
|
107
|
+
|
|
108
|
+
if (explicitDir) { installTo(explicitDir); return; }
|
|
109
|
+
|
|
110
|
+
if (agent) {
|
|
111
|
+
const info = AGENT_DIRS[agent];
|
|
112
|
+
if (!info) {
|
|
113
|
+
console.log('未收录智能体: ' + agent + '。请用 --dir <路径> 指定技能目录。');
|
|
114
|
+
console.log('可用: ' + Object.keys(AGENT_DIRS).join(', '));
|
|
115
|
+
return;
|
|
116
|
+
}
|
|
117
|
+
installTo(resolveUserDir(info.dirs[0]));
|
|
118
|
+
console.log('完成。');
|
|
119
|
+
return;
|
|
120
|
+
}
|
|
121
|
+
|
|
122
|
+
if (isGlobal) {
|
|
123
|
+
const seen = new Set();
|
|
124
|
+
for (const v of Object.values(AGENT_DIRS)) {
|
|
125
|
+
for (const d of v.dirs) {
|
|
126
|
+
if (seen.has(d)) continue;
|
|
127
|
+
seen.add(d);
|
|
128
|
+
installTo(resolveUserDir(d));
|
|
129
|
+
}
|
|
130
|
+
}
|
|
131
|
+
console.log('完成。');
|
|
132
|
+
return;
|
|
133
|
+
}
|
|
134
|
+
|
|
135
|
+
const PROJECT_DIRS = [
|
|
136
|
+
'.claude/skills',
|
|
137
|
+
'.cursor/skills',
|
|
138
|
+
'.codex/skills',
|
|
139
|
+
'.config/goose/skills',
|
|
140
|
+
'.config/agents/skills',
|
|
141
|
+
'.opencode/skills',
|
|
142
|
+
'.codeium/windsurf/skills',
|
|
143
|
+
'.workbuddy/skills',
|
|
144
|
+
'.kiro/skills',
|
|
145
|
+
'.traecli/skills',
|
|
146
|
+
'.gemini/skills',
|
|
147
|
+
'.trae-cn/skills',
|
|
148
|
+
'.qwen/skills',
|
|
149
|
+
'.comate/skills',
|
|
150
|
+
'.codebuddy/skills',
|
|
151
|
+
'.kimi/skills',
|
|
152
|
+
'.agents/skills',
|
|
153
|
+
];
|
|
154
|
+
let installedAny = false;
|
|
155
|
+
for (const d of PROJECT_DIRS) {
|
|
156
|
+
if (fs.existsSync(d)) { installTo(d); installedAny = true; }
|
|
157
|
+
}
|
|
158
|
+
if (!installedAny) {
|
|
159
|
+
console.log('未检测到项目级智能体目录。可手动复制,或用 --agent <name> / -g 装到用户级。');
|
|
160
|
+
}
|
|
161
|
+
}
|
|
162
|
+
|
|
163
|
+
main();
|
package/install.sh
ADDED
|
@@ -0,0 +1,132 @@
|
|
|
1
|
+
#!/usr/bin/env bash
|
|
2
|
+
# yotta-guardian 多智能体安装脚本(YottaSkills 模板)
|
|
3
|
+
# 用法:
|
|
4
|
+
# bash install.sh --agent <name> # 按智能体默认用户级目录安装
|
|
5
|
+
# bash install.sh --dir <path> # 装到指定目录(用户改过目录的智能体)
|
|
6
|
+
# bash install.sh -g # 装到全部已知智能体用户级目录
|
|
7
|
+
# bash install.sh # 检测并安装到已存在的项目级目录
|
|
8
|
+
# bash install.sh --list # 列出智能体 -> 默认目录
|
|
9
|
+
set -euo pipefail
|
|
10
|
+
|
|
11
|
+
SKILL_NAME="yotta-guardian"
|
|
12
|
+
SOURCE_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
|
|
13
|
+
case "$(uname -s)" in
|
|
14
|
+
MINGW*|MSYS*)
|
|
15
|
+
SOURCE_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd -W)"
|
|
16
|
+
;;
|
|
17
|
+
esac
|
|
18
|
+
|
|
19
|
+
# 智能体 -> 用户级默认目录(--agent 装到第一个)
|
|
20
|
+
# .agents/skills 并非通用目录:OpenCode / Cursor / Cline / Amp / Kimi / Gemini CLI / GitHub Copilot 读取。
|
|
21
|
+
# 判断当前环境:Windows Git Bash 用 %USERPROFILE%,Unix 用 ~
|
|
22
|
+
_IS_WINDOWS=0
|
|
23
|
+
case "$(uname -s)" in
|
|
24
|
+
MINGW*|MSYS*|CYGWIN*) _IS_WINDOWS=1 ;;
|
|
25
|
+
esac
|
|
26
|
+
dirs_for() {
|
|
27
|
+
case "$1" in
|
|
28
|
+
claude) echo ".claude/skills" ;;
|
|
29
|
+
cursor) echo ".cursor/skills .agents/skills" ;;
|
|
30
|
+
codex) echo "__CODEX__" ;;
|
|
31
|
+
gemini) echo ".gemini/skills .agents/skills" ;;
|
|
32
|
+
goose) echo ".config/goose/skills .agents/skills" ;;
|
|
33
|
+
amp) echo ".config/agents/skills .agents/skills" ;;
|
|
34
|
+
opencode) echo "__OPENCODE__" ;;
|
|
35
|
+
windsurf) echo ".codeium/windsurf/skills" ;;
|
|
36
|
+
workbuddy) echo ".workbuddy/skills" ;;
|
|
37
|
+
kiro) echo ".kiro/skills" ;;
|
|
38
|
+
trae) echo ".traecli/skills" ;;
|
|
39
|
+
trae-cn) echo ".trae-cn/skills" ;;
|
|
40
|
+
qwen) echo ".qwen/skills" ;;
|
|
41
|
+
comate) echo ".comate/skills" ;;
|
|
42
|
+
codebuddy) echo ".codebuddy/skills" ;;
|
|
43
|
+
kimi) echo ".kimi/skills" ;;
|
|
44
|
+
agents) echo ".agents/skills" ;;
|
|
45
|
+
*) return 1 ;;
|
|
46
|
+
esac
|
|
47
|
+
}
|
|
48
|
+
|
|
49
|
+
codex_dir() {
|
|
50
|
+
if [ -n "${CODEX_HOME:-}" ]; then printf '%s' "$CODEX_HOME/skills"; else printf '%s' "$HOME/.codex/skills"; fi
|
|
51
|
+
}
|
|
52
|
+
opencode_dir() {
|
|
53
|
+
if [ -n "${XDG_CONFIG_HOME:-}" ]; then printf '%s' "$XDG_CONFIG_HOME/opencode/skills"; else printf '%s' "$HOME/.config/opencode/skills"; fi
|
|
54
|
+
}
|
|
55
|
+
resolve_user() {
|
|
56
|
+
case "$1" in
|
|
57
|
+
__CODEX__) codex_dir ;;
|
|
58
|
+
__OPENCODE__) opencode_dir ;;
|
|
59
|
+
*) printf '%s' "$HOME/$1" ;;
|
|
60
|
+
esac
|
|
61
|
+
}
|
|
62
|
+
|
|
63
|
+
install_to() {
|
|
64
|
+
mkdir -p "$1/$SKILL_NAME"
|
|
65
|
+
cp -r "$SOURCE_DIR/." "$1/$SKILL_NAME/"
|
|
66
|
+
rm -rf "$1/$SKILL_NAME/.git"
|
|
67
|
+
echo "installed -> $1/$SKILL_NAME"
|
|
68
|
+
}
|
|
69
|
+
|
|
70
|
+
list() {
|
|
71
|
+
echo "智能体 -> 默认技能目录(--agent <name> 装到第一个,用户级):"
|
|
72
|
+
for a in claude cursor codex gemini goose amp opencode windsurf workbuddy kiro trae trae-cn qwen comate codebuddy kimi agents; do
|
|
73
|
+
local dirs first
|
|
74
|
+
dirs="$(dirs_for "$a")"
|
|
75
|
+
first="${dirs%% *}"
|
|
76
|
+
case "$first" in
|
|
77
|
+
__CODEX__) first=".codex/skills" ;;
|
|
78
|
+
__OPENCODE__) first=".config/opencode/skills" ;;
|
|
79
|
+
esac
|
|
80
|
+
if [ "$_IS_WINDOWS" = "1" ]; then
|
|
81
|
+
first="%USERPROFILE%\\${first//\//\\}"
|
|
82
|
+
else
|
|
83
|
+
first="~/$first"
|
|
84
|
+
fi
|
|
85
|
+
printf ' %-10s %s\n' "$a" "$first"
|
|
86
|
+
done
|
|
87
|
+
echo '说明:Windows 用 %USERPROFILE%,Linux/macOS 用 ~;仅收录有官方默认目录的智能体。'
|
|
88
|
+
echo '改了目录的请用 --dir <路径>,不要依赖默认位置;若设置了 CODEX_HOME / XDG_CONFIG_HOME,安装自动以该变量为准。'
|
|
89
|
+
}
|
|
90
|
+
|
|
91
|
+
main() {
|
|
92
|
+
local agent="" dir="" global=0 show_list=0
|
|
93
|
+
while [ $# -gt 0 ]; do
|
|
94
|
+
case "$1" in
|
|
95
|
+
--agent) shift; agent="${1:-}" ;;
|
|
96
|
+
--dir) shift; dir="${1:-}" ;;
|
|
97
|
+
-g|--global) global=1 ;;
|
|
98
|
+
--list|-l) show_list=1 ;;
|
|
99
|
+
*) echo "未知参数: $1" >&2; exit 2 ;;
|
|
100
|
+
esac
|
|
101
|
+
shift
|
|
102
|
+
done
|
|
103
|
+
|
|
104
|
+
if [ "$show_list" = "1" ]; then list; return; fi
|
|
105
|
+
if [ -n "$dir" ]; then install_to "$dir"; echo "完成。"; return; fi
|
|
106
|
+
if [ -n "$agent" ]; then
|
|
107
|
+
local dirs first
|
|
108
|
+
if ! dirs="$(dirs_for "$agent")"; then
|
|
109
|
+
echo "未收录智能体: $agent。请用 --dir <路径> 指定技能目录。" >&2; exit 2
|
|
110
|
+
fi
|
|
111
|
+
first="${dirs%% *}"
|
|
112
|
+
install_to "$(resolve_user "$first")"; echo "完成。"; return
|
|
113
|
+
fi
|
|
114
|
+
if [ "$global" = "1" ]; then
|
|
115
|
+
echo "安装到全部已知智能体用户级目录..."
|
|
116
|
+
local dirs rel
|
|
117
|
+
for a in claude cursor codex gemini goose amp opencode windsurf workbuddy kiro trae trae-cn qwen comate codebuddy kimi agents; do
|
|
118
|
+
dirs="$(dirs_for "$a")"
|
|
119
|
+
for rel in $dirs; do install_to "$(resolve_user "$rel")"; done
|
|
120
|
+
done
|
|
121
|
+
echo "完成。"; return
|
|
122
|
+
fi
|
|
123
|
+
local installed=0 d
|
|
124
|
+
for d in .claude/skills .cursor/skills .codex/skills .config/goose/skills .config/agents/skills .opencode/skills .codeium/windsurf/skills .workbuddy/skills .kiro/skills .traecli/skills .gemini/skills .trae-cn/skills .qwen/skills .comate/skills .codebuddy/skills .kimi/skills .agents/skills; do
|
|
125
|
+
if [ -d "$d" ]; then install_to "$d"; installed=1; fi
|
|
126
|
+
done
|
|
127
|
+
if [ "$installed" = "0" ]; then
|
|
128
|
+
echo "未检测到项目级智能体目录。可用 --agent <name> / -g 装到用户级,或 --dir 指定。"
|
|
129
|
+
fi
|
|
130
|
+
}
|
|
131
|
+
|
|
132
|
+
main "$@"
|
package/package.json
ADDED
|
@@ -0,0 +1,32 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "@yottameta/yotta-guardian",
|
|
3
|
+
"version": "0.1.0",
|
|
4
|
+
"description": "元盾 —— 跨智能体的危险调用拦截护栏:确定性规则引擎 + 可插拔意图验证(不绑模型),拦截危险 exec/write/edit 等工具调用,提供审计日志。触发:代理要执行高风险命令、写敏感路径、改系统配置时。边界:默认只读检查,不自动放行危险操作;规则可配置。",
|
|
5
|
+
"license": "MIT",
|
|
6
|
+
"keywords": [
|
|
7
|
+
"agent-skills",
|
|
8
|
+
"yotta-guardian"
|
|
9
|
+
],
|
|
10
|
+
"files": [
|
|
11
|
+
"SKILL.md",
|
|
12
|
+
"LICENSE",
|
|
13
|
+
"README.md",
|
|
14
|
+
"install.sh",
|
|
15
|
+
"references",
|
|
16
|
+
"scripts",
|
|
17
|
+
"assets",
|
|
18
|
+
"bin",
|
|
19
|
+
"NOTICE",
|
|
20
|
+
"CHANGELOG.md"
|
|
21
|
+
],
|
|
22
|
+
"repository": {
|
|
23
|
+
"type": "git",
|
|
24
|
+
"url": "git+https://github.com/YottaMeta/yotta-guardian.git"
|
|
25
|
+
},
|
|
26
|
+
"publishConfig": {
|
|
27
|
+
"access": "public"
|
|
28
|
+
},
|
|
29
|
+
"bin": {
|
|
30
|
+
"yotta-guardian": "bin/install.js"
|
|
31
|
+
}
|
|
32
|
+
}
|