Back to skills
SKILL.md
Euthyna
ASecurity代码安全审计的判定纪律与交付门禁。当用户要求对一段代码、一个 PR、一次变更或一条已有的漏洞结论做安全审查与验证时使用。它做三件事:补上模型算不准的确定性事实(调用方、测试覆盖、git 历史来源),用 6 道门禁判定每条结论真假,拿不出证据的一律降级为「观察」而不是「发现」。不适用于:仅询问某个 CVE 的详情、仅要求跑一次现成扫描器、纯文档或格式化改动、以及用户只要一句快速摘要且明确接受风险时。
- 2 stars
- 0 votes
- 0 copies
- 1 view
- Added October 21, 2026
Works with
Security analysis
100/100Pro scans all 8 files and shows the line behind each finding
npx -y skills add slow-stack/euthyna --skill euthyna --agent claude-codeAre you the author of Euthyna?
Add the live security badge to your README. It updates with every re-scan.
[](https://www.skillsdirectory.com/skills/slow-stack-euthyna)---
name: euthyna
description: 代码安全审计的判定纪律与交付门禁。当用户要求对一段代码、一个 PR、一次变更或一条已有的漏洞结论做安全审查与验证时使用。它做三件事:补上模型算不准的确定性事实(调用方、测试覆盖、git 历史来源),用 6 道门禁判定每条结论真假,拿不出证据的一律降级为「观察」而不是「发现」。不适用于:仅询问某个 CVE 的详情、仅要求跑一次现成扫描器、纯文档或格式化改动、以及用户只要一句快速摘要且明确接受风险时。
whenToUse: 用户要求审计代码或仓库的安全面、验证一条疑似漏洞结论真假、判定某个发现是否可利用、审查一次变更是否引入安全回归,或要求「审完再交付」时使用。只查密钥、只查依赖版本这类单一主题,直接用对应专项技能,不要触发本技能。
disable-model-invocation: true
user-invocable: true
license: Apache-2.0
---
# euthyna — 代码安全审计的判定纪律
> εὔθυνα:雅典官员离任时必须交出账目接受审查,通不过就无法体面离任。
> 本技能的核心机制即此:**说"审完了"不算数,证据交齐、门禁通过,才算交付。**
**本技能不找 bug,它管住结论。** 找 bug 由模型与现成工具做;本技能负责:
每条结论必须过门禁,过不了就只能降级为「观察」。
---
## 何时用 / 何时不用
**用**:
- 用户要求审计代码、仓库、一次变更(PR / commit / diff)的安全面
- 用户拿来一条疑似漏洞,问「这是真的吗」「是否可利用」
- 用户要求审查某次变更是否把已有的安全防护改弱了
- 用户要求「验证完再交付」
**不用**(直接拒绝或转其他技能):
- 只问某个 CVE / 某个依赖的详情 → 用依赖审计类工具
- 只要求跑一次现成扫描器并贴出结果 → 那是工具调用,不是审计
- 纯文档、格式化、lint 类改动 → 无安全面
- 用户明确只要快速摘要并接受风险 → 说明这是「非审计模式」,不套用本技能的裁定格式
---
## 三条不可跳过的规则
这三条是本技能与「让模型仔细点」的全部区别。任何阶段、任何路径都不许跳过。
### 规则 1:可测量的量一律由命令产出,模型只做判读
调用方数量、测试覆盖率、依赖版本、行号、提交哈希——**这些一律不许靠印象回答**。
模型可以在命令不可用时说「不可测量」,但不许估算后当成事实写进结论。
> 这条来自一次实测翻车:某包在 GitHub 上显示 5+ 人维护,而 npm 的实际权限列表只有 1 人;
> 另一个每周下载 1.6 亿次的包在某个数据源里显示零下载。**手感估数字必错。**
### 规则 2:证据强制到 `file:line`,禁止占位符
- 每条主张引用具体位置,格式 `path:L123`,有版本时写 `path:L123 (commit abc1234)`
- 禁用 `probably` / `likely` / `大概是` —— 去追真实代码,追不了就明说追不了
- 演示代码(PoC)里禁止 `TODO`、`...`、`// 攻击者在这里做某事`
- **一旦发现 PoC 用了人为绕过**(mock、stub、禁用检查),该 PoC 判定**无效**
### 规则 3:缺数据 ≠ 干净
每个判据只能落到三态:**已评估-干净 / 已评估-标记 / 因某原因不可评估**。
- 一次什么都没测到的运行,产出的是「不可评估」,**不是**「没发现问题」
- 引用任何「干净」结论之前,先看覆盖表
- **数字必须逐字引用**,不得重新推导、四舍五入或修饰
- 没发现不等于背书
---
## 入口决策树
```
用户给了什么?
│
├─ 一条已有的疑似漏洞断言 ──────────► 阶段 C:结论面验证
│ (「这是真的吗」「可利用吗」) 读 references/verification-gates.md
│ ★ 结论依赖「测过没有」→ 跑 coverage
│
├─ 一次变更(PR / diff / commit)────► 阶段 B:变更面审计
│ (「这个 PR 安全吗」) 读 references/change-audit.md
│ ★ 第一条命令:euthyna audit --base <分叉点>
│ (history + deps 一次跑完,见下节)
│ ★ 要谈测试覆盖 → 再跑 coverage
│
├─ 一个仓库 / 依赖面 ────────────────► 阶段 A:依赖面审计
│ (「依赖有没有问题」) 读 references/dependency-audit.md
│
└─ 一个仓库的整体安全审计 ───────────► 阶段 B 为主,A 与 C 作为子步骤
```
★ = **在动手人工读代码之前**先跑,不是读完之后的补充说明。
产出器给的确定性事实,决定了人工阅读该往哪里使劲。
**可以做多个阶段,但阶段之间不许互相替代。**
特别是:**阶段 B 报出的疑似发现,必须逐个走阶段 C 验证**,不许直接写进报告当结论。
### 模式词(斜杠命令)
用户用斜杠命令进来时,按下表把模式映射到阶段与第一条命令。**词表只在这里维护**,
各宿主命令文件(Cursor / OpenCode / Copilot / Hermes)指向本节,不各自重抄一份。
| 你打 | 走哪条支路 | 第一条命令 |
|---|---|---|
| `/euthyna pr` | 阶段 B 变更面 | `euthyna audit`(省略 `--base` 即按分叉点推断并声明) |
| `/euthyna graph` | 阶段 B 的来源谱系视图 | `euthyna audit --graph`(同样可省略 `--base`) |
| `/euthyna repo` | 阶段 A 依赖面 | `euthyna deps --all` |
| `/euthyna claim <结论>` | 阶段 C 结论面 | `euthyna coverage --symbol <名>` |
| `/euthyna gate <报告>` | 校验一份已写的报告 | `euthyna gate <报告>` |
| `/euthyna help` | 只打印这张表 | 不跑命令,不改变状态 |
`/euthyna graph` 不是新测量:`--graph` 只是把 `history` 已经给出的归属画成 Mermaid。
**图上没有第二条边不等于内容没被移过**,边界见 references/fact-producers.md。
---
## 本技能自带的两个确定性测量
调用方、覆盖率、依赖漏洞、密钥这些**不重造**(见文末分工表)。但有两件事没人做、
且模型自己算不准,所以本技能自带一个零依赖 CLI:
| 测量 | 回答的问题 | 什么时候**必须**跑 |
|---|---|---|
| `audit` | 上面两个问题**一次跑完**(history 默认追溯最初引入者 + deps 枚举 lockfile 全部依赖),合并一份报告 | **每次审计的第一条命令**(阶段 B 开场) |
| `history` | 这次变更**删掉**的代码来自哪个提交?那个提交是不是安全修复? | 需要单独重跑 history 时(如换 `--base`) |
| `coverage` | 某个符号在测试运行中**到底有没有被调用过**? | 报告里要说「测过 / 没测过」时(阶段 B / C) |
```powershell
# --base 可以省略:省略时按 merge-base(HEAD, origin/main) 推断,并在报告里声明为 range-inferred
node <euthyna 仓库>/bin/euthyna.js audit --base <改前版本> --repo <被审计的仓库>
# history / coverage 按需单独跑:
node <euthyna 仓库>/bin/euthyna.js history --base <改前版本> --repo <被审计的仓库>
node <euthyna 仓库>/bin/euthyna.js coverage --coverage <覆盖率文件绝对路径> --symbol <符号名>
```
⚠️ **`node bin/euthyna.js` 这种相对路径一定失败。** 审计时当前目录是**被审计的项目**,
不是 euthyna 仓库,会报 `Cannot find module`。要用 euthyna 仓库的路径,
并把被审计仓库用 `--repo` 显式传进去(`--base` / `--head` 相对它解析)。
**退出码**——`2` 与 `0` 的区别就是这套东西存在的意义:
| 码 | 含义 | 怎么办 |
|---|---|---|
| `0` | 已测量,无安全相关发现 | 继续,但**要读「未评估的判据」一节** |
| `10` | 已测量,存在 `security` 分类的事实 | **提高优先级**,逐条走阶段 C,不要直接当结论 |
| `1` | 用法错误 | 修命令。这不是测量结果 |
| **`2`** | **完全无法测量** | **不得当作干净**。换测量方式,或把判据标为「不可评估」 |
命令不可用时(没装、没有检出):**把判据标为「不可评估」,不要手工估算顶上。**
操作手册(命令、真实输出样例、失效情形):`references/fact-producers.md`。
### 执行纪律(复现命令与 PoC)
`--verify` 与 PoC 会在**用户的机器**上执行命令。跑任何复现/验证命令前:
- **先取得用户明确批准**,把要跑的命令原文列出来——不跑没报备的命令
- 能在沙箱/临时容器里跑的(如 Docker),**优先沙箱**;无法沙箱时说明风险再跑
- 报告里的 PoC 是给「拿到报告的人」复现用的;裁定过程中 agent 自己执行的每条命令同样适用本节
---
## 事实契约(测量与判定之间的接口)
本技能定义的是**测量层与判定层之间的接口**:`docs/fact-contract-zh.md`。
要点:
- 契约只装**事实**,不装分数、不装严重性等级、不装修复建议
- 每条事实必须带**复现命令**或**产出工具+版本**
- **分数不得用作门禁**(这是从 `dsh-trust-check` 学到的:它的契约明写「不要拿 `score` 或 `band` 做门禁」)
- `approximate` 的事实**不得参与门禁**
- **`unknown` 不是「干净」**——三态里最常被误用的就是它
事实的读法(能推出什么、**不能**推出什么):`references/fact-contract.md`。
---
## 裁定格式
无论走哪条路径,产出必须落到这个形状:
```
BUG #N TRUE POSITIVE — [一句话描述]
门禁全部通过。证据:path:L123 (commit abc1234)
复现:<可重跑的命令或 PoC 位置>
可利用性:EASY / MEDIUM / HARD
影响:具体到资金量 / 被提升的权限 / 被暴露的数据
BUG #N FALSE POSITIVE — [拒绝理由]
门禁 N(门禁名)FAIL:<具体证据>
例:第 98 行校验保证 packet_size >= 16,故 (packet_size - header_size) >= 8。
下溢在数学上不可能。
BUG #N INCONCLUSIVE — [无法判定的原因]
门禁 N(门禁名)未评估:<为什么>
```
**第三态 `inconclusive` 必须存在。**
Trail of Bits 的原始 fp-check 只有两态,因为它靠 Stop hook 无限强制继续直到补完;
**DSH 上做不到**(Stop hook 必须自带限流,见 `docs/dsh-stop-gate-zh.md`)。
所以必须有这个诚实出口——不许把「没查完」写成 `FALSE POSITIVE`。
---
## 门禁的程序化校验(euthyna gate)
上面的格式不是摆设:`euthyna gate <报告文件>` 会机械地逐条核对——
- **TRUE POSITIVE**:证据必须到 `path:L123`、必须有复现命令、必须说明影响、六门禁必须全过;
- **FALSE POSITIVE**:至少一条门禁 FAIL 且带具体证据;
- **INCONCLUSIVE**:至少一条门禁未评估,且没有任何 FAIL。
缺证据、缺复现、或门禁与裁定互相矛盾(如 TRUE POSITIVE 却带 FAIL 门禁)的 finding,
会被**降级为「观察」**并以退出码 `10` 报出——不需要裁定者自觉,校验器替你卡住。
```powershell
node <euthyna 仓库>/bin/euthyna.js gate <报告文件>
# 重跑每条复现命令核验(白名单工具、按 argv 执行不走 shell):
node <euthyna 仓库>/bin/euthyna.js gate <报告文件> --verify --cwd <被审计仓库>
```
- 退出码 `0` = 全部通过;`10` = 有 finding 被降级;`2` = 报告无法读取 / 没有可校验的 finding。
- `--verify` 下复现命令跑不通同样构成降级——「说能复现」不算数,跑通才算。
**报告交出去之前,先过一遍 `euthyna gate`。** 它校验的是报告自己的自我声明,
不测量目标仓库——因此它不能代替裁定,只能保证「拿不出证据的结论不会以已确证的面貌出去」。
---
## 报告必须落盘
- 只输出到聊天算**失败**。必须写报告文件
- 文件名:`<PROJECT>_EUTHYNA_AUDIT_<YYYY-MM-DD>.md`
- 写文件失败的降级顺序:当前工作目录 → 用户桌面 → 临时目录 → **最后手段**才输出到聊天并提示用户手动保存
---
## 交付前的自检(逐条打勾,缺一条不许说「审完了」)
- [ ] 每个疑似发现都走了**完整的**阶段 C,不是「看一眼觉得是假的」
- [ ] **跑过 `audit`(或 diff 有删除行时跑过 `history`)**;删自安全修复提交的代码已按最高风险处理
- [ ] 报告里每句「测过 / 没测过」都有 `coverage` 输出支撑,或已标为「不可评估」
- [ ] **退出码为 `2` 的判据没有出现在「干净」一栏**
- [ ] 每条结论都带 `file:line`
- [ ] 每条结论都标了三态之一(干净 / 标记 / 不可评估)
- [ ] 覆盖表写清了**哪些判据没评估、为什么**
- [ ] 恶魔代言人 13 问逐条答过(含防假阴性的第 12、13 问)
- [ ] 报告文件已落盘
- [ ] 报告已通过 `euthyna gate` 校验(退出码 `0`;有降级要读降级原因)
- [ ] 没有把「缺数据」写成「干净」
---
## 参考文件
按需加载。**不要一次全读**——渐进披露是这套东西能在长会话里保持有效的原因。
| 文件 | 内容 | 什么时候读 |
|---|---|---|
| `references/verification-gates.md` | **阶段 C**:路由、6 门禁、误报清单、恶魔代言人、PoC 规则 | 判定一条已有断言时(**最常用**) |
| `references/change-audit.md` | **阶段 B**:基线、深度 vs 风险、来源归属、爆炸半径、对抗建模 | 审一次变更时 |
| `references/dependency-audit.md` | **阶段 A**:清单/锁文件、三态、文体规范、禁止事项 | 审依赖面时 |
| `references/bug-classes.md` | 9 类缺陷的专项检查与**默认假设方向** | 定了缺陷类别之后 |
| `references/meta-mechanisms.md` | 六个元机制:让流程不退化成走过场 | **审计开始时读一次** |
| `references/fact-producers.md` | **操作手册**:两个测量何时跑、命令怎么写、退出码怎么处理、真实输出样例、失效情形 | **跑产出器之前**(阶段 B / C) |
| `references/fact-contract.md` | 拿到事实之后能推出什么、**以及它不能推出什么** | 读完产出器输出之后 |
> **技能文本自包含**:以上文件都在 `references/` 内,不依赖技能目录之外的路径,
> 可以整目录复制到任何技能根使用。
>
> ⚠️ 但**产出器本身是独立程序,不在技能目录里**。复制技能不会把 CLI 一起带走。
> 新环境里要单独安装、或提供本项目的一份检出,否则相关判据只能标为「不可评估」——
> 那也是一个诚实的结果,比手工估算强。见 `references/fact-producers.md` 第一节。
---
## 与既有生态的分工(避免重复劳动)
| 已经有人做的事 | euthyna 怎么做 |
|---|---|
| 调用图 / 爆炸半径(`dsh-tool-lens`、`dsh-blast-radius`) | **不重造**,消费其输出 |
| 覆盖率(`dsh-code-coverage`) | 不重造,消费其输出 |
| 依赖漏洞(`dsh-dep-vuln-scan` 等) | 不重造,消费其输出 |
| 密钥扫描(`dsh-code-security`) | 不重造,消费其输出 |
| 交付门禁机制(`dsh-doublecheck`、`formalswarm`) | 机制可借鉴;euthyna 的门禁内容是**安全专属**的 6 门禁 |
| 证据生命周期与 PoC 实验室(`dsh-omv`) | 可并存:`dsh-omv` 可作为事实契约的**消费方** |
**euthyna 只补两件没人做的确定性测量**(见 `docs/positioning-zh.md` §7.2):
git 安全回归的机械判定,以及「符号 × 真实执行覆盖」的 join。
Files in this skill
- SKILL.md
- references/bug-classes.md
- references/change-audit.md
- references/dependency-audit.md
- references/fact-contract.md
- references/fact-producers.md
- references/meta-mechanisms.md
- references/verification-gates.md
Attribution
Comments
Loading comments…
Newsletter
Get the weekly list of safe new skills, and the ones we pulled.