test-triage

test-triage is a skill for Claude Code, Codex from niki914/zafiro. It costs 71 tokens per session (2,182 once invoked), scanned A, original, MIT.

A review step for deciding whether a unit test should exist before writing or changing it. It asks which specific real bug the test would catch and removes tests that protect no meaningful behavior.

In plain words
What is it for?
Use it before adding or modifying a unit test, especially after a refactor, to identify the behavior worth protecting and discard tests with no clear purpose.
Why use it?
It helps prevent large, repetitive test suites that add maintenance work without catching regressions. It also stops tests from merely checking compiler guarantees or existing coverage.

Skill for Claude CodeCodex

Written for no agent in particular: nothing here depends on one. Also seen: installed under .agents/ (shared by several agents).

Good fit Use it before adding or modifying a unit test, especially after a refactor, to identify the behavior worth protecting and discard tests with no clear purpose.

Compare 6 skills from other repositories ↓
Install with agentmods
npx agentmods add skills/niki914/zafiro/test-triage
Install

Getting it into your agent

One page per mod, every tool's command on it. A separate URL per tool would split the same page into five that compete with each other.

Any agent
npx skills add niki914/zafiro --skill test-triage
Clone the repo
git clone --depth 1 https://github.com/niki914/zafiro

Made for: Claude Code, Codex.

Wrote this? Show the measurements

A badge with what this costs and how it scanned, read live from this page, so it follows the numbers instead of freezing them. Markdown for a README, HTML for a documentation site or a project page.

agentmods badge for test-triage

