mcpField
J
justify

justify

github.com/athola测试与质量34377 次安装1 天前更新
代码仓库

关于 justify

用于审查已完成代码变更的技能,重点识别偏向新增代码的做法,并要求逐项说明理由。它还检查测试逻辑、设计不变量及变更是否有证据支持。

主要功能

  1. 01计算增量偏差分数与风险区间
  2. 02检查测试逻辑是否被修改
  3. 03评估变更的必要性与最小性
  4. 04识别设计不变量冲突
  5. 05为每项变更生成理由报告
  6. 06记录需权衡的设计决策

适用场景

  1. 01提交代码前审查实现变更
  2. 02在拉取请求前检查测试修改
  3. 03评估新增抽象或兼容层是否必要

安装

复制下面的命令,在终端中运行。

$npx skills add https://github.com/athola/claude-night-market --skill justify

安装后在 Claude Code 中输入/justify确认已加载。

详细介绍

修复问题所需的最小改动, 才是最安全、适合合并的改动。 添加代码很容易。让代码不再必要, 才是工程。

论证

添加偏差问题

AI 模型经过训练,旨在提供帮助,因此会系统性地偏向于添加代码,而不是 修复根本原因:

AI 的默认行为正确做法
添加变通方案修复根本原因
修改测试预期修复实现
新建辅助工具使用已有工具
添加错误处理防止错误发生
添加兼容性垫片删除旧代码
用 try/catch 包装修复异常来源

这项技能会审查改动是否存在这些模式, 并要求对每一项给出明确的理由。

何时使用

  • 完成实现工作后
  • 提交或创建 PR 前
  • 检查自己的改动质量时
  • scope-guard 标记为红色/黄色区域时

何时不要使用

  • 编写代码之前,因为这项技能审查的是已完成的工作(请使用 imbue:karpathy-principles)
  • 判断某个功能是否属于范围时(请使用 imbue:scope-guard)

审查流程

第 1 步:收集差异
# Determine base branch
base=$(git merge-base master HEAD 2>/dev/null \
  || git merge-base main HEAD 2>/dev/null)

# Get change statistics
git diff "$base" --stat
git diff "$base" --shortstat
git diff "$base" --diff-filter=A --name-only  # new files
git diff "$base" --diff-filter=M --name-only  # modified files
git diff "$base" --diff-filter=D --name-only  # deleted files
第 2 步:计算添加偏差分数

为每个维度打分 0-3(0 = 无偏差,3 = 偏差严重):

信号权重衡量方式
行数比例2xadditions / max(deletions, 1)
新文件2x--diff-filter=A 的计数
测试逻辑改动3x测试断言/预期差异
新抽象1x新类、函数、模块
变通方案模式2x新增的 try/catch、if/else 守卫

行数比例评分:

比例分数说明
< 2:10改动均衡
2:1 到 5:11轻微偏向添加
5:1 到 10:12很可能存在添加偏差
> 10:13添加偏差严重

汇总分数:

bias_score = sum(signal_score * weight) / sum(weights)
汇总分数区域操作
0.0 - 0.5绿色继续
0.5 - 1.5黄色逐项说明每个信号
1.5 - 2.5红色重新考虑方案
2.5+停止方案很可能不正确
第 3 步:检查是否遵守铁律

铁律指出:由测试驱动实现,而不是反过来。检查是否存在违规:

# Find test files that were modified
git diff "$base" --name-only | rg "test_|_test\.|spec\." \
  || git diff "$base" --name-only | grep -E "test_|_test\.|spec\."

# For each modified test file, check what changed
git diff "$base" -- <test_file> | rg "^[-+].*assert|^[-+].*expect|^[-+].*should"

违规模式(测试逻辑遭到篡改):

  • 断言值被修改(预期输出被改动)
  • 测试用例被删除或注释掉
  • 添加了 @skip 或 @pytest.mark.skip
  • 错误预期被放宽(使用宽泛的异常类型)
  • Mock 返回值被修改以匹配新行为
  • 测试被重命名,不再描述原有行为

每项违规都需要明确说明理由:

“我修改了这个测试断言,因为 需求发生了变化,而不是因为我的实现 无法满足原始需求。”

如果需求没有变化,测试就不应该改变。 应改为修复实现。

第 4 步:最小干预分析

