← 返回列表
✓ 可直接安装
εὔθυνα —— 在古典时期的雅典,每一位卸任官员都必须提交的审计。
自动检查通过:npm 包已发布且 engines 声明满足基线(声明 Node >=20);该结论来自程序自动检查,未经人工实机验证。 · 最近上游提交 2026/9/24 · 已提供中文文档
⚖️ 审计 AI 编码代理无法跳过的环节——确定性事实(git 历史、测试覆盖率)与用于代码安全审计的六道门控声明裁决。不是又一个扫描器。
综合分
30.7
GitHub 分
30.7
用户评分
—
★ Stars
1
周下载量
—
安装插件(需先安装 dsh CLI 引擎:npm install -g @deepseek-ai/dsh)
dsh plugin --profile web add euthynanpm 包 euthyna 已校验归属本仓库,走 npm 安装最省事
信任档位:已验证本站已于 1 天前真实安装成功(L4 · 真实安装)
- 是什么
- dsh 原生插件 · chat
- 装得上吗
- 本站已真实安装成功(L4 · 真实安装,非静态推断)
- 安全吗
- 本站尚未对该插件做风险分级(暂未覆盖,不等同于无风险)
- 还在维护吗
- 活跃:最近一次提交在 0 天前
档位由下列信号合成:本站实装验证(真实安装,当前最高到 L4)· 验证所用 dsh 版本 · 静态安装检查 · 风险分级 · 仓库维护状态。下方各区块是它的证据明细。 验证判据与等级说明 →
🟢实装验证通过· 2026/9/23
由本站实装验证器在真实 dsh 环境安装成功,非静态推断。
数据截至 2026/9/25(元数据每日更新 · 实装验证按队列轮转,单条结论的验证时间见上方)
安装兼容性检查✓ 自动检查通过
以下结论由程序自动检查 npm 包、engines 声明与入口文件得出,未做人工实机验证——能装不等于用着没问题。
✓npm 包euthyna @ 0.4.0
✓Node 引擎要求 >=20 · 基线 Node 22.19 满足
✓dsh CLI 依赖未声明 dsh 版本约束
✓入口文件main/exports/bin 已声明
验证方式:npm registry 存在性 + package.json 静态校验 · 最后验证 2026/9/23 19:04:08
依赖的 DSH / Cordis 模块
@deepseek-ai/dsh-skill-filesystem用户评分
还没有人投票,来当第一个
订阅周报,不错过优质插件更新
每周一封 · 高评分插件 + 新用户活动
README
由 DeepSeek 最新模型翻译生成euthyna εὔθυνα —— 在古典时期的雅典,每一位卸任官员都必须提交的审计。 你不能就这样一走了之、离开公职。你要交出你的账目,接受审查。 通过,你带着完好的声誉离开。失败,你就要面对审判。 euthyna 是一个面向 AI 编程代理的代码安全审计框架。 它不是又一个 扫描器。它做两件事:它产出代理无法通过阅读代码计算出来的事实, 并且它迫使代理做出的每一项安全断言都通过关卡,然后才能算作一个发现。 📖 用大白话说说问题 当 AI 编程代理接触安全问题时,它会以两种特定的方式失败: 1. 它报告并不真实的东西。 看起来危险的代码会被称作 漏洞,却没有追踪数据。在真实代码库上的验证运行中——一个 JavaScript 的、一个 Python 的——模式匹配出来的“漏洞”大多是 误报:第一次运行中5 个里有 5 个在关卡处被驳倒;第二次运行中 3 个里有 2 个被驳倒,第三个未解决(INCONCLUSIVE,依赖供应链)。参见 案例研究 (Python/crewAI、 JavaScript/axe-core)。 2. 它的保证无法被核查。 “我做完了。”“测试覆盖了这个。”“现在 安全了。”这些都是断言。你无法区分一句“完成声明”和一笔“完成的交易”。 这两者都不是靠告诉代理“更小心一点”就能解决的。euthyna 改变的是你与代理之间的 握手方式: Agent 说“我完成了”不算数。账户被移交,由门禁来裁决。 ⚖️ 它做的两件事 1. 它衡量模型无法衡量的东西 三个事实生产者——一个零依赖的 Node CLI: - history —— 对于变更删除的每一行,它将该行归因到一个提交,并根据提交信息、其自身的 diff 以及被删除行的内容对该提交进行分类(一个被删除的 if (!authorized) 即使在“tweaks”主题下也会被标记)。默认情况下,归因通过 git log -S 追溯首次引入该内容的提交(--no-origins 回退到 blame 的“最后触碰”,这更快,但会错误归因后来被格式化提交移动的安全代码行)。如果被删除的代码来自安全修复,则会被标记。这是任何模型都无法通过阅读 diff 完成的 git 考古。 - coverage —— 这个符号是否真的被测试调用过?它只有两个答案:从未被调用(已确定),或被进入但这不能证明任何特定调用点(未知)。它从不报告“已执行” —— V8 覆盖率会将不可达代码标记为已覆盖,而“行被覆盖 → 调用已运行”恰恰在审计无法承受的方向上是错误的。推理见 docs/fact-contract.md §6.2。 - deps —— 一个依赖实际上被固定到哪个版本?它读取锁文件 (package-lock.json / Cargo.lock / go.mod)并报告解析后的版本,或者报告某个依赖在依赖树中完全不存在。这是解决供应链声明(“该应用使用了存在漏洞的 X 版本”)的事实:版本到 CVE 的映射留给裁决层,正如事实契约所要求的那样。见 docs/fact-contract.md §6.3。 2. 它对 agent 的声明进行门禁 skill 就是审计纪律本身,以可加载的 Markdown 形式呈现。每一项安全声明都必须通过六道门——可达性、信任边界、真实 影响,以及它们的对应项。无法提供证据的声明会被降级为观察,而不是作为发现报告。“我完成了”变成一个包:声明、 证据,以及可复现两者的命令。 这些门不只是文字。euthyna gate 读取一份裁决报告,并 机械地根据其裁决检查每一项发现——证据精确到 path:L123、一条复现命令、一份影响声明、一致的门的 状态——并降级任何不达标的内容。--verify 会重新运行复现命令:默认是 git 命令, 解释器命令(node/npm/python)只有在显式 --allow-exec 下才会运行,因为报告中的解释器命令是任意代码,而该标志是调用者为该报告背书。 🖥️ 它适用于哪些工具,以及如何安装 一切的前提:Node >= 20 和 git。除此之外无需安装任何东西—— 该项目刻意保持零依赖。 | 宿主 | 技能(审计纪律) | CLI(事实生产者) | |---|---|---| | DSH | dsh plugin --profile web add euthyna —— npm 包会挂载它自己的技能;或者将 .agents/skills/euthyna/ 复制到 ~/.agents/skills/(用户级)或 /.agents/skills/。Markdown 会热重载;无需重启。 | npm install -g euthyna —— 可在任何终端中运行 | | Claude Code | /plugin marketplace add slow-stack/euthyna 然后 /plugin install euthyna@euthyna,或者将 .agents/skills/euthyna/ 复制到 ~/.claude/skills/ | 同上 | | Codex | 同样的 Markdown 层可以工作;打包通过 Codex 的插件/市场格式进行 | 同上 | | Hermes | 将同一个文件夹复制到 ~/.hermes/skills/ 下的某个分类文件夹中,或者使用 hermes skills install 从仓库安装 —— 至于斜杠命令,请将该仓库作为插件安装(见下文) | 同上 | | OpenCode | 将同一个文件夹复制到 ~/.agents/skills/ 或 ~/.config/opencode/skills/(OpenCode 两者都会加载;未知的 frontmatter 字段会被忽略)。若要使用 /euthyna 斜杠命令,请将 .opencode/commands/euthyna.md 复制到 ~/.config/opencode/commands/ —— 它是一个提示模板,告诉模型运行 CLI | 同上 | | OpenClaw | 将同一个文件夹复制到 ~/.agents/skills/(或 /.agents/skills/)—— OpenClaw 原生地将每个 user-invocable 技能暴露为斜杠命令,因此 /euthyna 无需额外文件即可工作。已在 ClawHub 上发布为 @modusensus/euthyna(中文)和 @modusensus/euthyna-en(英文):clawhub install modusensus/euthyna | 同上 | | GitHub Copilot | 将同一个文件夹复制到 .github/skills/(项目)、~/.copilot/skills/ 或 ~/.agents/skills/(个人)—— Copilot 会读取这三者。若要使用 /euthyna 提示,请将 .github/prompts/euthyna.prompt.md 复制到你的仓库或配置文件的同名文件夹中。gh skill 也可以从此仓库安装技能 | 同上 | | Cursor | 将同一个文件夹复制到 .cursor/skills/(项目)、~/.cursor/skills/(全局)—— Cursor 也会为兼容性读取 .claude/skills/。若要使用 /euthyna 命令,请将 .cursor/commands/euthyna.md 复制到匹配的 commands/ 文件夹中(纯 Markdown,无 frontmatter) | 同上 | | 任何终端 | — | npm install -g euthyna,然后 euthyna … | 该技能提供两种语言版本。上面的目录是中文原版(euthyna); 英文镜像位于 .agents/skills/euthyna-en/(技能名 euthyna-en)—— 如果是英语代理,请安装 那个版本,或者自行翻译该文件夹。两者定义相同的纪律,并且 euthyna gate 接受任一语言的报告标记。 两点坦诚说明: - 技能是指令;CLI 是测量。 技能目录 不包含 CLI。请从 npm 安装 CLI(npm install -g euthyna),或者 保持此仓库处于检出状态;在没有 CLI 的主机上,该技能要求将 无法衡量的标准记录为未评估,而不是进行猜测——这种 回退机制是设计使然,而非缺陷。 - CLI 默认使用中文,按需使用英文。 除非你 传入 --lang en(任何命令)或设置 EUTHYNA_LANG=en,否则输出为中文; 对现有用户而言,默认值永不改变。技能文本和 CLI 的报告 均以两种语言存在——英文读者应预期只有未请求英文的 运行才会输出中文。 🎯 首次使用 euthyna 是由用户调用,而非自动触发。该技能声明了 disable-model-invocation: true,因此模型不会自行加载它—— 你必须明确请求审计。这也是你区分它 与你可能安装的其他安全技能的方式:如果你没有点名它, 它就没有运行。 触发审计 在对话中直接说出来: 「用 euthyna 审计一下 D:\some-project,审完再交付」 然后智能体加载该技能并执行审计规程:它首先产生 确定性事实(history / coverage / deps),让每个 可疑项通过六道关卡,并写出报告文件,而不仅仅是在 聊天中回复。 斜杠命令 | 宿主 | 命令 | 设置 | |---|---|---| | Claude Code | /euthyna | 将包中的 .claude/commands/euthyna.md 复制到 ~/.claude/commands/(用户级)或 .claude/commands/(项目级) | | Codex | — | Codex 的自定义提示斜杠命令(~/.codex/prompts/)已被上游弃用;同样的 Markdown 仍可手动放置在那里 | | DSH | /euthyna | 随插件安装;重启后该命令会打印使用手册(DSH 斜杠命令运行时不经过模型) | | Hermes | /euthyna | 将此仓库安装为 Hermes 插件:hermes plugins install slow-stack/euthyna,然后 hermes plugins enable euthyna(需要 PATH 上有 Node >= 20;仓库根目录带有 plugin.yaml + __init__.py)。该命令转发到 CLI 并打印其输出,不经过模型。技能本身仍可单独安装:hermes skills install slow-stack/euthyna/.agents/skills/euthyna | | OpenCode | /euthyna | 将 .opencode/commands/euthyna.md 复制到 ~/.config/opencode/commands/ 或 .opencode/commands/ | | GitHub Copilot | /euthyna | 将 .github/prompts/euthyna.prompt.md 复制到 .github/prompts/(项目级)或你的配置文件的提示文件夹;在 VS Code 和 Copilot CLI 中可用 | | Cursor | /euthyna | 将 .cursor/commands/euthyna.md 复制到 .cursor/commands/(项目级)或 ~/.cursor/commands/(全局);纯 Markdown,无 frontmatter | 如何判断是 euthyna 执行的审计 - 报告文件名为 _EUTHYNA_AUDIT_.md - 判定采用三态形式 BUG #N TRUE POSITIVE / FALSE POSITIVE / INCONCLUSIVE - 每项主张都引用 path:L123 证据和一条复现命令 - 缺失数据记录为 not evaluated,绝不记为“clean” 🚀 快速开始 npm install -g euthyna euthyna audit --repo --base main --head HEAD # history + deps in one run euthyna coverage --coverage coverage/coverage-final.json --symbol euthyna deps --repo --all # or --dep for a single dep euthyna gate --verify --cwd # mechanically check the six gates 或者不进行全局安装:npx euthyna audit --repo --base main。 从检出副本开始(开发): git clone https://github.com/slow-stack/euthyna cd euthyna && npm test # 207 tests; no install step exists node bin/euthyna.js audit --repo --base main --head HEAD history 报告的内容如下所示: 已确证 (7) • 本次变更删除了 4 行来自提交 ab877f9d70 的代码,分布在 2 个文件。 提交信息:"fix(link-in-text-block): don't match style or script text (#3775)",分类:fix 证据: lib/checks/color/link-in-text-block-evaluate.js (ab877f9d70) 复现: git blame --porcelain -L 104,104 -L 114,114 -- lib/checks/.../evaluate.js 每一行被删除的代码都会被追溯到一个提交,而 复现 (Reproduce)命令让你可以自行重新推导该主张,而无需信任报告。 添加 --json 可获得结构化事实报告,添加 --pickaxe 可检测那些 曾被删除、现在又被重新添加回来的行。来源追溯默认开启(被删除的行 会被归因到首次引入其内容的提交);--no-origins 则回退到 blame 的最后修改者归因,速度更快。 退出码是契约的一部分 调查该生态系统中的八个测量插件后发现,它们没有一个发布 进程退出码,这使得它们的输出无法用作 CI 门禁。而这个工具会发布: | 代码 | 含义 | |---|---| | 0 | 已测量;未发现安全分类问题——或 gate 报告完全通过 | | 10 | 已测量;至少存在一项 security 分类的事实——或 gate 报告中有发现被降级为观察项 | | 1 | 用法错误 | | 2 | 完全无法测量——不得被解读为 clean(同样适用于:无法读取或没有任何发现的 gate 报告) | 2 与 0 不同,这正是关键所在:未能测量 和 测量后未发现任何问题 是两回事。 🧱 实际构建了什么 | 组件 | 它是什么 | 状态 | |---|---|---| | 事实生产者 | 一个零依赖的 Node CLI,确定性地回答三个问题 | 可用,已测试 | | 技能 | 审计纪律本身,以可加载的 Markdown 形式提供 | 可用,可加载 | | 基准测试 | 针对裁决层的盲测召回率测量 | 四轮已完成;循环只需一条命令(bench/adjudicate.js),并在 CI 上有一个确定性的黄金轮次 | ✅ 已验证的内容,以及尚未验证的内容 本项目力求明确区分二者。当前状态: 已验证 - history 归因在真实仓库上的表现——涵盖两种语言。 针对 axe-core(JavaScript)和 crewAI(Python)运行;删除的行被归因到 引入它们的提交,然后手工对照 git blame 进行核对。为那次比较开发的检查 现在作为回归测试在测试套件中运行。 - coverage 在三种格式的真实输出上的表现——c8/V8 JSON、经典 istanbul(jest/nyc,相同的 fnMap/f 结构)以及 coverage.py JSON(格式 3)——能正确区分全部三种状态,并且 拒绝任何不是可识别覆盖率报告的内容,而不是对其回答“未定位到符号”。 - deps 在真实 lockfile 上的表现——解析出的版本会附带指向 lockfile 的行级证据 指针,缺失的依赖会作为已确立的缺失来报告,而不是被静默跳过。已针对一个填充过的 npm v3 lockfile 以及 Cargo.lock 和 go.mod 的 fixture lockfile 进行验证。 - 裁决召回率与特异性,以盲测方式测量:10/10 个案例,4 个真实 漏洞全部被捕获,6 个非漏洞全部被正确排除,无弃权。 第 2 轮将每个案例重复三次——30 次裁决,零次翻转,其中四次 是在不同模型上进行的。第 3 轮将集合扩展到 18 个案例(8 个真实,10 个非真实),并 在每一轮重新打乱盲测 id:54 次裁决,24/24 个真实缺陷声明被捕获, 无漏报、无弃权,29/30 个非漏洞被正确排除——而 唯一的“误报”是该轮的发现,而非噪声:裁决器捕获了某个 fixture 防护中的一个缺陷, 经复现确认并修复。每个案例都是一个近邻 对——相同模式,仅差一个防护——因此裁决必须来自阅读防护, 而不是识别形状。第 4 轮在新的 id 打乱下重新运行了完整集合,其中 那个两次被击败的防护——重建为裸名允许列表——迎来了它的首次盲测 裁决:54/54 正确,全部 8 对均被区分开,并且在第二个模型 家族上的第三次运行与前两次在每个案例上都一致。 参见 bench/RESULTS.md、 bench/RESULTS-round2.md、 bench/RESULTS-round3.md 以及 bench/RESULTS-round4.md。 - 交付门机制,通过运行真实宿主插件验证:阻断有效,并且两个 - 有文档记录的出错方式则不会。 参见 docs/dsh-stop-gate.md。 - 门禁纪律,从机制上。 euthyna gate 不是散文式的声明:测试套件按裁决结果固定契约(一个 TRUE POSITIVE 若没有 path:L123 证据、复现命令或全部六道门禁通过,则被降级;一个 FALSE POSITIVE 需要一个带原因的失败门禁),并且 --verify 经过测试,不会在没有 --allow-exec 的情况下执行解释器命令。如果技能文本不再声明六道门禁、三种裁决结果或强制执行它们的命令,test/skill.test.js 会让 CI 失败。 - 裁决循环,端到端且在 CI 上。 bench/adjudicate.js 运行完整的一轮——盲树、每个案例一个裁决进程、机器验证的报告、评分——并且每次推送都会运行一个确定性的 golden 轮次,因此无需模型即可检查流水线(以及 score.js 在错误裁决时变红)。 未验证 - 该方法是否能在真实代码中发现漏洞。 基准测试衡量的是该纪律能否针对一项主张得出正确裁决。它并不衡量这些主张最初是否会被发现。这些案例是刻意构造的。crewAI 案例研究浮现出一个 INCONCLUSIVE(pickle 反序列化,依赖供应链)并驳斥了其余部分——这是一个方向性信号,而非比率。 - 实地召回率。 基准测试的真实缺陷案例是构造的;该纪律对没人特意为其准备的代码是否有帮助,尚未测量。 - 覆盖率生产者的 source maps、打包器、monorepos。 未测试。 - CI 上的真实模型轮次。 golden 轮次是确定性的管道,而非裁决:它按设计将基准真相写入报告。模型轮次需要凭据,且本质上是不确定的,因此它保持为本地/手动步骤(bench/README.md 记录了该命令),而不是可能不稳定的 CI 门禁。 - --verify 作为沙箱。 它不是沙箱,也不声称是:它以你的权限执行报告中的命令,除非传入 --allow-exec,否则仅限 git。 - deps 仅限三种格式和版本事实。 pnpm/yarn/poetry 锁文件会被检测但不解析(报告为未评估,绝不猜测);go.mod 报告的是声明的需求,而非解析后的构建版本;并且生产者从不将版本映射到 CVE——该映射被有意留给裁决层。 - 关于案例研究对象安全性的任何内容——这些运行没有发现任何可认可或谴责之处;这不是对任一项目的陈述。参见 docs/case-study-crewai.md 和 docs/case-study-axe-core.md。 - 通过在 GitHub 上运行来验证的 CI 配方。 退出码门禁和工作流接线是 记录于 docs/ci-integration.md; 该工作流片段尚未作为实际的 Actions 运行进行过验证。 📂 仓库布局 euthyna/ ├── bin/ src/ test/ 事实生产者(零依赖,Node >= 20) ├── .agents/skills/euthyna/ 审计纪律,作为可移植技能 ├── plugin.yaml __init__.py Hermes 插件:/euthyna 斜杠命令 ├── bench/ 盲测召回基准 + 结果 ├── docs/ 设计说明与案例研究(英文和中文) ├── tools/ 研究与验证脚本 └── data/ DSH 插件目录快照 tools/fetch-references.js 会将本项目读取的上游源码下载到 .refs/ (已被 gitignore)。本仓库不分发任何第三方文件 —— 原因以及欠谁什么, 请参见 NOTICE.md。 🧭 状态 尚处早期,并且对此坦诚。可用部分:事实生产者(euthyna audit 用一条命令运行历史 和完整的依赖面 —— 技能将其记录为每次审计的第一条命令)、技能、基准测试框架。尚未构建: 弥合剩余召回差距所需的 git 历史 / 覆盖率工作。 设计说明有英文和中文版本;-zh 文件是原始版本。 🤝 贡献 请阅读 CONTRIBUTING.md。简而言之:提交中不得包含 AI 署名, 每次提交只做一处更改,并且在亲自运行之前不要声称某功能可用。 🔒 安全 事实生产者会执行 git 并解析覆盖率输出;其完整性就是产品本身。 哪些属于范围,以及如何私下报告:SECURITY.md。请注意, bench/cases/ 中的基准测试夹具在构造上就是有漏洞的,它们并非安全漏洞。 📜 许可证 Apache License 2.0 —— 参见 LICENSE。