关于 hard-cheese
hard-cheese 是代码评审前的理解检查技能,要求作者解释改动,并按 SOLO 分数门槛评估。它将尝试记录在本地审计文件中,可独立运行或接入 `/plate --hard` 流程。
主要功能
- 01评审前检查改动理解
- 02SOLO 评分并限制重试次数
- 03按差异排序区域引导提问
- 04本地追加式记录尝试
- 05日志模式可跳过评审判定
适用场景
- 01提交拉取请求前检查改动理解
- 02评审判定不可用时记录解释
安装
复制下面的命令,在终端中运行。
npx skills add https:/ / github.com/ paulnsorensen/ easy-cheese --skill hard-cheese安装后在 Claude Code 中输入/hard-cheese确认已加载。
包含的文件
除 SKILL.md 外,安装时一起下载的参考资料和脚本。
wedge.tomlreferences/commands.mdcomposition.mdjudge-prompt.md详细介绍
/hard-cheese
此关卡可减少认知债务。当代码通过检查,但作者无法解释代码时,就存在这种债务。
输入
/hard-cheese [<slug>] [--socratic-cap N=3] [--passing-score N=3] [--no-judge]
参数:
<slug>用于标识.cheese/hard-cheese/<slug>.md中的制品。此参数为可选项。若未提供,则使用HEAD的短 SHA。显式指定的 slug 优先于 SHA。--socratic-cap N用于设置最大重试次数。达到上限后,关卡会将制品标记为FAILED,并返回非零状态。默认值为3。Vibecheck 没有上限,但 easy-cheese 可防止无限循环。--passing-score N用于设置 PASS 所需的最低 SOLO 分数。取值范围为1到5。默认值为3。如果之前的 PASS 分数低于此值,关卡会将其视为过期。--no-judge用于启用仅记录模式。将用户的解释记录为status: LOGGED。不要启动 judge 子 Agent。此模式相当于 vibecheck 中可选的 JSONL 遥测模式在 easy-cheese 中的对应模式。它会保留更多内容。请参阅## 与论文的差异。
调用模式
| 模式 | 关卡的运行方式 | 关卡所在位置 |
|---|---|---|
| standalone | 用户在发起拉取请求前运行 /hard-cheese <slug>。 | 位于流水线之外。无需上游技能。 |
| propagated | /plate --hard 在最终写入后、发布前运行 /hard-cheese <slug>。 | 位于已验证制品与供评审者审阅的制品之间的边界。 |
--hard 会沿着 /cheese → /mold → /cook (⇄ /press) → /age → /cure → /plate 传递。只有 /plate 会运行 /hard-cheese。
有关可移植性要求,请参阅 ../cheese/references/harness-portability.md。其中涵盖辅助程序解析、子 Agent 调度、GitHub 操作和交接转换。
请优先使用 bundle 或仓库辅助程序。仅将 ${CLAUDE_SKILL_DIR} 用作可选的宿主回退方案。
交接块定义了可移植契约,因为斜杠命令只是宿主呈现形式,并非控制模型。
流程
-
确定范围。
- 将
diff_base设为origin/main,将diff_head设为<short-sha of HEAD>。 - 如果
.cheese/specs/<slug>.md存在,则将其加载为可选的意图参考。差异仍是事实依据。 - 如果没有 slug,则使用
HEAD的短 SHA。 - 如果与
origin/main相比没有差异,则返回0,并输出"nothing to gate on"。不要写入产物。
- 将
-
新鲜度检查。 运行 gate 前,先运行新鲜度检查:
python3 skills/hard-cheese/scripts/hard-cheese.pyz freshness-check \ --slug <slug> --passing-score <n>此命令会输出一个 JSON 对象,并且在所有状态下都以
0退出。读取其state字段。 对于previously_passed,输出"previously passed"并停止。若状态为stale或new,则继续执行第 3 步。 非零退出状态表示输入错误;其 stderr 行是包含error和exit_code的 JSON。 当HEAD发生变化或上次 PASS 的分数过低时,结果为 stale。 -
排列代码块的优先级,然后编写 vibecheck 提示词。 忠实遵循 Sankaranarayanan 2026。使用“share for review”,使 gate 实现保持独立。
编写提示词前,先运行
rank-hunks:python3 skills/hard-cheese/scripts/hard-cheese.pyz rank-hunks \ --base origin/main --head HEAD将排名后的区域与差异摘要并列展示,每个代码块一行,格式为
path:start-end — reasons。将所有排名区域中的变更行放入 80 行差异摘要,再添加其他上下文。首次尝试前不得调用 judge。在分享以供审查之前,请用你自己的话解释这项变更的用途。 是如何工作的?为什么它能产生预期行为?它依赖哪些状态、控制流或不变量?从突出显示的区域开始。
随提示词一起展示差异摘要。对于
/plate,还要展示完整的最终证据:- 最终产物清单,
- 每条
{target, backend, verified}完成记录, - 已跟踪产物的差异,
- 质量 gate 结果。
如果
/plate缺少以上四项中的任意一项,则以非零状态停止。如果某条完成记录的verified: false,则以非零状态停止。 -
记录用户的解释,以自由文本形式保存。不要提供指导或示例答案。该解释就是受测试的产物。
-
在全新上下文中启动 judge 子 Agent。 使用与
/cook粉丝路径相同的模式。- 使用
references/judge-prompt.md作为系统提示词。 - 提供通过分数、差异摘要、可选的规范摘录、
rank-hunks输出的targetsJSON,以及用户的解释。 - 要求返回此 JSON 对象:
{score, level, pass, feedback, socratic_qs, targets_addressed}。
完整的系统提示词和输出格式请参阅
references/judge-prompt.md。用户设置
--no-judge时跳过此步骤。将该次尝试标记为status: LOGGED,写入产物,并返回0。 - 使用
-
处理 judge 结果。
- 当
score >= <passing-score>时,将该次尝试标记为 PASS。 - 当
score < <passing-score>时,将该次尝试标记为 FAIL。展示苏格拉底式问题;至少一个问题须锚定到targets_addressed中的排名代码块。当targets为空或不存在时,跳过锚定要求,并要求targets_addressed为空。若仍有重试次数,则返回第 4 步。 - judge 失败时,将该次尝试标记为 ERROR。输出警告并返回
0。请参阅## 与论文的差异。
追加该次尝试的记录行:
python3 skills/hard-cheese/scripts/hard-cheese.pyz append-attempt \ --slug <slug> --status <PASS|FAIL|ERROR> --score <n> \ --feedback "<judge feedback>" --explanation "<user explanation>" - 当
-
处理次数耗尽。 将产物
status设为FAILED。输出产物路径并返回非零状态。停止后续链。
产物
.cheese/hard-cheese/<slug>.md 包含审计记录。.gitignore 文件会排除 .cheese/,因此审计记录仅保留在本地。
每个文件都以此 YAML frontmatter 代码块开头:
---
slug: <slug>
attribution: Sankaranarayanan 2026 / vibecheck
rubric: SOLO Taxonomy (1-5), pass threshold = <passing-score>
passing_score: <n>
divergence: fail-open on judge error (vibecheck fails closed)
diff_base: <sha>
diff_head: <short-sha>
status: PASS | FAIL | FAILED | LOGGED | ERROR
attempts: <n>
---
append-attempt 会将尝试日志写入此六列 Markdown 表格:
| timestamp | head_sha | status | score | feedback | explanation |
| --- | --- | --- | --- | --- | --- |
| 2026-06-25T10:00:00+00:00 | a1b2c3d | FAIL | 2 | "Unistructural: lists steps but no causal link" | <user explanation verbatim> |
| 2026-06-25T10:05:00+00:00 | a1b2c3d | PASS | 4 | "Relational: explains why invariant holds" | <user explanation verbatim> |
每次调用都会追加尝试记录,不会覆盖现有行。如果 HEAD 发生变化,则在之前的行下方追加新行。
子 Agent 契约 — 独立评审
- 每次调用都使用全新上下文。 编写代码的上下文可能会影响评审判断。
- 使用共享 Agent 解析器,以
powerful功能等级和high工作强度解析一个无工具或只读的reviewer。 - 共享解析器会将每位评审者固定为
powerful。不要为评审判断降低此值。 - 仅在强制禁止写入时使用通用工作者。设置
degraded: true。 - 使用
references/judge-prompt.md作为系统提示词。 - 向评审者提供差异摘要、可选的规范摘录、
targetsJSON 和说明。要求以 JSON 回复。禁止写入代码库。 - 解析 JSON 输出。 如果解析失败,记录一次
ERROR尝试,并采用开放失败策略。
此门禁需要宿主提供子 Agent 功能。若没有此功能,建议使用 /hard-cheese --no-judge,记录说明但不评分。
归属说明
Sankaranarayanan, S. (2026). Mitigating 'Epistemic Debt' in Generative AI-Scaffolded Novice Programming using Metacognitive Scripts. Proceedings of the 13th ACM Conference on Learning at Scale. https://arxiv.org/abs/2602.20206
此实现使用了论文作者的开源 VS Code 扩展:
https://github.com/sreecharansankaranarayanan/vibecheck
此 SKILL.md、references/judge-prompt.md 和每个产物都包含归属说明。因此,引用会保留在审计轨迹中。
与论文的差异
Hard-cheese 与 vibecheck 有三处差异:
1. 评审错误。 Vibecheck 遇到错误时会采用封闭失败策略。模态窗口会阻止应用代码,直到评审者恢复或用户重试。
Hard-cheese 遇到错误时会采用开放失败策略。门禁会记录 ERROR、打印警告并返回 0。
此策略可避免 API 故障阻塞拉取请求工作。
2. 遥测内容。 Vibecheck 会记录说明的长度,但从不记录说明文本。
Hard-cheese 会在本地产物中记录每条说明的完整文本。.gitignore 文件会排除 .cheese/,因此这些文本会保留在作者的计算机上。
在 --no-judge 记录第一条说明之前,告知用户此保留行为。
3. 提示词措辞。 Vibecheck 的提示词会直接列出三个问题,没有引导句。
Hard-cheese 会增加一句目的优先的引导语,并指向排名区域。论文中的三个问题保持原文不变。
每出现一处新差异,都将其添加到本节。
与 --auto 配合使用
--hard 和 --auto 可以同时运行。终端模式下,/plate --hard 会在发布前暂停一次自动化,此时 /plate 已验证最终产物。
用户回应提示。PASS 允许发布。FAILED 会停止发布。ERROR 使用文档所述的开放失败行为。
仅提交模式下的 /plate --hard 不会运行门禁。该路径不共享任何内容。有关新拉取请求和非 TTY 行为,请参阅 references/composition.md。
输出
门禁结束时,打印:
Hard-cheese artifact: .cheese/hard-cheese/<slug>.md
Status: PASS | FAILED | LOGGED | ERROR
Score: <n>/5 (<SOLO level>, pass ≥ <passing-score>)
Attempts: <n>
Score 行报告最近一次经评审的尝试。对于 LOGGED 模式,或没有评分尝试的 ERROR,省略此行。
然后打印一条适用的消息:
- PASS 时:
Ready to share for review. - FAILED 时:
Cap exhausted. Improve understanding of the change before sharing. - LOGGED 时:
Telemetry only — judge skipped via --no-judge. - ERROR 时:打印一条指出故障原因的警告。包含
Fail-open divergence active — gate exited 0; you may share for review at your discretion.
首选工具和备用方案
| 需求 | 首选 | 备用方案 |
|---|---|---|
| 检查面向用户的摘要中的差异 | delta | git diff --unified=3 |
| 为提示词中的代码块排序 | rank-hunks 捆绑命令 | 无 — 跳过已排序的区域,并说明这一缺口 |
| 阅读规范(如果存在) | 按 code-intelligence-routing.md 有界读取文件 | 主机文件读取 |
| 启动评审 Agent | 主机子 Agent 原语(Agent() 或等效的运行框架功能) | 无 — 如果无法启动子 Agent,则运行 --no-judge 模式,并告知用户评审不可用 |
| GitHub / PR 上下文(此处不在范围内) | 不适用 | 不适用 |
规则
- 在全新上下文中运行评审子 Agent。不要使用编写代码时的上下文来评估作者的理解。
- 回答前不要指导用户。说明本身就是待测试的对象。
- 只有在评审结果为 FAIL 后才展示评审提出的苏格拉底式问题。不要添加提示。
- 展示已排序的区域;首次尝试前不要提出问题或给出提示。
- 原样将用户的说明传给评审。
- 始终运行新鲜度检查。
HEAD发生变化时,必须重新开始一轮尝试。 - 记录每次 ERROR 尝试。每次评审失败都要显示警告。
- 不要调用 GitHub 工具或拉取请求工具。此门禁在代码进入评审前运行。
- 应用
../age/references/voice.md中的共享表达规范。报告结果。将残余风险分类为certain | speculating | don't know。 - 不要将 FAILED 描述为“差一点就通过”。
参考资料
references/judge-prompt.md定义 SOLO 分类法评分标准、评审提示词和 JSON 输出。references/composition.md定义完整的--hard和--auto矩阵。references/commands.md列出了生成的捆绑命令。
Agent 解析
通过 ../cheese/references/agent-resolution.md 解析全新的评审 Agent。
| 工作 | 首选类型 | 权限/隔离 | 最低能力 | 工作量 | 备用方案 |
|---|---|---|---|---|---|
| 评估说明 | reviewer | 无工具或只读,使用全新上下文 | 强大 | 高 | 兼容的 reviewer,然后是通用类型 |
规范的 hard-cheese 审计包含共享的 agent_resolution 区块。