对于每个改动过的文件,请回答:

  1. 这项改动有必要吗? 不修改这个文件能否实现目标?

  2. 这是最小改动吗? 能否用更少的代码行实现相同结果?

  3. 这项改动增加了还是减少了复杂度? 新函数、类或控制流都意味着增加了 需要说明理由的复杂度。

  4. 是否存在优先删减的替代方案? 能否通过删除代码来解决问题,而不是 添加代码?

步骤 4.5:不变量影响分析

改动可以很小,却仍可能造成灾难性后果, 如果它悄然改写了一个承载关键设计决策。 对于每个变更文件,检查它是否涉及设计 不变量:

不变量包括:

  • 架构模式(模块边界、分层 隔离、数据流方向)
  • 数据结构选择(为何用映射而非列表,为何 采用规范化而非反规范化)
  • API 契约(公共接口、协议格式)
  • 错误处理策略(快速失败还是恢复)
  • 并发模型(单线程假设、 Actor 模型、无共享)

检测启发式:

# Check for structural changes (new modules, moved
# boundaries, changed interfaces)
git diff "$base" --name-only | rg "(interface|abstract|base|core|types|schema|model)" \
  || git diff "$base" --name-only | grep -E "(interface|abstract|base|core|types|schema|model)"

# Check for pattern-breaking changes
git diff "$base" -U5 | rg "(TODO.*refactor|HACK|WORKAROUND|XXX)" \
  || git diff "$base" -U5 | grep -E "(TODO.*refactor|HACK|WORKAROUND|XXX)"

检测到不变量冲突时:

不要悄然自行选择解决方案。向人类呈现以下三个 选项:

选项说明适用情形
保留不添加此功能;该不变量能带来长期收益不变量简化了许多事情;功能只是锦上添花
分层叠加以不够优雅的方式在其上添加功能功能确有必要;不变量仍有价值;可以接受不完美
修订改变不变量本身新的认知确实推翻了原始决策

添加到论证报告:

### Invariant Impact: NONE / DETECTED

[If DETECTED:]
- **Invariant**: [name the design decision]
- **Conflict**: [what change clashes with it]
- **Option chosen**: Preserve / Layer / Revise
- **Justification**: [why this option, not the others]
- **Human reviewed**: YES / NO — if NO, flag as
  requiring review before merge

**风险累积警告:**糟糕的不变量决策 会不断累积。如果此分支有多项不变量 修订,应将整个分支标记为需要架构 审查。每次悄然更改不变量,都会成倍增加 代码库无法挽救的概率。

步骤 5:生成论证报告

输出一份结构化报告:

## Justification Report

**Branch**: feature/xyz
**Base**: master
**Delta**: +N/-M lines, X files changed

### Additive Bias Score: X.X (ZONE)

| Signal | Score | Detail |
|--------|-------|--------|
| Line ratio | N | +A/-D = R:1 |
| New files | N | [list] |
| Test changes | N | [list] |
| New abstractions | N | [list] |
| Workarounds | N | [list] |

### Iron Law Compliance: PASS/FAIL

[List any test logic modifications with justification]

### Change-by-Change Justification

