troublemaker
by wonderfulcode1
故意注入一个已知的小错误到可丢弃的git工作树中,以便学习者练习查找和修复它。教学工具 - 阅读README了解其教育理念和安全性保证。
Deliberately inject a small, known bug into a disposable git worktree so learners can practice finding and fixing it. A teaching tool - read the README for its educational philosophy and safety guarantees.
安装
dsh plugin --profile web add github:wonderfulcode1/troublemakerGitHub 源码安装:首次需按提示配置 allowBuilds 构建授权后重试
安装与环境配置指引、插件开发教程见 DSH 中文社区文档 ↗
安装即在你的机器上以你的权限运行第三方代码——它可读写文件、使用凭据、访问网络,DSH 的工具审批不会为插件代码加沙箱。「检测到 manifest」仅代表发现 dsh.bundle / dsh.plugin 清单,不构成兼容性或安全审查;安装前请审阅源码,不熟悉的插件先在不含密钥的环境试用。
README
往一个一次性的 git worktree 里故意注入一个小而明确的 bug,让学习者练习"找到它、修好它"。
troublemaker 是一个教学工具。它故意"制造麻烦"——但只发生在一个它为你创建的一次性 worktree 里,绝不会动你的真实代码——并用"探针-预言机"流水线来判定学习者的修复是否成功。
状态:v0.1.0 教学原型。 在把它用于练习之外的任何场景之前,请先阅读当前局限。
- 零运行时依赖。只需要 PATH 上有 Node.js(>= 18)和
git。 - npm 包名:
dsh-troublemaker(CLI 命令:troublemaker)。源码:github.com/wonderfulcode1/troublemaker。
它为什么存在(教学理念)
调试是一项只能靠调试来练的技能。真实代码库太大、太吵、也太珍贵,不适合拿来练习;完全虚构的练习题又太假,提不起劲。
troublemaker 取中间路线:它拿你自己的仓库(或自带的示例仓库),检出一个一次性的 worktree,然后注入一个小而明确、可描述的 bug——比如一个单字符的 off-by-one 变异。学习者随后:
- 阅读 bug 描述;
- 在 worktree 里找到变异点;
- 亲手修复;
- 反复运行检查,直到报告
solved; - 回滚 worktree。
这个工具存在的意义是让练习可验证,而不是骗人。每个注入的场景都自带:
- 探针(probe)——插入源码的一行日志,运行时报告 bug 行为;
- 预言机(oracle)——该探针应有的正确值;
- 注入时的 kill check——证明预言机确实能检测出注入的 bug(检测不出的变异会立即回滚);
- gate 与 regression——修复后的代码必须继续通过的检查命令。
这与真实的 bug 注入教学系统是同一套模式:难度在场景里,机制是诚实的——预言机从不谎报正确行为是什么。注入的 bug 不会对你隐藏:bug 描述会点名它,而真相就藏在 worktree 与你已提交代码的 diff 里。
这个工具不是什么
- 不是破坏工具。 它碰不到你的工作区,也碰不到任何你没指向的仓库,更不会修改已提交的分支——见安全保障。
- 不是安全工具,不是模糊测试器,也不是"测试你有多容易被骗"的基准。
- 不是生产软件。 它是一个用于学习 bug 注入教学原理的 MVP,公开出来是为了让别人研究、复用和改进这个想法。
未经他人同意,把 bug 注入别人的代码,是对这个工具的滥用。设计上已经尽量让这种滥用变难(worktree、要求仓库干净、可回滚),但没有任何工具能拦住铁了心的滥用者。请把它用在它该用的地方:教学与学习。
安全保障
以下是这个工具实际强制实施的技术保障,不是口头承诺:
- 只碰一次性 worktree。 每个场景都在
<repo>/.dsh-teaching-worktrees/<scenarioId>下,由git worktree add --detach <path> HEAD创建。你的工作区、分支、stash、已提交历史都不会被修改。rollback会删除 worktree 并清理陈旧的 worktree 记录。 - 拒绝脏仓库。
inject要求git diff与git diff --cached都为干净状态,未提交的工作永远不会被带进或破坏某个场景。 - bug 一定可被检测。 注入时会跑 kill check:driver 必须走到探针路径,且预言机必须在变异代码上观察到不匹配。检测不到的变异会被回滚、注入失败。你永远不会拿到一个检查器都看不见的 bug。
- 仓库必须包含场景目标文件,且每个锚点必须恰好出现一次。 找不到预期的原始源码时,注入会大声失败(并回滚)——绝不猜测、绝不部分变异。
- 失败即回滚。
inject中任何一步失败,都会先删掉它创建的 worktree 再报错。 - 无网络、无遥测、无隐藏行为。 包零运行时依赖,只执行本地
git和node命令,全部源码可读。 check只读。 它在 worktree 里运行场景的 gate、driver、regression 并读取文件;除inject已产生的.dsh-teaching产物外,不写任何东西。- 命令不经 shell 执行。 工具直接用参数向量启动
git和node(manifest 里的命令按空白切分);场景无法通过引号把 shell 元字符偷渡进来——详见下方局限。
你需要知道的一个注意事项
场景里的 gate、driver、regression 字符串是会在你机器上、以你的用户权限、在 worktree 内执行的命令。这是设计使然——场景要能被检查,就必须运行代码。请把场景 manifest 当作可执行文件对待:只注入你信任的场景,且只注入你拥有的仓库。内置场景只运行 node --check 和一个纯 node 回归脚本。
当前局限
v0.1.0 明确不做的事情:
- 只有一个内置场景。 目前只有
v0-retain-items(一个小型 retainer 类里的 off-by-one)。它针对自带的示例练习仓库(examples/practice-repo);要在别处使用,仓库必须包含同样的目标文件与锚点。 - 还没有场景编写格式。 场景是代码而非数据:目前没有文档化的"仅靠 manifest 编写新场景"的方式,不改包就写不了新场景。磁盘上的 worktree manifest(
dsh-teaching-scenariov1 格式)会被读写,但编写工具是后续工作。 - 只支持零依赖场景。 gate 与 regression 用纯
node运行;worktree 里不会安装node_modules或工具链(本工具所源自的 harness 版本会链接node_modules,这个独立 CLI 不会)。 - 命令只按空白切分。 manifest 里的
gate/regression字符串不能包含带引号的参数或 shell 运算符。这是刻意的安全取舍(不用 shell),代价是复杂命令需要包装脚本。 - 没有鉴权、没有远程面。 一切都在本地 CLI。没有服务器、没有 GUI、也没有任何联网使用方式。
- Windows 上测试过,要求
git在 PATH 上。 换行处理会把注入文件规范化为 LF;其他平台应该能工作,但未测试。 fix只对内置场景有效。 已知修复命令需要场景定义;它无法修复包中没有定义该场景的 worktree。- 没有并发控制。 两个进程同时对同一个仓库注入没有协调。
- 注入的探针行是普通的
console.log。 学习者删除或改名探针行会触发tampered判定——这是设计意图——但大量日志也可能拖慢 driver。
安装
npm install -g dsh-troublemaker
troublemaker --help
或免安装运行:
npx dsh-troublemaker --help
五分钟快速上手
自带的示例是一个极小的零依赖仓库。初始化、注入、亲手修复、回滚:
git clone https://github.com/wonderfulcode1/troublemaker.git
cd troublemaker/examples/practice-repo
git init -b main
git add -A
git commit -m "pristine practice repo"
troublemaker inject .
# Injected scenario v0-retain-items into .../.dsh-teaching-worktrees/v0-retain-items
# gate: PASS
# kill check: mismatch (oracle detects the injected bug)
troublemaker check . v0-retain-items
# verdict: bug-alive
# 在 .dsh-teaching-worktrees/v0-retain-items/src/retainer.js 里手工修复
# (把 `<=` 改回 `<`),然后:
troublemaker check . v0-retain-items
# verdict: solved
troublemaker rollback . v0-retain-items
CLI 参考
troublemaker list <repo> 列出某个仓库下已注入的场景
troublemaker inject <repo> [--scenario ID] 注入内置场景(默认 v0-retain-items)
troublemaker check <repo> <scenarioId> 运行完整检查流水线(判定 + 探针)
troublemaker fix <repo> <scenarioId> 应用已知修复(仅内置场景,演示用)
troublemaker rollback <repo> <scenarioId> 删除场景 worktree
troublemaker scenarios 列出内置场景
troublemaker --version | --help
--json 以 JSON 输出命令结果
工作原理
学习者循环
inject——要求仓库干净。创建 detached worktree,应用变异(每个锚点必须恰好匹配一次),写入场景 manifest,跑 gate,再跑 driver 并证明预言机能检测出 bug(kill check)。check——按顺序短路判定:tampered——某探针行不再以其源码文件中的原样出现。type-fail——gate 命令在注入后的源码上失败。bug-alive——driver 跑通了,但至少一个探针与预言机不一致。incomplete——driver 没有触发某个必需探针。regression-failed——探针全部匹配,但回归套件失败。solved——探针全部匹配且回归套件通过。
fix——应用已知修复(仅内置场景;学习者应当亲手修复)。rollback——删除 worktree 并清理陈旧记录。
状态在磁盘上
每个答案都在调用时由 worktree 的 manifest.json 和源码推导而来。工具不保留任何跨场景内存,所以多个 shell 看到的是同一份事实,一个进程创建的 worktree 可以由另一个进程检查或回滚。
内置场景
v0-retain-items 在自带示例仓库的 ItemRetainer.push 中注入一个 off-by-one:比较符 < 被变异为 <=,导致 retainer 多保留一个条目(maxItems + 1)。探针在 finish() 内触发,报告保留条目、seen 计数与 omitted 计数;预言机固定了正确值。这也是 DeepSeek Harness 教学功能(bug 注入教学)使用的同一场景,此处移植为零依赖独立运行。
项目状态
v0.1.0 以一个诚实的 MVP 身份发布。它刻意保持小巧,上面的局限都写了出来而不是藏着掖着,整个工具是一份可以通读到底的教学产物。欢迎在 issue 区提交 bug 报告和下一个场景的想法。
License
MIT——见 LICENSE。
原始 README: https://github.com/tmpdot/troublemaker/blob/main/README.zh-CN.md ↗
同类插件
查看全部 →
k8e
k8e.sh — 开源 Agentic AI 沙箱矩阵

hol-guard
开源AI代理防病毒:运行时拦截风险工具、秘密访问、提示注入、恶意软件包、MCP服务器、插件和技能。

anolisa
ANOLISA(Agentic Nexus Operating Layer & Interface System Architecture):具备运行时、安全性、可观测性和 Tokenless 响应压缩能力的 Agentic OS,可降低 Token 使用量与成本。

mobius
首个自我演进的开源 Agent OS:连接你的团队、AI agent、设备与算力

deepseek-harness-desktop
DeepSeek Harness Tauri 桌面版 | Only 5mb installer, zero environment setup. Windows / macOS / Linux.

open-managed-agents
开源Claude管理代理API实现和自托管Claude标签式代理运行时。即插即用;在Cloudflare Workers/Durable Objects或Node.js上运行。Apache 2.0。