ponytail-debt:把 `ponytail:` 技术债标记收割为可追踪的债务账本
ponytail 让 AI Agent 以"最懒的资深工程师"方式写代码,凡是刻意简化的地方都会留下一条 ponytail: 注释,标明当前的"天花板"和将来的升级路径。ponytail-debt 是 ponytail 技能套件中的债务账本技能:它用一条 grep 扫描全仓库的 ponytail: 标记,把它们汇总成一份按文件分组的"债务台账",并对没有升级路径的条目打上 no-trigger 腐化风险标签。读完本文,你可以完整复现这套债务收割流程(扫描命令、台账行格式、计数收尾、边界行为),并理解 ponytail 仓库自身是如何用 ponytail: 注释实践这套约定的。
债务从何而来:ponytail: 注释约定
ponytail-debt 并不是凭空扫描任意注释,它收割的是 ponytail 主技能写入代码的"刻意简化"标记。该约定定义在主技能 skills/ponytail/SKILL.md 与随仓库分发的规则文件 AGENTS.md 中,原文规则是:
Mark deliberate simplifications that cut a real corner with a known ceiling (global lock, O(n²) scan, naive heuristic) with a
ponytail:comment naming the ceiling and upgrade path.
也就是说,当 Agent 为了"偷懒"而牺牲某个真实维度(全局锁、O(n²) 扫描、朴素启发式)时,必须留下形如:
ponytail: <ceiling>, <upgrade path>
的注释,同时命名天花板(当前实现的上限在哪)和升级路径(什么触发条件出现时该重做它)。官方示例是 # ponytail: global lock, per-account locks if throughput matters——天花板是全局锁,升级触发条件是"吞吐变得重要时换成按账户加锁"。
这条约定是 ponytail 理念"最好的代码是你没写的代码"的配套机制:偷懒可以,但偷懒必须留痕,且留痕要可审计。ponytail-debt 正是审计侧——它存在的意义是让"以后再说"(deferral)不会悄无声息地变成"永远不说"(never)。
本仓库的真实 ponytail: 标记长什么样
ponytail 仓库本身就在使用这套约定。以下都是仓库中真实存在的标记(可直接用 git grep 复核):
- benchmarks/agentic/judge.py:
ponytail: stdlib urllib for the API call, no requests dependency.—— 天花板写得很明确(不引入 requests 依赖),升级路径隐含在"需要更强 HTTP 能力时"。 - benchmarks/agentic/complete.py:
ponytail: reuses judge.py's HTTP/key/source plumbing instead of duplicating it -- one rubric。 - benchmarks/correctness.js:
// ponytail: terse models often answer with bare, unfenced code. Treat the whole(该条没有明确的升级触发条件,正是no-trigger机制要盯住的类型)。
另外 README.md 的 Before/after 示例里也有一条 HTML 版标记:
<!-- ponytail: browser has one -->
<input type="date">
这些真实样本正好覆盖三种注释前缀:Python 的 #、JS 的 //、HTML 的 <!--,也解释了为什么后面的扫描命令必须可扩展前缀。
技能定义:触发条件与一句话描述
ponytail-debt 的规范版本是 skills/ponytail-debt/SKILL.md,其 frontmatter 规定了触发词与行为边界:
---
name: ponytail-debt
description: >
Harvest every `ponytail:` comment in the codebase into a debt ledger, so the
deliberate shortcuts and deferrals ponytail leaves behind get tracked instead
of rotting into "later means never". Use when the user says "ponytail debt",
"/ponytail-debt", "what did ponytail defer", "list the shortcuts", "ponytail
ledger", or "what did we mark to do later". One-shot report, changes nothing.
---
从这份描述可以提炼出三要点:触发(用户说出 "ponytail debt"、/ponytail-debt、"what did ponytail defer"、"list the shortcuts"、"ponytail ledger"、"what did we mark to do later" 等表达时激活)、形态(One-shot report,一次性报告)、副作用(changes nothing,不修改任何东西)。
本仓库文档对应的 OpenClaw 打包版
本文的核心文档是 .openclaw/skills/ponytail-debt/SKILL.md,它是为 OpenClaw / ClawHub 平台生成的打包版本。两者的关系由 scripts/build-openclaw-skills.js 定义:
- 正文从
skills/<name>/SKILL.md逐字复制,"ruleset never drifts"(规则文本永不漂移); - 只重写 frontmatter,因为 OpenClaw 要求
description必须是不含引号、160 字符以内的单行文本; - 生成物提交进仓库,tests/openclaw-skills.test.js 会在副本过期时让测试失败。
所以 OpenClaw 版的 description 被压缩为:"Harvest every ponytail: shortcut comment into one debt ledger, so deferrals get tracked instead of forgotten. One-shot report.",而正文与规范版完全一致。这也意味着下文的每个流程细节,对两个文件同样成立。
扫描:一条 grep 命令收割全部标记
ponytail-debt 的 Scan 章节给出的扫描命令是:
grep -rnE '(#|//) ?ponytail:' .
并附了关键提示:(add other comment prefixes if your stack uses them)——如果你的技术栈用别的注释前缀(HTML 的 <!--、C++ 的 /* 等),要自行扩展正则。几个参数值得展开:
-r递归整个目录树;-n输出行号(台账行格式需要<file>:<line>);-E启用扩展正则,(#|//) ?ponytail:匹配# ponytail:、#ponytail:、// ponytail:、//ponytail:四种形态(注意前缀与ponytail:之间的空格是可选的);- 文档明确要求跳过
node_modules、.git和构建产物——在本仓库实践中可写作grep -rnE '(#|//) ?ponytail:' . --exclude-dir={node_modules,.git,dist}之类。
还有一个容易被忽略的设计意图:每个命中就是一条台账行,而"注释前缀"本身就是过滤器。文档原话是 "The comment prefix keeps prose that merely mentions the convention out of the ledger."——只有写成真注释的标记才入账;文档、README 或聊天里仅仅口头提到 ponytail: 这个约定的散文不会混进台账。这是用语法位置(而不是语义判断)来保证账本信噪比的一个便宜而有效的办法。
输出:台账行格式与 no-trigger 腐化标签
文档规定的输出结构是:每个标记一行,按文件分组,行格式为:
<file>:<line>, <what was simplified>. ceiling: <the limit named>. upgrade: <the trigger to revisit>.
由于注释约定本身就是 ponytail: <ceiling>, <upgrade path>,所以天花板和重访触发条件可以直接从注释文本里抽取,不需要额外判断。用仓库里的真实标记填一遍这个模板,效果大致是:
benchmarks/agentic/judge.py:16, API 调用改用标准库而非 requests。ceiling: 只用 stdlib urllib。upgrade: 需要更强 HTTP 能力(重定向/会话池)时再引入依赖。
benchmarks/agentic/complete.py:22, 复用 judge.py 的 HTTP/key/source 管道而非复制。ceiling: 两套脚本共享同一套配置。upgrade: 两者需要独立 rubric 时拆开。
追责:git blame 补 owner
文档给了一个可选的增强:给每一行补上负责人,方法是
git blame -L<line>,<line> <file>
其中 <line> 用台账行里的行号。这样每条债务都能对应到当初写下这个简化的人——账本从"债务清单"升级为"债务责任人清单"。
no-trigger:标记腐化风险
这是 ponytail-debt 最有判断力的一条规则:
Flag the rot risk: any
ponytail:comment that names no upgrade path or trigger gets ano-triggertag, those are the ones that silently rot.
任何 ponytail: 注释如果没有写明升级路径或触发条件,就被打上 no-trigger 标签。逻辑很直白:有触发条件的债务会在条件达成时被人想起来;没有触发条件的债务没有任何外部事件会唤醒它,只会"静默腐烂"。回看前面的真实样本,benchmarks/correctness.js 那类只解释"为什么这么做"、却不写"何时该重做"的注释,就是典型的 no-trigger 候选——这正是该技能要暴露的问题。
收尾与空结果话术
报告的结尾必须是固定格式的计数行:
<N> markers, <M> with no trigger.
即"共 N 条标记,其中 M 条没有触发条件"。如果全仓库一条都没有,则输出:
No ponytail: debt. Clean ledger.
空账本也是一种有效结果——它证明当前代码库里没有任何未偿还的 ponytail 简化。
边界行为:只读、一次性、可持久化
SKILL.md 的 Boundaries 章节把行为边界压缩到了四句话,逐条看:
- Reads and reports only, changes nothing. 默认只读只报告,不修改任何代码——这与 skills/ponytail-debt/SKILL.md frontmatter 里的 "changes nothing" 呼应;
- To persist it, ask and it writes the ledger to a file (e.g.
PONYTAIL-DEBT.md) 用户显式要求持久化时,把台账写进文件(示例文件名PONYTAIL-DEBT.md),这样债务清单可以进版本库、参与 code review; - One-shot 一次性任务,跑完即止,不是常驻监控;
- "stop ponytail-debt" 或 "normal mode" to revert 说"stop ponytail-debt"或"normal mode"即可退出。
这套边界与主技能 skills/ponytail/SKILL.md 的 Boundaries 风格一致:ponytail 管的是"造什么",退出路径总是明确的,模式不会偷偷粘住用户。
调用渠道:命令、技能与插件
同一份 ponytail-debt 逻辑在仓库里有多个投递渠道,行为一致,选择取决于你的宿主:
| 渠道 | 入口 | 位置 |
|---|---|---|
| 斜杠命令 | /ponytail-debt |
commands/ponytail-debt.toml |
| 技能文件(规范版) | 用户说出触发词时由 Agent 激活 | skills/ponytail-debt/SKILL.md |
| OpenClaw 技能 | clawhub install ponytail-debt 或整包安装 |
.openclaw/skills/ponytail-debt/SKILL.md |
| Hermes 插件 | ponytail:ponytail-debt |
由 init.py 的插件代码加载 |
命令渠道的完整 prompt 在 commands/ponytail-debt.toml,它把 SKILL.md 的流程压成一段指令:
description = "Harvest ponytail: comments into a tracked debt ledger"
prompt = "Harvest every `ponytail:` comment in this repository into a debt ledger so deferrals do not rot into 'later means never'. Grep the whole tree for comment markers (grep -rnE '(#|//) ?ponytail:' ., skipping node_modules/.git/build output). One row per marker, grouped by file: <file>:<line> — <what was simplified>. ceiling: <the limit named in the comment>. upgrade: <the trigger to revisit>. Tag any marker that names no upgrade path or trigger as no-trigger, those rot silently. End with the count of markers and how many lack a trigger. If none: 'No ponytail: debt. Clean ledger.' Report only, change nothing."
对照可以看到:SKILL.md 里的扫描命令、行格式、no-trigger 标签、计数收尾、空结果话术、"Report only, change nothing" 边界,在命令 prompt 中一一保留,没有信息损失。
按 README.md 的 Commands 表,各渠道的可见性规则是:/ponytail-debt 等命令需要"支持技能的宿主"(Claude Code、Codex、Devin CLI、OpenCode、Gemini、pi、Swival、Hermes Agent、Qoder);在 Codex 里它们是技能,用 @ponytail-debt 调用;而纯指令型适配器(Cursor、Windsurf、Cline、Copilot、Kiro、Antigravity)只加载常驻规则集,不提供命令——此时直接对 Agent 说 "ponytail ledger" 这类触发词即可。
实践闭环:从标记到偿还
把前面各节串起来,ponytail-debt 在 ponytail 工作流中构成一个完整的债务生命周期:
- 记账——日常编码时,ponytail 主技能(skills/ponytail/SKILL.md 的 Rules 第 8 条)要求每个"砍了真实角"的简化都留下
ponytail: <ceiling>, <upgrade path>注释; - 对账——定期(或说 "ponytail ledger" 时)运行
ponytail-debt,一条 grep 得到全量台账,no-trigger标签揪出最容易腐烂的无主债务; - 追责——对高价值条目补
git blame -L<line>,<line>确认 owner; - 持久化——需要跟踪趋势时让 Agent 把台账写入
PONYTAIL-DEBT.md; - 偿还——当某条债务的 upgrade trigger 真的到来时,按注释里写明的升级路径重做它。
第 2 步可以完全脱离 Agent 手工执行(一条 grep + 人工分组),第 3、4 步依赖版本库与文件系统权限,第 1 步依赖 ponytail 规则集已生效——适用前提就是你的 Agent 宿主已按 README.md 的 Install 章节装好 ponytail。整个链路中没有任何遥测或外部服务,账本永远在你自己的仓库里。
参考文件
- 核心文档(本文主体):.openclaw/skills/ponytail-debt/SKILL.md
- 规范版技能(生成源):skills/ponytail-debt/SKILL.md
- 斜杠命令定义:commands/ponytail-debt.toml
- 打包脚本(说明
.openclaw/与skills/的生成关系):scripts/build-openclaw-skills.js - 打包过期检测测试:tests/openclaw-skills.test.js
- 约定源头(
ponytail:注释规则):skills/ponytail/SKILL.md、AGENTS.md - 真实标记样本:benchmarks/agentic/judge.py、benchmarks/agentic/complete.py、benchmarks/correctness.js
atomcodeClaude Code 的开源替代方案。连接任意大模型,编辑代码,运行命令,自动验证 — 全自动执行。用 Rust 构建,极致性能。 | An open-source alternative to Claude Code. Connect any LLM, edit code, run commands, and verify changes — autonomously. Built in Rust for speed. Get StartedRust0622
Hy4-previewHy4 preview 是由腾讯混元团队研发的新一代混合专家(MoE)旗舰模型。模型总参数量 770B,每个 token 激活 49B,主干共包含78层,第一层采用标准 FFN,其余 77 层均为 MoE 结构,每层包含 256 个路由专家与 1 个共享专家,每个 token 激活 top-8 路由专家及共享专家。主干之外原生内置 1 层 MTP(总参数量 10B,激活 0.7B)以支持投机解码。Python00
GLM-5.3GLM-5.3 与 GLM-5.2 使用相同的基座模型——所有提升均来自后训练。与 GLM-5.2 相比,它在复杂编程和长程任务上的表现显著提升。Jinja00
GLM-5.3-FlashGLM-5.3-Flash (320B-A18B),是GLM-5系列的首个原生多模态模型。320B总参数,能力超过GLM-5.2Jinja00
Spark-X2.5-4BSpark-X2.5-4B 旨在让强大的 AI 更实用、更高效、更易获得。在广泛日常任务中表现强劲,涵盖对话、写作、翻译、推理、编码、工具调用以及智能体工作流,并在同等规模的开源模型中取得领先成绩。Spark-X2.5 将面向效率的架构与最高 1M tokens 的原生上下文窗口相结合,并支持 200 多种语言。Python00
Spark-X2.5-1.7BSpark-X2.5-1.7B 旨在让强大的 AI 更加实用、高效且易于获取。这些模型在广泛的日常任务中表现出色,涵盖对话、写作、翻译、推理、编程、工具调用和智能体工作流,并在同等规模的开源模型中取得领先结果。Spark-X2.5 将面向效率的架构与最高 1M tokens 的原生上下文窗口相结合,并支持 200 多种语言。Python00