#### file.py (+N/-M)
- **What**: [description]
- **Why**: [root cause this addresses]
- **Alternatives considered**: [what else could work]
- **Why this is minimal**: [why fewer changes won't work]

#### test_file.py (+N/-M)
- **What**: [description]
- **Justification**: [why test logic changed, if it did]
- **Iron Law status**: PASS/VIOLATION

### Risk Assessment

| Factor | Rating |
|--------|--------|
| Lines changed | LOW/MED/HIGH |
| Files touched | LOW/MED/HIGH |
| Test modifications | NONE/JUSTIFIED/VIOLATION |
| New abstractions | NONE/JUSTIFIED/UNNECESSARY |
| Overall merge risk | LOW/MED/HIGH |

### Recommendations

[List any changes that should be reconsidered,
simpler alternatives, or unnecessary additions]

决策权重

评估相互竞争的方案时,应考虑 以下因素及其权重:

因素权重理由
更少的代码行改动高风险更低,更易审查
不新增文件高不增加维护负担
不改动测试逻辑高符合铁律
修复根本原因高防止问题重现
删除代码加分缩小维护范围
增加抽象扣分仅在第 3 次使用时才有充分理由
增加错误处理中性仅在系统边界处添加

减法测试:接受任何改动前, 请问:“我能否通过删除代码而不是 添加代码来实现这一点?”如果可以,优先采用减法方案。

与工作证明的集成

Justify 通过变更级问责机制扩展工作证明:

  • proof-of-work:“是否有效?”(证据)
  • justify:“这是否是正确的做法?”(推理)

声称工作已完成前,两者都必须具备。 先运行 proof-of-work,再运行 justify。

需要标记的反模式

1. 修改测试

更改测试预期以迁就有缺陷的代码。 修复:还原测试改动,修复实现。

2. 大范围零散添加

为修复单一问题而在许多文件中添加代码。 修复:找到唯一的改动点。

3. 防御性过度设计

为实践中不可能发生的情形添加 try/catch、空值检查或验证。 修复:信任内部代码。仅在边界处进行验证。

4. 过早抽象

为单一使用场景创建辅助函数、工具类或基类。 修复:内联代码。到第 3 次使用时再抽象。

5. 兼容性垫片

添加向后兼容代码,而不是更新调用方。 修复:直接更新调用方。删除无用路径。

6. 悄然修订不变量

更改架构模式、数据结构 选择或 API 契约,却不承认 正在修订设计不变量。 修复:明确指出该不变量。向人类呈现 3 个选项 (保留、分层叠加、修订)。不要 自行作出判断:模型会倾向于训练数据的 “平均值”,而错误的不变量 决策会不断累积,最终导致代码库 无法挽救。

审查问题(来自 leyline:additive-bias-defense)

在为任何变更辩护之前,请先回答以下问题。 如果第 4 和第 5 个问题的答案不是具体证据, 则该变更没有正当理由。

  1. 优先级一致性:这是否偏离了 当前优先级?
  2. 关键性:在当前阶段实施是否至关重要?
  3. 简单性:是否存在更简单或更优雅的 解决方案?
  4. 证据:有什么证据能证明这是必需的 (而非假设)?
  5. 后果:如果不添加此项,会有什么问题?

举证责任倒置

默认立场是:这项新增内容不应存在。 必须由变更证明其必要性,而不是由审查者证明它没有必要。

生成论证报告(步骤 5)时,添加一个 Burden of Proof 部分:

变更审查问题 4 的答案审查问题 5 的答案结论
file.py[证据][后果]有正当理由/需要证据/没有正当理由

结论为 unjustified 的变更必须在报告通过前删除或返工。

记录权衡(决策日志)

当此步骤对存在实际备选方案的决策作出定论时,应趁推理过程仍在进行,将其记录到 docs/tradeoffs.md(起草并确认):

  • 如果已安装 leyline,调用 Skill(leyline:decision-journal) 并附加 一条权衡记录(包含决策、权衡过的选项以及作出的牺牲;将 phase 设为 review)。展示草稿;确认后再附加。
  • 备选方案(未安装 leyline):使用文件内的 ENTRY TEMPLATE,向 docs/tradeoffs.md 追加记录;分配下一个 TR-NNN ID。

明智的忠告

你正在做的事情是否偏离了你的优先事项? 在当前阶段实施是否至关重要? 少依赖 AI 和最初的思路。 挑战自己,做得更好,思考更优雅的实现方式或更简单的解决方案。

退出标准

  • 已计算加性偏差分数,并报告其所在区间(GREEN/YELLOW/RED/STOP)。
  • 铁律合规性标记为 PASS 或 FAIL;如修改了测试逻辑,须说明理由。
  • 每项变更都有一个结论(justified、needs_evidence 或 unjustified);最终报告中不得保留任何 unjustified 结论。
  • 如检测到不变量冲突,须明确指出,并给出所选方案及人工审查标记。
  • 报告通过前,须将有正当理由的非平凡新增内容记录到 docs/tradeoffs.md(或文件内模板)。

相关技能

  • imbue:karpathy-principles - “Surgical Changes”和 “Goal-Driven Execution”原则会从更高层次的综合视角调用此审计
  • leyline:additive-bias-defense - 本审计详细落实的约定
  • imbue:proof-of-work - 本审计的补充验证层(proof-of-work 会询问“是否奏效?”, justify 会询问“是否有必要存在?”)
  • 完整的关卡技能联邦图请参阅 docs/quality-gates.md#skill-level-quality-gate-composition

评论

支持 Markdown