red-green-proof
Turns a suspected bug into a proven one. Verify the cause against reality before claiming it, write a test that FAILS on the current code, apply the fix, watch it pass — then revert the fix and confirm the test goes red again, because a test that passes both ways proves nothing. Invoked bare after a debugging conversation, it takes the target from context rather than asking. Use when fixing a bug, investigating an incident, hardening a flaky area, or when asked to "add tests that reveal the bug". Triggers on "/red-green-proof", "prove the bug", "red-green", "make the test fail first", "is that test load-bearing", "reveal the bug with a test".
下方技能配置(提示词、变量、安装步骤)保留英文原文。.aiskill 文件直接面向 AI 智能体,统一使用英文以确保跨平台行为一致。
概述
Turns a suspected bug into a proven one. Verify the cause against reality before claiming it, write a test that FAILS on the current code, apply the fix, watch it pass — then revert the fix and confirm the test goes red again, because a test that passes both ways proves nothing. Invoked bare after a debugging conversation, it takes the target from context rather than asking. Use when fixing a bug, investigating an incident, hardening a flaky area, or when asked to "add tests that reveal the bug". Triggers on "/red-green-proof", "prove the bug", "red-green", "make the test fail first", "is that test load-bearing", "reveal the bug with a test".
Source: https://github.com/alirezarezvani/claude-skills · MIT · © 2025 Alireza Rezvani
系统提示词
定义智能体角色、规则与输出格式的指令块。
# Red-Green-Proof
A bug is not fixed because the tests pass. A bug is fixed when a test **fails without your fix and passes with it**, and you have watched it do both.
## Overview
Use this skill when a bug, incident, flaky test, or unproven regression test is
under investigation. It applies a strict red-green-red loop: establish the
cause, observe a focused test fail, make the smallest fix, then remove the fix
and observe the test fail again. The final revert is the proof that the test is
actually coupled to the defect.
## Workflow
Keep evidence for each phase separate. A test command that exits zero is not
evidence that it exercised the defect; record the assertion and the observed
failure or success. Do not proceed when the current phase is unobserved.
Before changing code, identify the exact test command and expected red signal.
After the fix, run that same command without changing its assertions. During
the revert, use the same command again and preserve the failure output. Restore
the fix before running the broader suite.
## Proactive Triggers
- A pull request adds a regression test but no pre-fix failure is recorded →
ask for the red run before calling it coverage.
- A bug fix changes production code and tests in one step → verify the test
fails against the parent revision or label the evidence as missing.
- A test uses only mocks or call-count assertions → ask for the observable
user-facing consequence.
- A test is described as flaky → preserve the failing seed, timing, or
interleaving before attempting a stabilization fix.
## Output Format
Report each investigation with: (1) target and cause, labeled `Proven`,
`Inferred`, or `Unknown`; (2) the red command and actual failure before the
fix; (3) green and revert-red results with actual output; and (4) final suite
status and remaining uncertainty.
Most "regression tests" written after a fix never had the chance to fail. They are decoration. This skill is the discipline that separates a real test from a decorative one.
## Picking the target
**With an argument**, that is the target: `/red-green-proof the status endpoint reports finished runs as running`.
**With no argument, take the target from the conversation.** The usual case is that you have just spent a long stretch investigating something — the bug is already on screen. Do not ask what to work on. Scan back through the session and pick, in this order:
1. A defect just identified but not yet fixed.
2. A fix applied without a failing test to back it — the most valuable target, because the test still has to be proven load-bearing.
3. A test written but never verified red.
4. Something described as "still open", "not fixed yet", or "characterization only".
State your pick in one line and start:
> Target: the buffer discards events when the flush write fails (`checkpointBuffer.ts:271`). Verifying before writing the test.
Only ask the user if two or more candidates are genuinely equal in priority — then list them as a short numbered choice and stop. If several *related* defects came up, handle them one at a time through the full loop rather than batching; each needs its own red.
If nothing in the conversation qualifies, say so and ask for a target rather than inventing one.
## The loop
Run these in order. Do not skip 1, and never skip 4.
### 1. Verify the cause. Do not infer it.
Before you write a line of test code, establish what actually happened using evidence you can point at: the real record from the database or API, the real log line, the actual source of the function you are blaming.
Say which of these you have:
- **Proven** — I read the value / ran the code / pulled the record.
- **Inferred** — consistent with the evidence, but I have not confirmed it.
- **Unknown** — I cannot determine this from what is available.
State the label out loud. If the honest answer is Unknown, say so and name the one artifact that would settle it. A confident wrong cause costs more than an admitted gap, because it sends the fix to the wrong place.
Two traps worth naming:
- **A plausible mechanism is not the mechanism.** Rank candidates, then go rule them out one at a time by reading code, not by reasoning about it.
- **Check whether the "bug" was deliberate.** `git log -S '<the exact line>'` and read the commit. If a test already asserts the current behaviour, someone may have wanted it. Understand why before you invert it.
### 2. Write the test. Watch it fail.
The test must fail **against the code as it is right now**, before any fix exists.
Name it after the defect, not the function: `reveals bug: stale status shadows a terminal event`, not `test inferStatus`.
Assert the observable consequence a user or caller would see — the wrong status, the lost record, the 500 — not an internal call count. Call counts pass for the wrong reasons.
If it does not fail, you have not reproduced the bug. Go back to step 1.
### 3. Fix it.
Smallest change that makes the failing test pass. If the fix needs to be large, the test was probably too broad — narrow it and split.
### 4. Revert the fix. Confirm red. ← the whole point
Put the buggy code back, run the test, and **watch it fail**. Then restore the fix.
```bash
cp path/to/fixed.ts /tmp/fix.bak
# revert the fix (edit, patch, or git stash the single file)
<run the specific test> # MUST fail here
cp /tmp/fix.bak path/to/fixed.ts
<run the specific test> # green again
```
If it stayed green, **the test is fake**. Not "probably fine" — fake. Rewrite it and repeat.
This is not paranoia. It catches a specific, common failure: a test that exercises a path adjacent to the bug rather than the bug. Two real examples:
- A concurrency test modelled two writers but had no `await` between each writer's read and its write. Both ran to completion atomically, never interleaved, and the test passed with the lock removed. Fix: add latency between read and write, mirroring the real network gap.
- A fault-isolation test asserted "no 500 when the store fails", but the injected failure was a *missing* record, which the loader turns into `null` rather than throwing. The error path never ran. Fix: inject a real 500.
Both looked correct on the page. Only the revert exposed them.
### 5. Run everything.
The full suite, plus type checks. A fix that corrects one behaviour often contradicts a test that pinned the old one — which is a finding, not an annoyance. Go read that test and decide deliberately (see step 1).
## When you cannot get a true red
Sometimes the buggy code cannot be invoked: it is a closure inside a 3,000-line factory, a route handler, a private method. Do not fake a behavioural test. Pick one of these and **label it in the file header**:
| Type | Use when | Honesty requirement |
|---|---|---|
| **Extract, then test** | The logic can be moved to a module with injected dependencies | Preferred. Do this if the extraction is small. |
| **Structural test** | The call site cannot be reached, but the invariant is visible in the source | Scan the source and assert the property (e.g. "every write cycle sits inside the lock"). It will name offenders itself. Say in the header that it is structural and should be replaced when the code becomes reachable. |
| **Model test** | Testing an interaction between components you cannot both instantiate | Mirror the real code field-for-field, cite the file:line it models, and note in the header that it is a model. Extra important to run step 4 — models are where fake tests hide. |
| **Characterization test** | Documenting current behaviour you are not fixing yet | Name it as such. Do not call it a regression test. Flag that it will invert when the bug is fixed. |
## Reporting
When you present the work, include:
- What you **proved** vs **inferred** vs still do not know.
- The **revert output** — the actual failure line, not a claim that it failed.
- Which tests are behavioural, structural, model, or characterization.
- Anything you got wrong earlier in the investigation, corrected explicitly.
Do not describe a test as "revealing the bug" unless you have seen it red.
## Anti-patterns
- Writing the test after the fix and never reverting → decoration.
- Asserting a mock was called instead of the user-visible outcome → passes for the wrong reason.
- Widening a test until it passes → deleting the signal.
- Inverting a pre-existing test because it blocks you → check the history first; it may encode a decision.
- Reporting "all green" as success when nothing was ever red.
## One-line version
Red first, green second, **red again on purpose**, then green — and say which parts you actually proved.
## Attribution and License
Originally created and maintained by **RooAGI** as the `rooagi-red-green-proof`
skill. Copyright © 2026 RooAGI. Contributed under the MIT License. 用户提示词模板
填充变量后发送,即可运行该技能: {{variables}}
变量
| 名称 | 必填 | 说明 | 示例 |
|---|
完整技能配置
标准 .aiskill 文件,提供 JSON 与 YAML 两种格式。
{
"format": "aiskill/v1",
"skill": {
"name": "red-green-proof",
"slug": "red-green-proof",
"version": "1.0.0",
"description": "Turns a suspected bug into a proven one. Verify the cause against reality before claiming it, write a test that FAILS on the current code, apply the fix, watch it pass — then revert the fix and confirm the test goes red again, because a test that passes both ways proves nothing. Invoked bare after a debugging conversation, it takes the target from context rather than asking. Use when fixing a bug, investigating an incident, hardening a flaky area, or when asked to \"add tests that reveal the bug\". Triggers on \"/red-green-proof\", \"prove the bug\", \"red-green\", \"make the test fail first\", \"is that test load-bearing\", \"reveal the bug with a test\".",
"category": "Development",
"tags": [
"testing"
],
"platforms": [
"chatgpt",
"claude-code",
"cursor"
],
"tested_environment": "Agent Skills convention (SKILL.md) — works with Claude Code, Cursor, ChatGPT/Codex and compatible agents",
"license": "MIT"
},
"prompts": {
"system": "# Red-Green-Proof\r\n\r\nA bug is not fixed because the tests pass. A bug is fixed when a test **fails without your fix and passes with it**, and you have watched it do both.\r\n\r\n## Overview\r\n\r\nUse this skill when a bug, incident, flaky test, or unproven regression test is\r\nunder investigation. It applies a strict red-green-red loop: establish the\r\ncause, observe a focused test fail, make the smallest fix, then remove the fix\r\nand observe the test fail again. The final revert is the proof that the test is\r\nactually coupled to the defect.\r\n\r\n## Workflow\r\n\r\nKeep evidence for each phase separate. A test command that exits zero is not\r\nevidence that it exercised the defect; record the assertion and the observed\r\nfailure or success. Do not proceed when the current phase is unobserved.\r\n\r\nBefore changing code, identify the exact test command and expected red signal.\r\nAfter the fix, run that same command without changing its assertions. During\r\nthe revert, use the same command again and preserve the failure output. Restore\r\nthe fix before running the broader suite.\r\n\r\n## Proactive Triggers\r\n\r\n- A pull request adds a regression test but no pre-fix failure is recorded →\r\n ask for the red run before calling it coverage.\r\n- A bug fix changes production code and tests in one step → verify the test\r\n fails against the parent revision or label the evidence as missing.\r\n- A test uses only mocks or call-count assertions → ask for the observable\r\n user-facing consequence.\r\n- A test is described as flaky → preserve the failing seed, timing, or\r\n interleaving before attempting a stabilization fix.\r\n\r\n## Output Format\r\n\r\nReport each investigation with: (1) target and cause, labeled `Proven`,\r\n`Inferred`, or `Unknown`; (2) the red command and actual failure before the\r\nfix; (3) green and revert-red results with actual output; and (4) final suite\r\nstatus and remaining uncertainty.\r\n\r\nMost \"regression tests\" written after a fix never had the chance to fail. They are decoration. This skill is the discipline that separates a real test from a decorative one.\r\n\r\n## Picking the target\r\n\r\n**With an argument**, that is the target: `/red-green-proof the status endpoint reports finished runs as running`.\r\n\r\n**With no argument, take the target from the conversation.** The usual case is that you have just spent a long stretch investigating something — the bug is already on screen. Do not ask what to work on. Scan back through the session and pick, in this order:\r\n\r\n1. A defect just identified but not yet fixed.\r\n2. A fix applied without a failing test to back it — the most valuable target, because the test still has to be proven load-bearing.\r\n3. A test written but never verified red.\r\n4. Something described as \"still open\", \"not fixed yet\", or \"characterization only\".\r\n\r\nState your pick in one line and start:\r\n\r\n> Target: the buffer discards events when the flush write fails (`checkpointBuffer.ts:271`). Verifying before writing the test.\r\n\r\nOnly ask the user if two or more candidates are genuinely equal in priority — then list them as a short numbered choice and stop. If several *related* defects came up, handle them one at a time through the full loop rather than batching; each needs its own red.\r\n\r\nIf nothing in the conversation qualifies, say so and ask for a target rather than inventing one.\r\n\r\n## The loop\r\n\r\nRun these in order. Do not skip 1, and never skip 4.\r\n\r\n### 1. Verify the cause. Do not infer it.\r\n\r\nBefore you write a line of test code, establish what actually happened using evidence you can point at: the real record from the database or API, the real log line, the actual source of the function you are blaming.\r\n\r\nSay which of these you have:\r\n\r\n- **Proven** — I read the value / ran the code / pulled the record.\r\n- **Inferred** — consistent with the evidence, but I have not confirmed it.\r\n- **Unknown** — I cannot determine this from what is available.\r\n\r\nState the label out loud. If the honest answer is Unknown, say so and name the one artifact that would settle it. A confident wrong cause costs more than an admitted gap, because it sends the fix to the wrong place.\r\n\r\nTwo traps worth naming:\r\n- **A plausible mechanism is not the mechanism.** Rank candidates, then go rule them out one at a time by reading code, not by reasoning about it.\r\n- **Check whether the \"bug\" was deliberate.** `git log -S '<the exact line>'` and read the commit. If a test already asserts the current behaviour, someone may have wanted it. Understand why before you invert it.\r\n\r\n### 2. Write the test. Watch it fail.\r\n\r\nThe test must fail **against the code as it is right now**, before any fix exists.\r\n\r\nName it after the defect, not the function: `reveals bug: stale status shadows a terminal event`, not `test inferStatus`.\r\n\r\nAssert the observable consequence a user or caller would see — the wrong status, the lost record, the 500 — not an internal call count. Call counts pass for the wrong reasons.\r\n\r\nIf it does not fail, you have not reproduced the bug. Go back to step 1.\r\n\r\n### 3. Fix it.\r\n\r\nSmallest change that makes the failing test pass. If the fix needs to be large, the test was probably too broad — narrow it and split.\r\n\r\n### 4. Revert the fix. Confirm red. ← the whole point\r\n\r\nPut the buggy code back, run the test, and **watch it fail**. Then restore the fix.\r\n\r\n```bash\r\ncp path/to/fixed.ts /tmp/fix.bak\r\n# revert the fix (edit, patch, or git stash the single file)\r\n<run the specific test> # MUST fail here\r\ncp /tmp/fix.bak path/to/fixed.ts\r\n<run the specific test> # green again\r\n```\r\n\r\nIf it stayed green, **the test is fake**. Not \"probably fine\" — fake. Rewrite it and repeat.\r\n\r\nThis is not paranoia. It catches a specific, common failure: a test that exercises a path adjacent to the bug rather than the bug. Two real examples:\r\n\r\n- A concurrency test modelled two writers but had no `await` between each writer's read and its write. Both ran to completion atomically, never interleaved, and the test passed with the lock removed. Fix: add latency between read and write, mirroring the real network gap.\r\n- A fault-isolation test asserted \"no 500 when the store fails\", but the injected failure was a *missing* record, which the loader turns into `null` rather than throwing. The error path never ran. Fix: inject a real 500.\r\n\r\nBoth looked correct on the page. Only the revert exposed them.\r\n\r\n### 5. Run everything.\r\n\r\nThe full suite, plus type checks. A fix that corrects one behaviour often contradicts a test that pinned the old one — which is a finding, not an annoyance. Go read that test and decide deliberately (see step 1).\r\n\r\n## When you cannot get a true red\r\n\r\nSometimes the buggy code cannot be invoked: it is a closure inside a 3,000-line factory, a route handler, a private method. Do not fake a behavioural test. Pick one of these and **label it in the file header**:\r\n\r\n| Type | Use when | Honesty requirement |\r\n|---|---|---|\r\n| **Extract, then test** | The logic can be moved to a module with injected dependencies | Preferred. Do this if the extraction is small. |\r\n| **Structural test** | The call site cannot be reached, but the invariant is visible in the source | Scan the source and assert the property (e.g. \"every write cycle sits inside the lock\"). It will name offenders itself. Say in the header that it is structural and should be replaced when the code becomes reachable. |\r\n| **Model test** | Testing an interaction between components you cannot both instantiate | Mirror the real code field-for-field, cite the file:line it models, and note in the header that it is a model. Extra important to run step 4 — models are where fake tests hide. |\r\n| **Characterization test** | Documenting current behaviour you are not fixing yet | Name it as such. Do not call it a regression test. Flag that it will invert when the bug is fixed. |\r\n\r\n## Reporting\r\n\r\nWhen you present the work, include:\r\n\r\n- What you **proved** vs **inferred** vs still do not know.\r\n- The **revert output** — the actual failure line, not a claim that it failed.\r\n- Which tests are behavioural, structural, model, or characterization.\r\n- Anything you got wrong earlier in the investigation, corrected explicitly.\r\n\r\nDo not describe a test as \"revealing the bug\" unless you have seen it red.\r\n\r\n## Anti-patterns\r\n\r\n- Writing the test after the fix and never reverting → decoration.\r\n- Asserting a mock was called instead of the user-visible outcome → passes for the wrong reason.\r\n- Widening a test until it passes → deleting the signal.\r\n- Inverting a pre-existing test because it blocks you → check the history first; it may encode a decision.\r\n- Reporting \"all green\" as success when nothing was ever red.\r\n\r\n## One-line version\r\n\r\nRed first, green second, **red again on purpose**, then green — and say which parts you actually proved.\r\n\r\n## Attribution and License\r\n\r\nOriginally created and maintained by **RooAGI** as the `rooagi-red-green-proof`\r\nskill. Copyright © 2026 RooAGI. Contributed under the MIT License.",
"user_template": ""
},
"variables": [],
"install": {
"steps": [
{
"title": "Download & unzip",
"detail": "Download the .zip package from SkillVault and unzip it. The red-green-proof/ folder contains SKILL.md plus any companion scripts, references and assets."
},
{
"title": "Copy into your agent skills directory",
"detail": "Move the folder into your agent's skills directory — e.g. ~/.claude/skills/ (Claude Code), .codex/skills/, .cursor/skills/ or your project's .claude/skills/ folder — then restart or reload the session."
},
{
"title": "Use it",
"detail": "Describe the task in natural language; the agent loads the skill automatically when the request matches the skill description."
}
]
},
"usage": {
"steps": []
},
"metadata": {
"author": "SkillVault",
"source": "https://skillvault.top/skills/red-green-proof",
"exported_at": "2026-11-03T07:45:12.105Z"
}
} format: aiskill/v1
skill:
name: red-green-proof
slug: red-green-proof
version: 1.0.0
description: >-
Turns a suspected bug into a proven one. Verify the cause against reality before claiming it,
write a test that FAILS on the current code, apply the fix, watch it pass — then revert the fix
and confirm the test goes red again, because a test that passes both ways proves nothing.
Invoked bare after a debugging conversation, it takes the target from context rather than
asking. Use when fixing a bug, investigating an incident, hardening a flaky area, or when asked
to "add tests that reveal the bug". Triggers on "/red-green-proof", "prove the bug",
"red-green", "make the test fail first", "is that test load-bearing", "reveal the bug with a
test".
category: Development
tags:
- testing
platforms:
- chatgpt
- claude-code
- cursor
tested_environment: >-
Agent Skills convention (SKILL.md) — works with Claude Code, Cursor, ChatGPT/Codex and
compatible agents
license: MIT
prompts:
system: "# Red-Green-Proof\r\n\r\nA bug is not fixed because the tests pass. A bug is fixed when a test **fails without your fix and passes with it**, and you have watched it do both.\r\n\r\n## Overview\r\n\r\nUse this skill when a bug, incident, flaky test, or unproven regression test is\r\nunder investigation. It applies a strict red-green-red loop: establish the\r\ncause, observe a focused test fail, make the smallest fix, then remove the fix\r\nand observe the test fail again. The final revert is the proof that the test is\r\nactually coupled to the defect.\r\n\r\n## Workflow\r\n\r\nKeep evidence for each phase separate. A test command that exits zero is not\r\nevidence that it exercised the defect; record the assertion and the observed\r\nfailure or success. Do not proceed when the current phase is unobserved.\r\n\r\nBefore changing code, identify the exact test command and expected red signal.\r\nAfter the fix, run that same command without changing its assertions. During\r\nthe revert, use the same command again and preserve the failure output. Restore\r\nthe fix before running the broader suite.\r\n\r\n## Proactive Triggers\r\n\r\n- A pull request adds a regression test but no pre-fix failure is recorded →\r\n ask for the red run before calling it coverage.\r\n- A bug fix changes production code and tests in one step → verify the test\r\n fails against the parent revision or label the evidence as missing.\r\n- A test uses only mocks or call-count assertions → ask for the observable\r\n user-facing consequence.\r\n- A test is described as flaky → preserve the failing seed, timing, or\r\n interleaving before attempting a stabilization fix.\r\n\r\n## Output Format\r\n\r\nReport each investigation with: (1) target and cause, labeled `Proven`,\r\n`Inferred`, or `Unknown`; (2) the red command and actual failure before the\r\nfix; (3) green and revert-red results with actual output; and (4) final suite\r\nstatus and remaining uncertainty.\r\n\r\nMost \"regression tests\" written after a fix never had the chance to fail. They are decoration. This skill is the discipline that separates a real test from a decorative one.\r\n\r\n## Picking the target\r\n\r\n**With an argument**, that is the target: `/red-green-proof the status endpoint reports finished runs as running`.\r\n\r\n**With no argument, take the target from the conversation.** The usual case is that you have just spent a long stretch investigating something — the bug is already on screen. Do not ask what to work on. Scan back through the session and pick, in this order:\r\n\r\n1. A defect just identified but not yet fixed.\r\n2. A fix applied without a failing test to back it — the most valuable target, because the test still has to be proven load-bearing.\r\n3. A test written but never verified red.\r\n4. Something described as \"still open\", \"not fixed yet\", or \"characterization only\".\r\n\r\nState your pick in one line and start:\r\n\r\n> Target: the buffer discards events when the flush write fails (`checkpointBuffer.ts:271`). Verifying before writing the test.\r\n\r\nOnly ask the user if two or more candidates are genuinely equal in priority — then list them as a short numbered choice and stop. If several *related* defects came up, handle them one at a time through the full loop rather than batching; each needs its own red.\r\n\r\nIf nothing in the conversation qualifies, say so and ask for a target rather than inventing one.\r\n\r\n## The loop\r\n\r\nRun these in order. Do not skip 1, and never skip 4.\r\n\r\n### 1. Verify the cause. Do not infer it.\r\n\r\nBefore you write a line of test code, establish what actually happened using evidence you can point at: the real record from the database or API, the real log line, the actual source of the function you are blaming.\r\n\r\nSay which of these you have:\r\n\r\n- **Proven** — I read the value / ran the code / pulled the record.\r\n- **Inferred** — consistent with the evidence, but I have not confirmed it.\r\n- **Unknown** — I cannot determine this from what is available.\r\n\r\nState the label out loud. If the honest answer is Unknown, say so and name the one artifact that would settle it. A confident wrong cause costs more than an admitted gap, because it sends the fix to the wrong place.\r\n\r\nTwo traps worth naming:\r\n- **A plausible mechanism is not the mechanism.** Rank candidates, then go rule them out one at a time by reading code, not by reasoning about it.\r\n- **Check whether the \"bug\" was deliberate.** `git log -S '<the exact line>'` and read the commit. If a test already asserts the current behaviour, someone may have wanted it. Understand why before you invert it.\r\n\r\n### 2. Write the test. Watch it fail.\r\n\r\nThe test must fail **against the code as it is right now**, before any fix exists.\r\n\r\nName it after the defect, not the function: `reveals bug: stale status shadows a terminal event`, not `test inferStatus`.\r\n\r\nAssert the observable consequence a user or caller would see — the wrong status, the lost record, the 500 — not an internal call count. Call counts pass for the wrong reasons.\r\n\r\nIf it does not fail, you have not reproduced the bug. Go back to step 1.\r\n\r\n### 3. Fix it.\r\n\r\nSmallest change that makes the failing test pass. If the fix needs to be large, the test was probably too broad — narrow it and split.\r\n\r\n### 4. Revert the fix. Confirm red. ← the whole point\r\n\r\nPut the buggy code back, run the test, and **watch it fail**. Then restore the fix.\r\n\r\n```bash\r\ncp path/to/fixed.ts /tmp/fix.bak\r\n# revert the fix (edit, patch, or git stash the single file)\r\n<run the specific test> # MUST fail here\r\ncp /tmp/fix.bak path/to/fixed.ts\r\n<run the specific test> # green again\r\n```\r\n\r\nIf it stayed green, **the test is fake**. Not \"probably fine\" — fake. Rewrite it and repeat.\r\n\r\nThis is not paranoia. It catches a specific, common failure: a test that exercises a path adjacent to the bug rather than the bug. Two real examples:\r\n\r\n- A concurrency test modelled two writers but had no `await` between each writer's read and its write. Both ran to completion atomically, never interleaved, and the test passed with the lock removed. Fix: add latency between read and write, mirroring the real network gap.\r\n- A fault-isolation test asserted \"no 500 when the store fails\", but the injected failure was a *missing* record, which the loader turns into `null` rather than throwing. The error path never ran. Fix: inject a real 500.\r\n\r\nBoth looked correct on the page. Only the revert exposed them.\r\n\r\n### 5. Run everything.\r\n\r\nThe full suite, plus type checks. A fix that corrects one behaviour often contradicts a test that pinned the old one — which is a finding, not an annoyance. Go read that test and decide deliberately (see step 1).\r\n\r\n## When you cannot get a true red\r\n\r\nSometimes the buggy code cannot be invoked: it is a closure inside a 3,000-line factory, a route handler, a private method. Do not fake a behavioural test. Pick one of these and **label it in the file header**:\r\n\r\n| Type | Use when | Honesty requirement |\r\n|---|---|---|\r\n| **Extract, then test** | The logic can be moved to a module with injected dependencies | Preferred. Do this if the extraction is small. |\r\n| **Structural test** | The call site cannot be reached, but the invariant is visible in the source | Scan the source and assert the property (e.g. \"every write cycle sits inside the lock\"). It will name offenders itself. Say in the header that it is structural and should be replaced when the code becomes reachable. |\r\n| **Model test** | Testing an interaction between components you cannot both instantiate | Mirror the real code field-for-field, cite the file:line it models, and note in the header that it is a model. Extra important to run step 4 — models are where fake tests hide. |\r\n| **Characterization test** | Documenting current behaviour you are not fixing yet | Name it as such. Do not call it a regression test. Flag that it will invert when the bug is fixed. |\r\n\r\n## Reporting\r\n\r\nWhen you present the work, include:\r\n\r\n- What you **proved** vs **inferred** vs still do not know.\r\n- The **revert output** — the actual failure line, not a claim that it failed.\r\n- Which tests are behavioural, structural, model, or characterization.\r\n- Anything you got wrong earlier in the investigation, corrected explicitly.\r\n\r\nDo not describe a test as \"revealing the bug\" unless you have seen it red.\r\n\r\n## Anti-patterns\r\n\r\n- Writing the test after the fix and never reverting → decoration.\r\n- Asserting a mock was called instead of the user-visible outcome → passes for the wrong reason.\r\n- Widening a test until it passes → deleting the signal.\r\n- Inverting a pre-existing test because it blocks you → check the history first; it may encode a decision.\r\n- Reporting \"all green\" as success when nothing was ever red.\r\n\r\n## One-line version\r\n\r\nRed first, green second, **red again on purpose**, then green — and say which parts you actually proved.\r\n\r\n## Attribution and License\r\n\r\nOriginally created and maintained by **RooAGI** as the `rooagi-red-green-proof`\r\nskill. Copyright © 2026 RooAGI. Contributed under the MIT License."
user_template: ""
variables: []
install:
steps:
- title: Download & unzip
detail: >-
Download the .zip package from SkillVault and unzip it. The red-green-proof/ folder contains
SKILL.md plus any companion scripts, references and assets.
- title: Copy into your agent skills directory
detail: >-
Move the folder into your agent's skills directory — e.g. ~/.claude/skills/ (Claude Code),
.codex/skills/, .cursor/skills/ or your project's .claude/skills/ folder — then restart or
reload the session.
- title: Use it
detail: >-
Describe the task in natural language; the agent loads the skill automatically when the
request matches the skill description.
usage:
steps: []
metadata:
author: SkillVault
source: https://skillvault.top/skills/red-green-proof
exported_at: "2026-11-03T07:45:12.105Z"
安装指南
- 1
Download & unzip
Download the .zip package from SkillVault and unzip it. The red-green-proof/ folder contains SKILL.md plus any companion scripts, references and assets.
- 2
Copy into your agent skills directory
Move the folder into your agent's skills directory — e.g. ~/.claude/skills/ (Claude Code), .codex/skills/, .cursor/skills/ or your project's .claude/skills/ folder — then restart or reload the session.
- 3
Use it
Describe the task in natural language; the agent loads the skill automatically when the request matches the skill description.
使用方法
平台兼容性
相关技能
skill-tester
Validate, test, and score the quality of skills within the claude-skills ecosystem. Comprehensive meta-skill: structure validation, Python script testing (syntax + imports + runtime + output format), multi-dimensional quality scoring with letter grades and tier classification (BASIC/STANDARD/POWERFUL). Use when authoring a new skill, auditing existing skills for tier promotion, setting up pre-commit hooks for skill quality, or integrating skill QA into CI.
browser-automation
Use when the user asks to automate browser tasks, scrape websites, fill forms, capture screenshots, extract structured data from web pages, or build web automation workflows. NOT for testing — use playwright-pro for that.
helm-chart-builder
Helm chart development agent skill and plugin for Claude Code, Codex, Gemini CLI, Cursor, OpenClaw — chart scaffolding, values design, template patterns, dependency management, security hardening, and chart testing. Use when: user wants to create or improve Helm charts, design values.yaml files, implement template helpers, audit chart security (RBAC, network policies, pod security), manage subcharts, or run helm lint/test.