Ponytail
Lazy senior dev skill — DietrichGebert/ponytail
Ponytail は、AI コーディングエージェントに「lazy senior dev」の判断基準を注入するスキル配布パッケージ。YAGNI・標準ライブラリ・ネイティブ機能を優先し、依存追加や抽象化レイヤーを書く前に止まる。セキュリティ・信頼境界の検証・アクセシビリティなど、削ってはいけない領域は例外として残す。
skills/ponytail/SKILL.md が行動定義の正。AGENTS.md はスキル非対応ホスト向けのコンパクト版。各ホスト用ファイル(.cursor/rules/ など)は薄いアダプタで、コアを複製しない。
タスク「フォームに日付ピッカーを追加」への応答例(examples/date-picker.md より)。
flatpickr 導入、ラッパー、2 つの useEffect、CSS import。
npm install flatpickr
// + wrapper component (~30 lines)依存 0・1 行。ブラウザ組み込みを採用。
<!-- ponytail: browser has one -->
<input type="date">意図的な簡略化は ponytail: コメントで残し、上限とアップグレード経路を明示する。
コードを書く前に上から順に確認し、成立する最初の段で止める。2 段が成立するなら上の段を選び、調査ループに入らない。
<input type="date">、CSS、DB 制約などプラットフォーム機能を使う。
%%{init: {'theme': 'base', 'themeVariables': { 'primaryColor': '#e8f4f8', 'primaryTextColor': '#1a3a4a', 'primaryBorderColor': '#5a9aaa', 'lineColor': '#5a9aaa', 'fontSize': '14px'}}}%%
flowchart TD
A[タスク受領] --> B{YAGNI?}
B -->|不要| Z[スキップ + 1行説明]
B -->|必要| C{stdlib?}
C -->|Yes| R[採用して終了]
C -->|No| D{native?}
D -->|Yes| R
D -->|No| E{既存 deps?}
E -->|Yes| R
E -->|No| F{1行?}
F -->|Yes| R
F -->|No| G[最小実装]
切り替え: /ponytail lite/ponytail full/ponytail ultra。終了は stop ponytail または normal mode。
| レベル | 挙動 | 例(API キャッシュ要求) |
|---|---|---|
| lite | 依頼どおり実装しつつ、より短い代替を 1 行で提示 | キャッシュ実装 +「functools.lru_cache で 1 行」の FYI |
| full(既定) | ラダーを強制。最短 diff・最短説明 | @lru_cache(maxsize=1000)。カスタムキャッシュクラスは計測で不足が出るまで保留 |
| ultra | YAGNI 極大。削除優先。要件自体を問い直す | プロファイラ結果があるまでキャッシュなし。必要時も lru_cache のみ |
[code] → skipped: [X], add when [Y]. 説明がコードより長い場合は説明を削る。
5 タスク(メール検証、debounce、CSV 合計、React カウントダウン、FastAPI レート制限)× Haiku / Sonnet / Opus。各セル 10 回実行の中央値。アームは no skill / caveman / ponytail。
コード行数(LOC・中央値)
| arm | Haiku | Sonnet | Opus |
|---|---|---|---|
| baseline(no skill) | 518 | 693 | 256 |
| caveman | 116 | 120 | 67 |
| ponytail | 39 | 44 | 51 |
コスト(USD・5 タスク合計)
| arm | Haiku | Sonnet | Opus |
|---|---|---|---|
| baseline | 0.032 | 0.141 | 0.135 |
| caveman | 0.014 | 0.045 | 0.075 |
| ponytail | 0.010 | 0.032 | 0.071 |
再現: npx promptfoo@latest eval -c benchmarks/promptfooconfig.yaml --repeat 10(リポジトリ内 benchmarks/)。caveman は prose 圧縮が主でコード量は ponytail より中間。実セッションではスキルが 1 回注入されプロンプトキャッシュされるため、コスト差はさらに広がる。
詳細は docs/agent-portability.md。アダプタは薄く保ち、可能なら既存 skills/ と hooks/ を参照する。
フック(Claude Code 例)
SessionStart で ponytail-activate.js がモードをロード。UserPromptSubmit で ponytail-mode-tracker.js がレベル変更を追跡する(hooks/hooks.json)。
Claude Code
/plugin marketplace add DietrichGebert/ponytail
/plugin install ponytail@ponytailCodex
codex plugin marketplace add DietrichGebert/ponytail
# /plugins でインストール → /hooks で 2 つの lifecycle hook を信頼Pi agent harness
pi install git:github.com/DietrichGebert/ponytailOpenCode
リポジトリを checkout したディレクトリから起動し、opencode.json にプラグインを追加:
{ "plugin": ["./.opencode/plugins/ponytail.mjs"] }Cursor など(ルールコピー)
.cursor/rules/ponytail.mdc 等をプロジェクトへコピー。ルール本文を変更したら node scripts/check-rule-copies.js で各コピーの整合を確認する。
@ponytail 等でスキルを明示呼び出し可能。| 名前 | 役割 | 起動 |
|---|---|---|
ponytail | lazy senior dev モード(ラダー・出力規律) | 常時 / /ponytail [lite|full|ultra] |
ponytail-review | diff の過剰実装だけを狩るレビュー(正しさレビューとは別) | /ponytail-review |
ponytail-help | クイックリファレンス | /ponytail-help |
ponytail-review の出力形式
L12-38: stdlib: 27-line validator class. "@" in email, 1 line.
L4: native: moment.js for one format. Intl.DateTimeFormat, 0 deps.
L52-71: delete: retry wrapper around idempotent local call.タグ: delete / stdlib / native / yagni / shrink。1 指摘 1 行。diff の最良結果は行数が減ること。
参考リンク
- GitHub: DietrichGebert/ponytail
- caveman — ベンチマーク比較アーム(prose 圧縮)