README.md
[![agentmods](https://agentmods.dev/badge/skills/niki914/zafiro/test-triage/github.svg)](https://agentmods.dev/skills/niki914/zafiro/test-triage)
Your own site
<a href="https://agentmods.dev/skills/niki914/zafiro/test-triage"><img src="https://agentmods.dev/badge/skills/niki914/zafiro/test-triage/github.svg" alt="Measured on agentmods" height="20"></a>

Or the 80×15 button, for a site that already has a row of RSS and ATOM ones. Only the verdict fits; the numbers stay here.

agentmods 80×15 button for test-triage

Your own site · 80×15
<a href="https://agentmods.dev/skills/niki914/zafiro/test-triage"><img src="https://agentmods.dev/badge/skills/niki914/zafiro/test-triage.svg" alt="Reviewed on agentmods" width="80" height="20"></a>
Per session 71 Skills are progressive disclosure: only the name and description are preloaded; the body loads when the skill is used.
When invoked 2,182 The whole file, excluding the scripts and references it only reads on demand.
Security scan A 0 findings. A grade says what 26 rules found in the file — not that it is safe.
Origin original No closer match found in the catalogue.
Token cost

What it costs to keep this loaded

Counted locally with the o200k_base tokenizer, which is exact for GPT models; Claude uses its own tokenizer and its counts differ. Treat this as one consistent yardstick across the catalogue rather than a bill. Prices are per million input tokens.

ModelPer sessionOnce invoked
Fable 5.1 $0.00071 $0.02182
Opus 5.5 $0.00028 $0.00873
Sonnet 5.5 $0.00014 $0.00436
Haiku 4.5 $0.00007 $0.00218

Measured 9d ago against content hash d7d64b0b8f33, method: parsed. Prices are Anthropic first-party input rates as of 2026-10-07, from the pricing page.

Security

Grade A, and why

test-triage scanned grade A with 0 findings against 26 rules in 11 categories — prompt injection, anti-refusal, data exfiltration, privilege escalation, supply chain, agent snooping, system-prompt leakage, SSRF and excessive agency — measured 9d ago.

A static scan of the body, not an audit. Every finding is printed with the line that produced it so you can judge whether it matters here. A mod is markdown that instructs an agent; that is exactly why what it instructs is worth reading.

Nothing flagged

None of the 26 patterns this scan looks for appear in this file: no shell pipes, no recursive deletes, no credential paths, no hidden text, no instruction-override or anti-refusal phrasing, no agent-config snooping. That is not a guarantee, it is the absence of the things that are checkable.

.agents/skills/test-triage/SKILL.md · 156 lines

How it starts

The opening of the file, as written. The whole thing — 156 lines — stays where its author put it; the contents beside it link to each section on GitHub.

Test Triage

写测试前先分诊:这个测试该不该存在。通过了才谈怎么写。

一个测试的全部价值来自它的拦截力——删掉它,哪个真实 bug 会漏到用户手上?答不上来的测试拦截力为零:不要写,已经写了的删掉。

测试膨胀的根源不是测试写得不好,是没经过分诊就写下去了。

门禁

动手写 @Test 之前,先回答一句话:

删掉这个测试,哪一个真实发生过、或真实可能发生的改动,会让 bug 漏出去?

答案必须是一个具体的改动:谁改什么、怎么改坏、漏出去之后用户看到什么。答得出来 → 往下写;指不出来 → 不写。

"我想确认它是对的"不是答案。那是静态分析、类型系统、编译器的工作。

改已有测试,也要过同一道门禁

动任何一个已存在的 @Test 之前,拿同一句话再问它一遍,另外加一句:

如果这个测试今天要我从零写一遍,我还会写吗?

不会 → 删掉它,而不是改两行让它继续绿。

改测试只有两种正当理由:被测契约变了(该重写),或测试本身有缺陷(该重写)。"让它变绿"不是理由。

一票否决:看到这些,直接不写

不需要判断,也不需要"至少测一下"。

被测对象 为什么拦不住 bug 处置
data class 的字段、copy()、equals/toString 编译器已经保证 不写
常量、枚举成员、默认参数值 编译器已经保证 不写
getter / setter / 纯委托的转发方法 没有分叉点 不写
private 辅助方法的单独测试 通过 public 行为间接覆盖 不写
资源字符串、文案、提示语的措辞 文案不是行为 不写
日志有没有打、打成什么 不是行为 不写
ServiceRegistry 装配、DI 注册、构造注入 装配错了启动就崩,不用断言 不写
断言某字段"以后仍然是 null / 仍然不会被赋值" 拦的是一个尚不存在的变化 不写
断言某个已删除 / 遗留的东西不存在 拦的是过去的影子 不写
另一个测试已经完整覆盖的同一契约 两个测试守一个契约 = 只有一个 不写,删重复的那个

一票通过:这些是拦截力的来源

行为会分叉,而分叉点在静态分析里看不出来——这才是值得写的。

形态 为什么值得
状态机迁移,含非法迁移与出错后停在哪 迁移关系不在类型里
if / when 的条件分支、边界值、空集合、超长输入 分支覆盖不可静态推导
解析、序列化、编解码的畸形输入 真实数据会超出预期
权限、降级、兜底、重试路径 出错路径最容易写坏
并发、取消、顺序、重复调用的既定契约 时序不可静态推导
曾经真实回归过的点 已证实的拦截力,最高优先
ViewModel / Reducer 的状态计算 是逻辑,不是渲染

UI 的硬边界

不给 UI 写测试。 渲染、布局、点击、滚动、主题、动画、文案换行——这些都是 UI,由人工和 QA 验证,不写 @Test。这条不开放讨论。

要测的是 UI 背后的状态机:ViewModel / Reducer / Controller 里那段"输入什么、状态变成什么"的纯计算。它和 Compose 无关,只是恰好被 UI 调用。

一个测试里如果出现了 Compose 的 @Composable、createComposeRule、semantics、onNodeWithText——放错地方了,删掉。

拦截力为零的四种形态

四类都归零,原因各不相同。给它们起了名字,方便在提交和评审里直接点名。

① 回声测试

构造一个对象,再断言它等于自己刚塞进去的值。

val model = ToolSpec(name = "a", enabled = true)
assertEquals("a", model.name)

它拦的是字段改名导致的编译错误——而编译错误不需要断言兜着。唯一能让它变红的方式是改坏赋值,那时候编译器先红。

② 钉文案

断言某个 message 等于一句写死的文案。

assertEquals("接口返回为空", error.message)

文案不是行为:它进资源、换措辞、做本地化,测试就为一个字而碎,与功能正确性无关。

Read the full file on GitHub · 156 lines

Changes

What this file has done since we first saw it

Hashed on every crawl. A supply-chain change to an agent config is a question of when, not whether, so the history is kept rather than the latest state alone.

  1. 9d ago First seen · 156 lines · 71 tokens per session scan A d7d64b0b8f33

Subscribe to this mod's changes

test-triage is a skill published in the GitHub repository niki914/zafiro (263 stars, last pushed 2d ago), licensed MIT. It adds 71 tokens to every session and 2,182 once invoked, about $0.0003 per session on Opus 5.5. A static security scan graded it A with 0 findings. No closer match exists in the catalogue, so it is treated as the original; first seen 2026-10-08.