mutation-adequacy
Compare original and translation side by side
🇺🇸
Original
English🇨🇳
Translation
ChineseMutation Adequacy Skill
Mutation Adequacy技能
Overview
概述
The review dimension is the adequacy backstop for the relaxed verification
mix (verification ladder slice 3, R5). When the planner ships the cheaper testing strategy — strict
types + inline invariants + one PBT + one acceptance test instead of granular per-behavior red-green
— mutation adequacy is the machine guard against the vacuous tests (and vacuous PBT properties) that
omission could otherwise admit. It scores whether the test suite actually kills injected mutants:
the strongest signal that tests fail for the right reason.
mutation-adequacyThis dimension gates the HIGH risk tier only, at the boundary only — it is the
review-phase counterpart to the delegation-time (R3) gate. The coupling to the
high tier is policy data in (the dimension name = this skill's folder name); you
never decide tier membership in this skill. The gate is registered as a required D1 review
dimension () — a structural
participation fact, distinct from severity (below).
/reviewcheck_test_adequacyreview-contract.tsadaptLadderGate(MUTATION_GATE_NAME, 'D1', handleMutationAdequacy)Two orthogonal axes, two default severities. The mutation score stays advisory by default: a
sub-threshold surfaces survivor follow-ups and warns, but does not block, unless an
explicit config override raises its severity. A 100% score is
neither expected nor required (equivalent mutants exist).
mutationScorereview.gates['mutation-adequacy']The NoCoverage axis is a second, independent check DR-6 added, with its own real, functioning
enforcement path: under , the block-mode guard
( Check 4b) fails the transition whenever the diff-scoped
count exceeds the configured budget (default 0 — zero uncovered
changed lines tolerated), independent of the score. This is live code, not a deferred plan — but it is
opt-in, the same way the score's severity is: defaults to , and
's per-gate severity default is deliberately advisory too (so a project's
dimension-level defaults never silently re-block a demoted gate). A project flips NoCoverage
enforcement on with one config line (); honor whichever way it's
resolved, never hardcode "advisory" when recording this dimension's result.
review.mutationEnforcement: blockworkflow/guards.tsreview → synthesizenoCoveragemaxNoCoveragereview.mutationEnforcementadvisorymutation-adequacyreview.mutation-enforcement: blockThe CI side is separate and narrower: a diff-scoped mutation gate runs on pull-request events, but it
runs in observe mode unconditionally — it logs its verdict and always exits 0, regardless of any
setting. It is not yet a blocking CI backstop; the flip is deferred, pending a clean
runner verdict on the full server suite. Never represent the CI gate as a merge blocker — where
NoCoverage enforcement is live, it is on the review path above, not in CI.
.exarchos.ymlNote: advisory (where it applies) refers to whether a sub-threshold score or an over-budget
NoCoverage count actually stops the transition. The dimension entry is required on the high tier
regardless of either axis's resolved severity (the guard fails if the
review is absent), so run and record it every time.
all-reviews-passedmutation-adequacymutation-adequacy该维度仅针对高风险层级生效,且仅在**节点触发——它是评审阶段对应委托阶段(R3)检查门的机制。与高风险层级的关联是中的策略数据(维度名称等于本技能的文件夹名称);本技能不负责判定层级归属。该检查门被注册为必填的D1**评审维度()——这是结构参与属性,与下文的严重程度无关。
/reviewcheck_test_adequacyreview-contract.tsadaptLadderGate(MUTATION_GATE_NAME, 'D1', handleMutationAdequacy)两个独立维度,两种默认严重程度。变异分数默认仅作为参考:低于阈值的会显示存活变异体的后续任务并发出警告,但不会阻塞流程,除非通过显式的配置覆盖提升其严重程度。100%的分数既非预期也非强制要求(存在等效变异体)。
mutationScorereview.gates['mutation-adequacy']NoCoverage维度是DR-6新增的第二个独立检查项,拥有独立的可生效执行路径:当设为时,阻塞模式防护(检查项4b)会在差异范围的计数超过配置的预算(默认0——不允许存在未覆盖的变更行)时,阻止的流程转换,与分数无关。这是已生效的代码,而非延迟规划——但它是可选启用的,与分数的严重程度设置方式相同:默认值为,且检查门的默认严重程度也特意设为参考级(因此项目的维度级默认设置不会静默重新启用已降级的检查门)。项目只需一行配置即可启用NoCoverage的阻塞模式();无论配置如何,都需严格遵循,记录该维度结果时切勿硬编码为“参考级”。
review.mutationEnforcementblockworkflow/guards.tsnoCoveragemaxNoCoveragereview → synthesizereview.mutationEnforcementadvisorymutation-adequacyreview.mutation-enforcement: blockCI侧的实现是独立且范围更窄的:差异范围的变异检查门会在拉取请求事件中运行,但它无条件以观察模式运行——会记录验证结果但始终返回0退出码,与的设置无关。目前它还不是阻塞性的CI保障机制;切换为阻塞模式的计划已推迟,需等待完整服务器套件的运行器验证结果无误后再执行。切勿将CI检查门描述为合并阻塞项——NoCoverage的阻塞模式生效于上文的评审流程,而非CI流程。
.exarchos.yml注意:参考级(适用时)指的是低于阈值的分数或超出预算的NoCoverage计数是否会实际阻止流程转换。无论两个维度的最终严重程度如何,高风险层级都必须包含该评审维度(如果缺少评审,防护会判定失败),因此每次都需运行并记录该维度。
mutation-adequacyall-reviews-passedTriggers
触发条件
Activate this skill when:
- reaches the quality stage on a HIGH-tier feature
review - The review contract lists in the required reviews for this workflow
mutation-adequacy - You need to assess whether the (possibly relaxed) test mix actually kills mutants
Do not activate for medium/low-tier work, or outside the boundary — those paths do not
require this dimension.
/review在以下情况激活本技能:
- 针对高风险层级功能的流程进入质量阶段
review - 评审合约中列出作为该工作流的必填评审项
mutation-adequacy - 需要评估(可能已简化的)测试组合是否真正杀死变异体
请勿为中/低风险层级的工作或节点之外的流程激活本技能——这些路径不需要该维度。
/reviewExecution
执行步骤
Step 1: Run the diff-scoped mutation gate
步骤1:运行差异范围的变异检查门
Invoke the action against the review/PR base ref. It runs the resolved mutation command
diff-scoped (Stryker , cargo-mutants , mutmut path restriction — resolved from
the toolchains SoT, never composed by hand), so the run completes in , not the full-tree
time budget.
--since--in-diff< minutestypescript
exarchos:exarchos_orchestrate({
action: "mutation-adequacy",
featureId: "<featureId>",
base: "<review/PR base ref>", // e.g. "main" — reuse the same base the review diff uses
worktreePath: "<optional worktree>", // 'auto' resolves the calling delegation's worktree
operationId: "<optional idempotency key>"
// scope defaults to "diff"; do NOT pass scope:"full" here (see Anti-Patterns)
})The action emits / (liveness, INV-10) and a foldable
carrying (INV-1) automatically. Do not hand-emit these events.
mutation.executing_startedmutation.executedgate.executedmutationScore针对评审/PR的基准引用调用该动作。它会运行解析后的变异命令(差异范围:Stryker的、cargo-mutants的、mutmut的路径限制——从工具链的可信源解析,切勿手动组合),因此运行时间仅需数分钟,而非全代码树测试的耗时。
--since--in-difftypescript
exarchos:exarchos_orchestrate({
action: "mutation-adequacy",
featureId: "<featureId>",
base: "<review/PR base ref>", // 例如 "main" — 复用评审差异使用的同一基准
worktreePath: "<optional worktree>", // 'auto'会解析调用委托的工作树
operationId: "<optional idempotency key>"
// scope默认值为"diff"; 请勿在此处传递scope:"full"(参见反模式)
})该动作会自动发送 / (活跃度追踪,INV-10)以及包含的可折叠事件(INV-1)。请勿手动发送这些事件。
mutation.executing_startedmutation.executedmutationScoregate.executedStep 2: Read the carrier
步骤2:读取载体数据
The action returns the fixed carrier (). The shape is stable regardless of pass/fail/degrade:
data| Field | Meaning |
|---|---|
| |
| |
| mutants a test caught (good) |
| mutants that escaped — tests ran but did not catch them |
| mutants in code no test exercises at all |
| total mutants generated within the diff scope |
| the effective advisory threshold (override > config > soft default) |
| the parsed Stryker |
| "write a test that kills |
Degrade signals to recognize (each returns so the gate never blocks closed-with-error):
passed: true- +
skipped: true— no mutation runner resolved. Report the remediation; do not treat as a failure.reason - + a
warningentry — the runner produced no parseable report. Note it; do not throw.warnings[] - +
deferred: true— you (incorrectly) requested full scope; re-run with the default diff scope.scope: 'full'
See for the full carrier and report shape.
references/reading-the-carrier.md该动作返回固定格式的载体数据()。无论通过/失败/降级,格式保持稳定:
data| 字段 | 含义 |
|---|---|
| |
| |
| 被测试捕获的变异体(符合预期) |
| 逃逸的变异体 — 测试已运行但未捕获它们 |
| 位于完全未被测试覆盖的代码中的变异体 |
| 在差异范围内生成的变异体总数 |
| 实际生效的参考阈值(覆盖配置 > 默认配置 > 软默认值) |
| 解析后的Stryker |
| “编写测试以杀死 |
需要识别的降级信号(均返回,因此检查门不会因错误阻塞流程):
passed: true- +
skipped: true— 未解析到变异运行器。报告修复建议;勿视为失败。reason - +
warning条目 — 运行器未生成可解析的报告。记录该情况;勿抛出异常。warnings[] - +
deferred: true— 错误请求了全范围;使用默认的差异范围重新运行。scope: 'full'
完整的载体数据和报告格式请参见。
references/reading-the-carrier.mdStep 3: Turn survivors into kill-this-mutant follow-ups (INV-12)
步骤3:将存活变异体转化为“杀死该变异体”的后续任务(INV-12)
The action already maps each surviving and mutant to a entry of the form
"write a test that kills ". Surface these as concrete, actionable review findings —
each one names a specific assertion the suite is missing:
NoCoveragenext_actions<file>:<line>- A survived mutant means a test exercises that line but asserts nothing strong enough to detect the mutation. The follow-up: add an assertion that distinguishes the mutated behavior.
- A NoCoverage mutant means no test touches that line at all. The follow-up: add a test that exercises it, then assert on the observable behavior.
Record these as with so they ride the same review-report contract
as the other dimensions. Do not invent generic "improve coverage" advice — quote the file:line the
action surfaced.
issuescategory: "test-quality"该动作已将每个存活和变异体映射为中的条目,格式为**“编写测试以杀死”**。将这些内容作为具体、可执行的评审结果呈现——每个条目都指出了测试套件缺失的特定断言:
NoCoveragenext_actions<file>:<line>- 存活变异体表示测试覆盖了该行代码,但未添加足够强的断言以检测变异。后续任务:添加可区分变异后行为的断言。
- NoCoverage变异体表示完全没有测试触及该行代码。后续任务:添加覆盖该行的测试,然后针对可观察行为添加断言。
将这些内容记录为的,使其与其他维度遵循相同的评审报告合约。请勿给出“提升覆盖率”这类通用建议——直接引用动作返回的信息。
category: "test-quality"issues<file>:<line>Step 4: Apply the verdict — two axes, each with its own resolved severity
步骤4:应用验证结果——两个维度,各有独立的最终严重程度
The score axis stays advisory (warning) by default. A sub-threshold :
mutationScore- surfaces the survivor follow-ups (Step 3),
- warns in the review report,
- does not block the transition — unless an explicit
review → synthesizeconfig override raises its severity. Honor the resolved severity, do not hardcode it. Seereview.gates['mutation-adequacy']for why the default is a soft threshold and how to calibrate it from the score trend.references/advisory-threshold.md
The NoCoverage axis is independent, with its own real block-mode enforcement path: under
, if the folded count exceeds the configured
budget (default 0), the block-mode guard fails the transition regardless of the score.
Like the score, it is opt-in ( defaults to ) — resolve and honor
the actual configured mode, don't assume either axis is on or off. Record both axes honestly in the
review report — do not fold a blocking NoCoverage failure into advisory-score language, and do not
describe either axis as enforced by CI (the diff-scoped CI wiring runs in observe mode; see
Anti-Patterns).
review.mutationEnforcement: blocknoCoveragemaxNoCoveragereview.mutationEnforcementadvisory分数维度默认是参考级(警告)。低于阈值的:
mutationScore- 显示存活变异体的后续任务(步骤3),
- 在评审报告中发出警告,
- 不会阻塞的流程转换——除非通过显式的
review → synthesize配置覆盖提升其严重程度。遵循最终生效的严重程度,切勿硬编码。关于默认阈值为何是软默认值以及如何根据分数趋势校准阈值,请参见review.gates['mutation-adequacy']。references/advisory-threshold.md
NoCoverage维度是独立的,拥有自己的阻塞模式执行路径:当设为时,如果汇总的计数超过配置的预算(默认0),无论分数如何,阻塞模式防护都会阻止流程转换。与分数一样,它是可选启用的(默认值为)——解析并遵循实际配置的模式,勿假设任一维度是启用或禁用状态。在评审报告中如实记录两个维度的结果——勿将阻塞性的NoCoverage失败转化为参考级分数的表述,也勿描述任一维度由CI强制执行(差异范围的CI流程以观察模式运行;参见反模式)。
review.mutationEnforcementblocknoCoveragemaxNoCoveragereview.mutationEnforcementadvisoryRequired Output Format
要求的输出格式
Record the dimension result on the review state. The review key MUST be the kebab-case dimension name
(it equals this skill's folder name):
typescript
exarchos:exarchos_workflow({ action: "update", featureId: "<id>", updates: {
reviews: { "mutation-adequacy": {
status: "pass", // "pass" is honest when both axes are advisory (the default); if either
// axis's severity is configured to block, report the real result instead
summary: "mutationScore 0.62 (threshold 0.40); 3 survivors surfaced as kill-test follow-ups",
issues: [
{ severity: "MEDIUM", category: "test-quality", file: "src/foo.ts", line: 42,
description: "surviving mutant — no assertion distinguishes the mutated branch",
required_fix: "write a test that kills src/foo.ts:42" }
]
} }
}})A passing-value (, case-insensitive) is required
for the guard — a flat string is silently ignored and blocks the transition.
statuspass | passed | approved | fixes-appliedall-reviews-passed在评审状态中记录维度结果。评审键必须为短横线格式的维度名称(与本技能的文件夹名称一致):
typescript
exarchos:exarchos_workflow({ action: "update", featureId: "<id>", updates: {
reviews: { "mutation-adequacy": {
status: "pass", // 当两个维度均为参考级(默认设置)时,"pass"是如实记录;如果任一
// 维度的严重程度被配置为阻塞,则需报告实际结果
summary: "mutationScore 0.62(阈值0.40);已将3个存活变异体转化为杀死测试的后续任务",
issues: [
{ severity: "MEDIUM", category: "test-quality", file: "src/foo.ts", line: 42,
description: "存活变异体——无断言可区分变异后的分支",
required_fix: "编写测试以杀死src/foo.ts:42" }
]
} }
}})all-reviews-passedpass | passed | approved | fixes-appliedAnti-Patterns
反模式
| Don't | Do Instead |
|---|---|
Run | Full-tree mutation is the long-running op deferred to R10/v2.12 — it returns a deferred advisory, never an inline run |
Compose | Let the action resolve the diff scope from the toolchains SoT |
| Block the merge on a sub-threshold score with no config override | The score axis is advisory by default — surface follow-ups, honor the resolved severity |
| Assume NoCoverage is always advisory, or always blocking | It has its own real block-mode path ( |
| Claim the CI mutation gate blocks merges | It runs diff-scoped in observe mode unconditionally (logs its verdict, always exits 0, regardless of config) — never represent it as a merge blocker |
| Treat a Skipped/Warning carrier as a hard failure | Both return |
| Run this dimension for medium/low tier | It gates the HIGH tier at the |
Emit | The action auto-emits liveness + the foldable gate event |
| Give generic "add more tests" advice | Quote the |
| 禁止操作 | 正确做法 |
|---|---|
内联运行 | 全代码树变异测试是推迟至R10/v2.12版本的长时操作——它会返回延迟的参考结果,而非内联运行 |
手动组合 | 让动作从工具链的可信源解析差异范围 |
| 在无配置覆盖的情况下,因分数低于阈值而阻塞合并 | 分数维度默认是参考级——显示后续任务,遵循最终生效的严重程度 |
| 假设NoCoverage始终是参考级或始终是阻塞级 | 它拥有独立的阻塞模式路径( |
| 声称CI变异检查门会阻塞合并 | 它无条件以观察模式运行差异范围测试(记录验证结果,始终返回0退出码,与配置无关)——切勿将其描述为合并阻塞项 |
| 将Skipped/Warning载体数据视为严重失败 | 两者均返回 |
| 为中/低风险层级运行该维度 | 它仅在 |
手动发送 | 动作会自动发送活跃度事件和可折叠的检查门事件 |
| 给出“添加更多测试”这类通用建议 | 引用动作在 |
References
参考资料
- — reading the carrier and the Stryker
references/reading-the-carrier.md.mutation-testing-report-schema - — why the threshold is a soft default, and how to calibrate it.
references/advisory-threshold.md
- — 读取载体数据和Stryker
references/reading-the-carrier.md报告。mutation-testing-report-schema - — 为何阈值是软默认值,以及如何校准阈值。
references/advisory-threshold.md