chill-agent 1.5.0 → 1.6.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/.claude-plugin/contrast-mcp-launcher.mjs +31 -0
- package/.claude-plugin/plugin.json +8 -3
- package/.cline-plugin/plugin.js +6 -0
- package/.codex-plugin/plugin.json +4 -3
- package/.cursor-plugin/marketplace.json +16 -0
- package/.cursor-plugin/plugin.json +2 -2
- package/.devin-plugin/plugin.json +2 -2
- package/.kimi-plugin/plugin.json +11 -29
- package/.omp-plugin/marketplace.json +15 -0
- package/.openclaw/skills/ponytail/SKILL.md +2 -7
- package/.openclaw/skills/ponytail-audit/SKILL.md +3 -6
- package/.openclaw/skills/ponytail-debt/SKILL.md +3 -4
- package/.openclaw/skills/ponytail-gain/SKILL.md +3 -4
- package/.openclaw/skills/ponytail-help/SKILL.md +3 -3
- package/.openclaw/skills/ponytail-review/SKILL.md +3 -6
- package/.opencode/plugins/ponytail.mjs +1 -1
- package/.qoder-plugin/plugin.json +12 -26
- package/AGENTS.md +32 -19
- package/__init__.py +1 -1
- package/assets/antislop-banner.png +0 -0
- package/assets/band/band.png +0 -0
- package/assets/band/board.png +0 -0
- package/assets/benchmark-3model.svg +21 -0
- package/assets/benchmark-agentic.svg +62 -0
- package/assets/codex-icon.png +0 -0
- package/assets/compare/code/after.webp +0 -0
- package/assets/compare/code/before.webp +0 -0
- package/assets/compare/text/after.webp +0 -0
- package/assets/compare/text/before.webp +0 -0
- package/assets/compare/ui/w-all.webp +0 -0
- package/assets/compare/ui/w-antislop.webp +0 -0
- package/assets/compare/ui/w-design.webp +0 -0
- package/assets/compare/ui/without.webp +0 -0
- package/assets/logo-dark.png +0 -0
- package/assets/logo-dark.svg +115 -0
- package/assets/logo-greenpt-dark.svg +27 -0
- package/assets/logo-greenpt.svg +27 -0
- package/assets/logo.png +0 -0
- package/assets/photoreunion-logo-dark.svg +4 -0
- package/assets/photoreunion-logo-light.svg +4 -0
- package/assets/profile.png +0 -0
- package/assets/retriever-logo-dark.svg +4 -0
- package/assets/retriever-logo-light.svg +4 -0
- package/assets/stories-banner.png +0 -0
- package/assets/v5/audit-es.png +0 -0
- package/assets/v5/audit-ja.png +0 -0
- package/assets/v5/audit-ko.png +0 -0
- package/assets/v5/audit-zh-CN.png +0 -0
- package/assets/v5/audit.png +0 -0
- package/assets/v5/beforeafter-es.png +0 -0
- package/assets/v5/beforeafter-ja.png +0 -0
- package/assets/v5/beforeafter-ko.png +0 -0
- package/assets/v5/beforeafter-zh-CN.png +0 -0
- package/assets/v5/beforeafter.png +0 -0
- package/assets/v5/chart-es.png +0 -0
- package/assets/v5/chart-ja.png +0 -0
- package/assets/v5/chart-ko.png +0 -0
- package/assets/v5/chart-zh-CN.png +0 -0
- package/assets/v5/chart.png +0 -0
- package/assets/v5/hero-es.jpg +0 -0
- package/assets/v5/hero-ja.jpg +0 -0
- package/assets/v5/hero-ko.jpg +0 -0
- package/assets/v5/hero-zh-CN.jpg +0 -0
- package/assets/v5/hero.jpg +0 -0
- package/assets/v5/ladder-es.png +0 -0
- package/assets/v5/ladder-ja.png +0 -0
- package/assets/v5/ladder-ko.png +0 -0
- package/assets/v5/ladder-zh-CN.png +0 -0
- package/assets/v5/ladder.png +0 -0
- package/assets/v5/review-es.png +0 -0
- package/assets/v5/review-ja.png +0 -0
- package/assets/v5/review-ko.png +0 -0
- package/assets/v5/review-zh-CN.png +0 -0
- package/assets/v5/review.png +0 -0
- package/assets/v5/tests-es.png +0 -0
- package/assets/v5/tests-ja.png +0 -0
- package/assets/v5/tests-ko.png +0 -0
- package/assets/v5/tests-zh-CN.png +0 -0
- package/assets/v5/tests.png +0 -0
- package/assets/waitlist-banner-es.png +0 -0
- package/assets/waitlist-banner-ja.png +0 -0
- package/assets/waitlist-banner-ko.png +0 -0
- package/assets/waitlist-banner-zh-CN.png +0 -0
- package/assets/waitlist-banner.png +0 -0
- package/benchmarks/.env.example +2 -0
- package/benchmarks/agentic/README.md +201 -0
- package/benchmarks/agentic/answer.py +288 -0
- package/benchmarks/agentic/compare.py +93 -0
- package/benchmarks/agentic/complete.py +178 -0
- package/benchmarks/agentic/judge.py +198 -0
- package/benchmarks/agentic/run.py +543 -0
- package/benchmarks/agentic/tasks.py +1544 -0
- package/benchmarks/arms/baseline.js +2 -0
- package/benchmarks/arms/caveman-SKILL.md +67 -0
- package/benchmarks/arms/caveman.js +8 -0
- package/benchmarks/arms/ponytail.js +8 -0
- package/benchmarks/behavior.js +54 -0
- package/benchmarks/behavior.yaml +40 -0
- package/benchmarks/correctness.js +291 -0
- package/benchmarks/loc.js +17 -19
- package/benchmarks/promptfooconfig.gemini.yaml +32 -0
- package/benchmarks/promptfooconfig.gpt-newest.yaml +33 -0
- package/benchmarks/promptfooconfig.yaml +41 -0
- package/benchmarks/results/2026-06-12-caveman-vs-ponytail.md +71 -0
- package/benchmarks/results/2026-06-12-v4-hardening-vs-caveman.md +125 -0
- package/benchmarks/results/2026-06-15-llama3.2-local.md +82 -0
- package/benchmarks/results/2026-06-16-correctness-gate-fix.md +113 -0
- package/benchmarks/results/2026-06-16-robustness-audit.md +135 -0
- package/benchmarks/results/2026-06-17-agentic-safety.md +164 -0
- package/benchmarks/results/2026-06-17-cost-verification.md +93 -0
- package/benchmarks/results/2026-06-18-agentic.md +219 -0
- package/benchmarks/results/2026-06-22-issue-245-217-comprehension.md +98 -0
- package/benchmarks/results/2026-10-07-agentic.md +186 -0
- package/cli/index.mjs +241 -0
- package/cli/lib/banner.mjs +21 -0
- package/cli/lib/install.mjs +498 -0
- package/cli/lib/settings.mjs +48 -0
- package/cli/package-lock.json +87 -0
- package/cli/package.json +42 -0
- package/cli/scripts/smoke-test.mjs +95 -0
- package/cli/scripts/smoke-worker.mjs +411 -0
- package/cli/scripts/sync-skills.mjs +81 -0
- package/examples/email-validation.md +156 -0
- package/examples/group-by.md +35 -0
- package/examples/infinite-scroll.md +58 -0
- package/examples/number-formatting.md +37 -0
- package/examples/rate-limit.md +272 -0
- package/examples/react-countdown.md +390 -0
- package/examples/url-params.md +41 -0
- package/gemini-extension.json +2 -2
- package/hooks/band/board.ts +560 -0
- package/hooks/band/logo.ts +3 -0
- package/hooks/band/metrics.ts +311 -0
- package/hooks/band/register.tsx +495 -0
- package/hooks/band/types.d.ts +34 -0
- package/hooks/claude-band.json +6 -0
- package/hooks/claude-codex-hooks.json +34 -4
- package/hooks/copilot-hooks.json +12 -2
- package/hooks/cursor-hooks.json +2 -2
- package/hooks/ponytail-band-import.js +274 -0
- package/hooks/ponytail-config.js +175 -0
- package/hooks/ponytail-map.js +111 -0
- package/hooks/ponytail-subagent.js +94 -0
- package/hooks/qoder-hooks.json +19 -4
- package/i18n/README.ko.md +230 -0
- package/package.json +12 -7
- package/pi-extension/test/extension.test.js +367 -0
- package/pi-extension/test/helpers.test.js +179 -0
- package/plugin.yaml +21 -12
- package/rules/antislop.mdc +18 -0
- package/scripts/build-openclaw-skills.js +60 -0
- package/scripts/check-repo.mjs +389 -0
- package/scripts/publish-openclaw-skills.js +75 -0
- package/scripts/skill-index.mjs +81 -0
- package/skills/antislop/SKILL.md +700 -0
- package/skills/antislop/VERSION +1 -0
- package/skills/antislop-code/SKILL.md +128 -0
- package/skills/antislop-copywriting/SKILL.md +407 -0
- package/skills/antislop-human/LICENSE-web-quality-skills +21 -0
- package/skills/antislop-human/SKILL.md +204 -0
- package/skills/antislop-human/contrast-check.py +168 -0
- package/skills/antislop-human/contrast-mcp.py +121 -0
- package/skills/antislop-human/references/A11Y-PATTERNS.md +249 -0
- package/skills/antislop-human/references/WCAG.md +127 -0
- package/skills/antislop-layoutmobile/SKILL.md +170 -0
- package/skills/antislop-ui/LICENSE-web-quality-skills +21 -0
- package/skills/antislop-ui/SKILL.md +344 -0
- package/skills/antislop-ui/references/CORE-WEB-VITALS.md +181 -0
- package/skills/antislop-ui/references/WEB-BASELINE.md +28 -0
- package/skills/plugin.json +5 -0
- package/src/package.json +3 -0
- package/tests/activation-map.test.js +63 -0
- package/tests/band-import.test.js +111 -0
- package/tests/band.test.tsx +520 -0
- package/tests/behavior.test.js +80 -0
- package/tests/gemini-extension.test.js +2 -2
- package/tests/grok-plugin.test.js +1 -1
- package/tests/hermes-plugin.test.js +1 -1
- package/tests/hooks-windows.test.js +205 -0
- package/tests/kimi-plugin.test.js +1 -1
- package/tests/map.test.js +30 -0
- package/tests/package-scripts.test.js +35 -0
- package/tests/package.test.js +23 -0
- package/tests/uninstall.test.js +202 -0
- /package/bin/{chill-agent.js → chill-agent.mjs} +0 -0
- /package/tests/{manifests.test.js → manifests.test.mjs} +0 -0
- /package/tests/{rules.test.js → rules.test.mjs} +0 -0
|
@@ -0,0 +1,71 @@
|
|
|
1
|
+
# Caveman vs Ponytail — 2026-06-12
|
|
2
|
+
|
|
3
|
+
5 coding tasks × fresh subagent per config, same model. Tokens = agent total
|
|
4
|
+
(includes thinking). Code lines = fenced blocks in the deliverable, approx.
|
|
5
|
+
n=1 per cell — durations carry noise.
|
|
6
|
+
|
|
7
|
+
## Ponytail v1 (before this benchmark)
|
|
8
|
+
|
|
9
|
+
| Task | Baseline | Caveman | Ponytail v1 |
|
|
10
|
+
|---|---|---|---|
|
|
11
|
+
| email | 31,971 tok · 104s · ~34 loc | 26,464 · 20s · ~25 | 27,582 · 32s · 6 |
|
|
12
|
+
| debounce | 23,966 · 25s · ~38 | 26,496 · 19s · ~36 | 27,812 · 33s · 6 |
|
|
13
|
+
| csv-sum | 22,607 · 11s · 6 | 26,062 · 13s · 6 | 26,867 · 20s · 7 |
|
|
14
|
+
| react-countdown | 44,629 · 208s · ~190 | 26,656 · 21s · ~30 | 28,748 · 49s · 13 |
|
|
15
|
+
| rate-limit | 38,782 · 131s · ~25 | 32,732 · 63s · ~20 | 32,579 · 93s · ~21 |
|
|
16
|
+
| **Total** | **161,955 · 479s · ~293** | **138,410 · 136s · ~117** | **143,588 · 228s · ~53** |
|
|
17
|
+
|
|
18
|
+
### v1 findings
|
|
19
|
+
|
|
20
|
+
1. Code minimalism: ponytail dominated (2.2× fewer lines than caveman, 5.5× fewer than baseline).
|
|
21
|
+
2. Total tokens: caveman won by ~4% — ponytail wrote minimal code, then long
|
|
22
|
+
"skipped on purpose" essays. Prose ate the code savings.
|
|
23
|
+
3. Speed: caveman 136s vs ponytail 228s — ponytail deliberated about what not to build.
|
|
24
|
+
4. Floor effect: on already-minimal tasks (csv-sum) both skills pay ~3k tokens
|
|
25
|
+
skill-read tax over baseline.
|
|
26
|
+
|
|
27
|
+
## Ponytail v2 (after fixes)
|
|
28
|
+
|
|
29
|
+
v2 changes: Output cap (code + ≤3 short lines, "if the explanation is longer
|
|
30
|
+
than the code, delete the explanation"), ladder-is-a-reflex clause
|
|
31
|
+
(anti-deliberation), ship-and-question rule (never stall on "do you need X?").
|
|
32
|
+
|
|
33
|
+
| Task | Ponytail v2 | Δ vs v1 | Δ vs caveman |
|
|
34
|
+
|---|---|---|---|
|
|
35
|
+
| email | 26,705 · 21s · 5 loc | −877 tok · −11s | +241 tok · +1s |
|
|
36
|
+
| debounce | 27,185 · 25s · 6 | −627 · −8s | +689 · +6s |
|
|
37
|
+
| csv-sum | 26,278 · 15s · 6 | −589 · −5s | +216 · +2s |
|
|
38
|
+
| react-countdown | 27,598 · 29s · 13 | −1,150 · −20s | +942 · +8s |
|
|
39
|
+
| rate-limit | 28,858 · 48s · 17 | −3,721 · −45s | −3,874 · −15s |
|
|
40
|
+
| **Total** | **136,624 · 158s · 47** | **−6,964 (−4.8%) · −70s (−31%)** | **−1,786 (−1.3%) · +22s** |
|
|
41
|
+
|
|
42
|
+
## Ponytail v3 (skill file compressed)
|
|
43
|
+
|
|
44
|
+
v3 change: SKILL.md 115 → 95 lines, same substance — the minimalism skill
|
|
45
|
+
should not be 2× caveman's length. Cuts read cost per invocation and
|
|
46
|
+
injection cost per session.
|
|
47
|
+
|
|
48
|
+
| Task | Ponytail v3 | Δ vs v2 | Δ vs caveman |
|
|
49
|
+
|---|---|---|---|
|
|
50
|
+
| email | 26,573 · 19s · 5 loc | −132 · −2s | +109 · −1s |
|
|
51
|
+
| debounce | 26,745 · 22s · 5 | −440 · −3s | +249 · +3s |
|
|
52
|
+
| csv-sum | 26,251 · 15s · 6 | −27 · 0s | +189 · +2s |
|
|
53
|
+
| react-countdown | 26,961 · 22s · 13 | −637 · −7s | +305 · +1s |
|
|
54
|
+
| rate-limit | 29,179 · 49s · 18 | +321 · +1s | −3,553 · −14s |
|
|
55
|
+
| **Total** | **135,709 · 127s · 47** | **−915 · −31s (−20%)** | **−2,701 (−2.0%) · −9s (−7%)** |
|
|
56
|
+
|
|
57
|
+
## Verdict (v3)
|
|
58
|
+
|
|
59
|
+
| Area | Winner |
|
|
60
|
+
|---|---|
|
|
61
|
+
| Code size | **Ponytail** — 47 vs 117 lines (2.5×) |
|
|
62
|
+
| Deliverable prose | **Ponytail** — capped at 3 skip-lines, under caveman's gotcha lists |
|
|
63
|
+
| Total tokens (cost) | **Ponytail** — 135.7k vs 138.4k (−2.0%) |
|
|
64
|
+
| Wall time | **Ponytail** — 127s vs 136s (−7%; n=1, treat as parity-or-better) |
|
|
65
|
+
| Follow-up prevention | **Ponytail** — every skip names its escalation trigger |
|
|
66
|
+
|
|
67
|
+
Both skills demolish the no-skill baseline: −16% tokens, ~3× faster, and the
|
|
68
|
+
baseline's degenerate cases (190-line countdown dashboard, 208s) simply don't
|
|
69
|
+
happen. Remaining ~3.6k floor tax vs baseline on trivial tasks is mostly the
|
|
70
|
+
benchmark's explicit SKILL.md read — production sessions get rules injected
|
|
71
|
+
by the SessionStart hook and don't pay it.
|
|
@@ -0,0 +1,125 @@
|
|
|
1
|
+
# Ponytail v4 hardening — A–F benchmark vs Caveman (2026-06-12)
|
|
2
|
+
|
|
3
|
+
Response to the hardening brief in `C:\dev\ponytail-bench\PONYTAIL-BENCHMARK-WRITEUP.md`.
|
|
4
|
+
Harness reused as-is: same 6 tasks (specs reconstructed in `ponytail-bench\specs.md` —
|
|
5
|
+
the originals were not preserved; both new arms got identical text), same scorer
|
|
6
|
+
(`score.py`, arms now auto-discovered), same adversarial probes (`probe_e.py`,
|
|
7
|
+
`probe_f.py`), same extension protocol (phase-1 git commit, cost = `git diff
|
|
8
|
+
--numstat` insertions + new-file LOC). Caveman = `JuliusBrussee/caveman` SKILL.md
|
|
9
|
+
verbatim (full level), saved at `ponytail-bench\caveman-SKILL.md`. One fresh
|
|
10
|
+
subagent per task × arm, same model for all 16 runs. Caveat: this model/harness
|
|
11
|
+
differs from the original Cursor runs, so comparisons to the old treatment
|
|
12
|
+
numbers are directional; the ponytail4-vs-caveman head-to-head is same-model.
|
|
13
|
+
|
|
14
|
+
## v4 changes (the hardening, ~10 lines of prompt total)
|
|
15
|
+
|
|
16
|
+
1. **Test reflex** (brief 5.1): non-trivial logic leaves ONE runnable check —
|
|
17
|
+
assert-based `demo()`/`__main__` self-check or one small `test_*.py`. No
|
|
18
|
+
frameworks. One-liners need no test.
|
|
19
|
+
2. **Ceiling comments** (5.2): a `ponytail:` shortcut with a known ceiling must
|
|
20
|
+
name the ceiling and the upgrade path in the comment.
|
|
21
|
+
3. **Robust variant rule** (5.3): between two same-size stdlib options, take the
|
|
22
|
+
edge-case-correct one.
|
|
23
|
+
|
|
24
|
+
Applied to SKILL.md, all five cross-agent rule copies, the hook fallback, and a
|
|
25
|
+
guard line in ponytail-review (never flag the minimal check as bloat).
|
|
26
|
+
|
|
27
|
+
## Build phase — non-blank LOC / .py files (scorer-verified)
|
|
28
|
+
|
|
29
|
+
| Task | Control (orig) | Treatment v3 (orig) | **Ponytail v4** | **Caveman** |
|
|
30
|
+
|---|--:|--:|--:|--:|
|
|
31
|
+
| A log CLI | 970 / 13 | 150 / 1 | **145 / 2** | 283 / 1 |
|
|
32
|
+
| B file sync | 587 / 9 | 175 / 2 | **99 / 1** | 228 / 2 |
|
|
33
|
+
| C dispatcher | 726 / 13 | 85 / 1 | **73 / 1** | 396 / 10 |
|
|
34
|
+
| D validation | 343 / 8 | 93 / 1 | **70 / 1** | 218 / 3 |
|
|
35
|
+
| E auth | 155 / 1 | 74 / 1 | **49 / 1** | 148 / 1 |
|
|
36
|
+
| F ledger | 162 / 1 | 86 / 1 | **54 / 1** | 167 / 1 |
|
|
37
|
+
| **Total** | 2943 | 663 | **490** | 1440 |
|
|
38
|
+
|
|
39
|
+
v4 is at or below v3 on every task (−3% to −43%) **despite now shipping a
|
|
40
|
+
runnable check in all six arms** — the test reflex did not cause bloat creep.
|
|
41
|
+
v4 is 34% of Caveman's size. Task A is the one place Caveman has fewer .py
|
|
42
|
+
files (1 vs 2): v4's second file is the 24-line regression check Caveman
|
|
43
|
+
doesn't ship — deleting it to win file count would sacrifice the safety clause
|
|
44
|
+
to win on size, which the brief forbids.
|
|
45
|
+
|
|
46
|
+
## Extension phase (tasks C, D — surprise requests, git-measured)
|
|
47
|
+
|
|
48
|
+
| Metric | C v4 | C caveman | D v4 | D caveman |
|
|
49
|
+
|---|--:|--:|--:|--:|
|
|
50
|
+
| Lines changed (insertions + new-file LOC) | **41** | 156 | **55** | 257 |
|
|
51
|
+
| Files touched | 1 | 7 | 1 | 3 |
|
|
52
|
+
| Still correct after | yes | yes | yes | yes |
|
|
53
|
+
|
|
54
|
+
v4 honored the requested seams (duck-typed registry in C, `@rule` registry in
|
|
55
|
+
D) and extended 74–79% cheaper. Both arms' extended demos re-run exit 0.
|
|
56
|
+
|
|
57
|
+
## Safety — adversarial probes (independently executed)
|
|
58
|
+
|
|
59
|
+
| Probe | v4 | caveman |
|
|
60
|
+
|---|--:|--:|
|
|
61
|
+
| Security, task E (8 checks) | **8/8** | 8/8 |
|
|
62
|
+
| Concurrency, task F (6 checks) | **6/6** | 6/6 |
|
|
63
|
+
|
|
64
|
+
No regression from the added rules. v4's E chose PBKDF2-HMAC-SHA256 (600k
|
|
65
|
+
iters) + 16-byte `secrets` salt + `hmac.compare_digest` + `token_urlsafe(32)`;
|
|
66
|
+
F kept integer cents + a global lock with the ceiling comment naming the
|
|
67
|
+
per-account-lock upgrade (5.2 working as designed; Caveman built per-account
|
|
68
|
+
locks at 3× the LOC).
|
|
69
|
+
|
|
70
|
+
## Correctness
|
|
71
|
+
|
|
72
|
+
19/19 independent re-runs exit 0 (14 build demos/tests + 5 post-extension).
|
|
73
|
+
|
|
74
|
+
## Acceptance criteria (brief §5.6)
|
|
75
|
+
|
|
76
|
+
1. Probes 100% — **pass** (8/8 + 6/6).
|
|
77
|
+
2. Every treatment arm ships a runnable check — **pass** (A: `test_loganalyze.py`;
|
|
78
|
+
B–F: assert-based `__main__` checks; all executed). This was the #1 gap (was 1/4).
|
|
79
|
+
3. LOC within ~20% of v3 treatment numbers — **pass on intent**: every arm at or
|
|
80
|
+
below v3 (A −3%, C −14%; B/D/E/F 25–43% *below* — leaner, not bloated).
|
|
81
|
+
4. Ceiling-bearing `ponytail:` comments name upgrade paths — **pass**, verified
|
|
82
|
+
per arm: global lock→per-account locks (F), no token TTL→add TTL (E),
|
|
83
|
+
sequential sends→async/threaded + hardcoded route→routing table (C),
|
|
84
|
+
special-cased `unique`→DATASET_RULES registry (D), observed-hours stats→
|
|
85
|
+
impute full range (A), no empty-dir handling→dir pass (B).
|
|
86
|
+
5. Head-to-head vs Caveman — **pass**: ≥ on every axis, strictly better on three.
|
|
87
|
+
- Safety: tie at 100% (≥, never regressed to win on size).
|
|
88
|
+
- Size: LOC strictly better 6/6; files ≤ on 5/6 (A caveat above).
|
|
89
|
+
- Extension cost: strictly better on both tasks.
|
|
90
|
+
- Reviewability: strictly better — every v4 simplification is `ponytail:`-marked
|
|
91
|
+
with its ceiling; Caveman's code marks only spec-allowed simulated transports,
|
|
92
|
+
and its design trade-offs live in the chat report, invisible to a later reviewer.
|
|
93
|
+
|
|
94
|
+
## Addendum: same-model control arm (control2, added same day)
|
|
95
|
+
|
|
96
|
+
The control numbers above were inherited from the original Cursor harness,
|
|
97
|
+
which could not expose token counts. Six fresh `task*-control2` arms were run
|
|
98
|
+
through this harness (no skill, "build production-normal", same model, same
|
|
99
|
+
specs), making all three arms same-model. Control2 passes both probes (8/8,
|
|
100
|
+
6/6) and all 10 demo/test runs exit 0; extensions on C and D re-verified.
|
|
101
|
+
|
|
102
|
+
| Whole benchmark (6 builds + C/D extensions) | Control2 | Caveman | Ponytail v4 |
|
|
103
|
+
|---|--:|--:|--:|
|
|
104
|
+
| Build LOC | 3,629 | 1,440 | **490** |
|
|
105
|
+
| Build LOC per task (A-F) | 946/656/808/677/260/282 | 283/228/396/218/148/167 | **145/99/73/70/49/54** |
|
|
106
|
+
| Extension lines changed (C, D) | 378, 737 | 156, 257 | **41, 55** |
|
|
107
|
+
| Agent tokens, total | 430,697 | 290,546 | **229,370 (-47% vs control2)** |
|
|
108
|
+
| Agent wall time, total | 2,749s | 1,596s | **821s (3.3x)** |
|
|
109
|
+
| Probes | 8/8 + 6/6 | 8/8 + 6/6 | 8/8 + 6/6 |
|
|
110
|
+
|
|
111
|
+
Wall times carry parallel-scheduling noise (arms ran concurrently, n=1 per
|
|
112
|
+
cell); token counts are exact from agent telemetry. The README "Numbers"
|
|
113
|
+
section now cites this same-model dataset and retires the older 5-task v3
|
|
114
|
+
figures (still recorded in `2026-06-12-caveman-vs-ponytail.md`).
|
|
115
|
+
|
|
116
|
+
## Residual (honest notes)
|
|
117
|
+
|
|
118
|
+
- A's spike stats still use observed-hours-only mean+3σ rather than a
|
|
119
|
+
leave-one-out/imputed baseline (Caveman zero-filled the hour range). The 5.3
|
|
120
|
+
rule softened but did not eliminate the naive-algorithm tendency; the choice
|
|
121
|
+
is now at least documented with its upgrade path (5.2). Candidate for a
|
|
122
|
+
future eval if it bites in practice.
|
|
123
|
+
- Caveman is a prose-compression skill that explicitly writes code "normal" —
|
|
124
|
+
it loses on code size by design. The meaningful result is that adding the
|
|
125
|
+
test reflex did not erode ponytail's size advantage or its 100% probe record.
|
|
@@ -0,0 +1,82 @@
|
|
|
1
|
+
# Local model benchmark: llama3.2 via Ollama — 2026-06-15
|
|
2
|
+
|
|
3
|
+
Same 5 tasks as the Claude benchmark, same three arms (baseline / caveman / ponytail),
|
|
4
|
+
run against a local **llama3.2:latest** (3.2B, Q4_K_M) via Ollama on a Windows 11 machine.
|
|
5
|
+
Tooling: `benchmarks/benchmark-local.py` (no promptfoo needed).
|
|
6
|
+
|
|
7
|
+
> **Updated 2026-06-15:** the LOC counter now counts bare, unfenced code. It
|
|
8
|
+
> previously counted only fenced code blocks and scored everything else as 0,
|
|
9
|
+
> which silently deflated any arm whose output happened to skip the fences (small
|
|
10
|
+
> models do this often). Numbers below use the corrected counter at n=5 median.
|
|
11
|
+
> Absolute times reflect this machine (GPU-accelerated); compare arms within a
|
|
12
|
+
> run, not against an earlier CPU-bound machine.
|
|
13
|
+
|
|
14
|
+
## Results (n=5, median)
|
|
15
|
+
|
|
16
|
+
**Code LOC**
|
|
17
|
+
|
|
18
|
+
| arm | email | debounce | csv-sum | countdown | rate-limit | **TOTAL** |
|
|
19
|
+
|---|--:|--:|--:|--:|--:|--:|
|
|
20
|
+
| baseline | 16 | 18 | 22 | 37 | 16 | **109** |
|
|
21
|
+
| caveman | 16 | 21 | 18 | 46 | 32 | **133** |
|
|
22
|
+
| ponytail | 17 | 22 | 18 | 52 | 28 | **137** |
|
|
23
|
+
|
|
24
|
+
**Time (seconds)**
|
|
25
|
+
|
|
26
|
+
| arm | email | debounce | csv-sum | countdown | rate-limit | **TOTAL** |
|
|
27
|
+
|---|--:|--:|--:|--:|--:|--:|
|
|
28
|
+
| baseline | 3.1 | 3.7 | 3.6 | 4.2 | 4.8 | **19.4** |
|
|
29
|
+
| caveman | 4.1 | 4.2 | 3.6 | 4.4 | 4.8 | **21.1** |
|
|
30
|
+
| ponytail | 4.1 | 4.2 | 3.8 | 4.8 | 4.9 | **21.8** |
|
|
31
|
+
|
|
32
|
+
## Key findings
|
|
33
|
+
|
|
34
|
+
**On llama3.2 the LOC effect is inside the noise floor.** At temperature 0.7 the
|
|
35
|
+
per-run totals swing hard: across the five runs, ponytail landed anywhere from
|
|
36
|
+
17% *below* baseline to 50% *above* it. The n=5 median came out +26%; a separate
|
|
37
|
+
n=3 median came out −17%. The aggregate itself flips sign depending on the
|
|
38
|
+
sample, and the countdown task alone ranged 19 to 74 LOC on baseline. There is no
|
|
39
|
+
stable LOC reduction to report.
|
|
40
|
+
|
|
41
|
+
**Ponytail does not transfer to llama3.2.** The 80-94% LOC reduction seen on
|
|
42
|
+
Claude is simply absent: the signal is lost in run-to-run variance. The one
|
|
43
|
+
consistent effect is on time, and it goes the wrong way: ponytail is ~10-15%
|
|
44
|
+
*slower* than baseline (more system-prompt tokens to process), never the 3-6x
|
|
45
|
+
speedup seen on Claude.
|
|
46
|
+
|
|
47
|
+
**Why:** ponytail is a prompt-engineering skill calibrated on Claude models,
|
|
48
|
+
which are trained to follow detailed system instructions. A 3.2B quantised model
|
|
49
|
+
absorbs the rules only partially and adds prose justifying its choices, paying
|
|
50
|
+
the instruction-following cost without reliably converting it into less code.
|
|
51
|
+
|
|
52
|
+
## Reproduce
|
|
53
|
+
|
|
54
|
+
`benchmark-local.py` was removed from `main` in #1042. Check out the last commit that still has it, then run the steps below:
|
|
55
|
+
|
|
56
|
+
```bash
|
|
57
|
+
git checkout 08e952d7a8057a57ce561ff1330d093fd92eec67
|
|
58
|
+
```
|
|
59
|
+
|
|
60
|
+
Install Ollama and pull a model, then run from the repo root:
|
|
61
|
+
|
|
62
|
+
```bash
|
|
63
|
+
ollama pull llama3.2
|
|
64
|
+
python benchmarks/benchmark-local.py --model llama3.2 --repeat 5
|
|
65
|
+
```
|
|
66
|
+
|
|
67
|
+
At this model size the LOC signal is noisy; raise `--repeat` (or lower the
|
|
68
|
+
sampling temperature in the script) before reading anything into the totals.
|
|
69
|
+
|
|
70
|
+
Optional flags:
|
|
71
|
+
|
|
72
|
+
```
|
|
73
|
+
--repeat N Runs per cell; median is reported (default: 1)
|
|
74
|
+
--ollama-url URL Ollama base URL (default: http://localhost:11434)
|
|
75
|
+
```
|
|
76
|
+
|
|
77
|
+
## Takeaway
|
|
78
|
+
|
|
79
|
+
The benchmark claims in the README are accurate for the models tested (Haiku,
|
|
80
|
+
Sonnet, Opus). For local/small models, expect the gains to shrink into the noise
|
|
81
|
+
until instruction-following reaches a threshold comparable to Claude Haiku or
|
|
82
|
+
better.
|
|
@@ -0,0 +1,113 @@
|
|
|
1
|
+
# Correctness under Ponytail: gate fixes + GPT-mini reproduction (2026-06-16)
|
|
2
|
+
|
|
3
|
+
Context: [issue #65](https://github.com/DietrichGebert/ponytail/issues/65) asked whether
|
|
4
|
+
Ponytail degrades model performance. A community run (Pyseph) reported a large correctness
|
|
5
|
+
drop on `gpt-4.1-mini` (10/15 with Ponytail vs 15/15 without) and a small one on
|
|
6
|
+
`gpt-5.4-mini` (14/15 vs 15/15).
|
|
7
|
+
|
|
8
|
+
Investigating that, the correctness gate itself turned out to be the main culprit. This
|
|
9
|
+
writeup documents the gate bugs, the fixes, and a clean reproduction of Pyseph's exact
|
|
10
|
+
model setup.
|
|
11
|
+
|
|
12
|
+
## TL;DR
|
|
13
|
+
|
|
14
|
+
- The `correct` gate had two bugs that **under-reported correctness for terse models** — it
|
|
15
|
+
could not read unfenced code, and the debounce task tested for a deliverable the prompt
|
|
16
|
+
never asked for.
|
|
17
|
+
- After fixing the gate, on a clean `n=20` run of Pyseph's exact models, the large drop
|
|
18
|
+
**does not reproduce**: `gpt-4.1-mini` is 100% with *and* without Ponytail.
|
|
19
|
+
- Ponytail roughly **halves** median code size, the original headline claim, with no
|
|
20
|
+
meaningful correctness cost on instruction-following models.
|
|
21
|
+
- One genuine, small Ponytail defect surfaced and is reported honestly below.
|
|
22
|
+
|
|
23
|
+
## The gate bugs
|
|
24
|
+
|
|
25
|
+
1. **Unfenced code was scored as "no code blocks."** `extractBlocks()` only matched
|
|
26
|
+
```` ```fenced``` ```` blocks. Models that reply with bare code (more common under
|
|
27
|
+
Ponytail's terse style, and frequent on `gpt-5.4-mini`) scored an automatic fail even
|
|
28
|
+
when the code was correct. This alone accounted for 41 of 74 failures in the first GPT run.
|
|
29
|
+
2. **The debounce task tested the wrong deliverable.** The prompt said *"add debounce to a
|
|
30
|
+
search input"* but the check expected a reusable `debounce(fn, delay)` utility it could
|
|
31
|
+
call. A correct inline answer (`input.addEventListener(... clearTimeout ...)`) failed with
|
|
32
|
+
`searchInput is not defined`. This accounted for 31 of 74 failures, and it penalized the
|
|
33
|
+
literal, minimal answer while rewarding code that over-built a utility nobody asked for.
|
|
34
|
+
|
|
35
|
+
Both are fixed: `extractBlocks()` now falls back to treating the whole response as one code
|
|
36
|
+
block when no fence is present (and tolerates CRLF), and the debounce task now asks for the
|
|
37
|
+
reusable `debounce(fn, delay)` function the check actually verifies.
|
|
38
|
+
|
|
39
|
+
## Method
|
|
40
|
+
|
|
41
|
+
Two arms (baseline = no skill, ponytail), Pyseph's two models, the five repo tasks, `n=20`
|
|
42
|
+
per cell, run serially (`--max-concurrency 1`) so transient quota 429s never reduced the
|
|
43
|
+
denominators. Code is executed where possible (email, debounce, CSV); React/FastAPI are
|
|
44
|
+
structural checks (see the README caveat). Claude numbers are a free re-score of the
|
|
45
|
+
committed `output-10x.json` responses through the fixed gate (`n=10`, 4 tasks — the saved
|
|
46
|
+
debounce responses predate the prompt fix and are excluded).
|
|
47
|
+
|
|
48
|
+
## Results
|
|
49
|
+
|
|
50
|
+
### GPT-mini (clean `n=20`, 0 errors, full denominators)
|
|
51
|
+
|
|
52
|
+
| model | baseline | ponytail | median LOC (base → pony) |
|
|
53
|
+
|---|--:|--:|--:|
|
|
54
|
+
| gpt-4.1-mini | 100/100 | 100/100 | 15 → 7 |
|
|
55
|
+
| gpt-5.4-mini | 100/100 | 98/100 | 16 → 7 |
|
|
56
|
+
|
|
57
|
+
Pyseph's reported `gpt-4.1-mini` drop (10/15 ≈ 67%) does not reproduce — it scores 100% here.
|
|
58
|
+
The difference is the gate fixes; the original numbers were measuring unfenced code and the
|
|
59
|
+
debounce deliverable mismatch, not model degradation.
|
|
60
|
+
|
|
61
|
+
### Claude (fixed gate, re-score of committed responses, `n=10`, 4 tasks)
|
|
62
|
+
|
|
63
|
+
| model | baseline | ponytail |
|
|
64
|
+
|---|--:|--:|
|
|
65
|
+
| claude-haiku-4-5 | 38/40 (95%) | 40/40 (100%) |
|
|
66
|
+
| claude-opus-4-8 | 40/40 (100%) | 40/40 (100%) |
|
|
67
|
+
| claude-sonnet-4-6 | 28/40 (70%) | 40/40 (100%) |
|
|
68
|
+
|
|
69
|
+
On instruction-following models Ponytail ties or slightly *beats* baseline. The low
|
|
70
|
+
`sonnet` baseline number is itself an over-engineering failure: the unconstrained validator
|
|
71
|
+
returns a rich `{is_valid, message}` dict instead of a bool, so `if validate_email(addr)` is
|
|
72
|
+
always truthy and accepts every address — a real bug Ponytail's `return bool(...)` avoids.
|
|
73
|
+
|
|
74
|
+
## The one real Ponytail defect
|
|
75
|
+
|
|
76
|
+
On `gpt-5.4-mini`, 2 of 20 Ponytail email runs failed because the model reached for the
|
|
77
|
+
laziest stdlib option:
|
|
78
|
+
|
|
79
|
+
```python
|
|
80
|
+
from email.utils import parseaddr
|
|
81
|
+
def is_valid_email(email):
|
|
82
|
+
_, addr = parseaddr(email)
|
|
83
|
+
return addr == email and "@" in addr # accepts "@missing-local.com"
|
|
84
|
+
```
|
|
85
|
+
|
|
86
|
+
`parseaddr` does not require a local part, so `"@missing-local.com"` is accepted. This is a
|
|
87
|
+
genuine (if minor) cost of pushing toward one-liners: occasionally the chosen stdlib helper
|
|
88
|
+
has an edge-case hole. The other 18 runs used a regex and passed.
|
|
89
|
+
|
|
90
|
+
## Reproduce
|
|
91
|
+
|
|
92
|
+
`promptfooconfig.gpt.yaml` was removed from `main` in #1042. Check out the last commit that still has it, then run the steps below:
|
|
93
|
+
|
|
94
|
+
```bash
|
|
95
|
+
git checkout 08e952d7a8057a57ce561ff1330d093fd92eec67
|
|
96
|
+
```
|
|
97
|
+
|
|
98
|
+
```bash
|
|
99
|
+
# GPT arms (needs OPENAI_API_KEY in ../.env)
|
|
100
|
+
cd benchmarks
|
|
101
|
+
npx promptfoo@latest eval -c promptfooconfig.gpt.yaml --env-file ../.env --repeat 20 --max-concurrency 1
|
|
102
|
+
|
|
103
|
+
# Claude re-score of committed responses through the fixed gate
|
|
104
|
+
node -e 'const c=require("./correctness.js"),d=require("./output-10x.json");/* score d.results.results through c */'
|
|
105
|
+
```
|
|
106
|
+
|
|
107
|
+
## Takeaway
|
|
108
|
+
|
|
109
|
+
The "Ponytail hurts correctness" reports trace to a benchmark that could not read terse
|
|
110
|
+
output, not to the skill. With the gate fixed, the LOC win holds and correctness is flat on
|
|
111
|
+
capable models. The honest caveats remain: the effect is model-dependent (small/local models
|
|
112
|
+
follow the ladder poorly — see the llama3.2 writeup), and chasing the shortest answer can
|
|
113
|
+
occasionally pick a stdlib helper with an edge-case gap.
|
|
@@ -0,0 +1,135 @@
|
|
|
1
|
+
# Robustness audit: does ponytail degrade weak models? (2026-06-16)
|
|
2
|
+
|
|
3
|
+
Follow-up to [issue #65](https://github.com/DietrichGebert/ponytail/issues/65). After fixing
|
|
4
|
+
the correctness-gate bugs, the open question was the real one: does Ponytail's push toward
|
|
5
|
+
the shortest solution make weak models produce *wrong* code on edge cases? This audit
|
|
6
|
+
answers it directly, with a deliberately hostile test set and high sample counts.
|
|
7
|
+
|
|
8
|
+
## TL;DR
|
|
9
|
+
|
|
10
|
+
- Across **12 classic edge-case traps** (off-by-one, n=0, leap-century, subtractive Roman,
|
|
11
|
+
deep nesting, …) on **two weak models** (`gpt-4.1-mini`, `gpt-5.4-mini`), Ponytail holds
|
|
12
|
+
**baseline parity** — it does not produce more wrong answers than the unconstrained model.
|
|
13
|
+
- The **one** measured soft spot is email validation, and it is **provider-specific**.
|
|
14
|
+
OpenAI models, at every size, sometimes reach for `email.utils.parseaddr` (a parser, not a
|
|
15
|
+
validator) under "stdlib-first" pressure and accept `"@missing-local.com"`. On Claude,
|
|
16
|
+
ponytail's target platform, email is **100%** (haiku/sonnet/opus, n=40 each).
|
|
17
|
+
- The slip is **not fixable by skill text**: 8 distinct SKILL.md edits (including an n=100
|
|
18
|
+
A/B, 96% → 95%) all scored ≤ the current skill, several worse, all bloating LOC. Counter-
|
|
19
|
+
instructions make small models overthink and fail *more*. Nothing was shipped — adding
|
|
20
|
+
skill text that doesn't move the number is exactly the cargo-cult Ponytail exists to avoid.
|
|
21
|
+
|
|
22
|
+
## Method
|
|
23
|
+
|
|
24
|
+
`baseline` (no skill) vs `ponytail` (full SKILL.md), single-shot, default params,
|
|
25
|
+
`gpt-4.1-mini` and `gpt-5.4-mini`. Each task runs generated code against edge-case
|
|
26
|
+
assertions. Every check is **self-verified**: a known-correct and a known-lazy-wrong
|
|
27
|
+
reference must pass/fail respectively before any model output is scored
|
|
28
|
+
(`node robustness-audit.js --selftest`, 16/16). Runs were serial to avoid quota 429s
|
|
29
|
+
shrinking denominators.
|
|
30
|
+
|
|
31
|
+
## Edge-case traps (n=20/cell)
|
|
32
|
+
|
|
33
|
+
All 12 algorithmic tasks: `baseline 20/20 == ponytail 20/20` on **both** models. Examples
|
|
34
|
+
of the traps (the lazy version passes the common case, fails the edge):
|
|
35
|
+
|
|
36
|
+
| task | the trap a lazy impl misses |
|
|
37
|
+
|---|---|
|
|
38
|
+
| is_prime | n = 0, 1, negatives |
|
|
39
|
+
| factorial / fibonacci | n = 0 |
|
|
40
|
+
| binary_search | empty list, target at the last index (off-by-one) |
|
|
41
|
+
| is_leap_year / days_in_month | 1900 not leap, 2000 leap (century rule) |
|
|
42
|
+
| int_to_roman | subtractive forms (4=IV, 9=IX, 40=XL) |
|
|
43
|
+
| flatten | nesting deeper than one level |
|
|
44
|
+
| clamp | value already in range |
|
|
45
|
+
| chunk | trailing remainder |
|
|
46
|
+
|
|
47
|
+
The only sub-20 cell in the first run was `gpt-5.4-mini` flatten at 19/20 — a single
|
|
48
|
+
stochastic miss that **did not reproduce**: 50/50 at n=50. (`clamp` showed 19/19, i.e. one
|
|
49
|
+
API error, not a wrong answer.)
|
|
50
|
+
|
|
51
|
+
## Validators: the email slip is provider-specific
|
|
52
|
+
|
|
53
|
+
The one place ponytail measurably affects correctness is **email validation**, via the
|
|
54
|
+
parse ≠ validate trap: under "stdlib-first" pressure a model reaches for
|
|
55
|
+
`email.utils.parseaddr` — a *parser* that accepts malformed input like `@missing-local.com`
|
|
56
|
+
— instead of writing an explicit check. The split is by **provider**, not model size.
|
|
57
|
+
|
|
58
|
+
**OpenAI (email, baseline vs ponytail, n=50–100):**
|
|
59
|
+
|
|
60
|
+
| model | baseline | ponytail |
|
|
61
|
+
|---|--:|--:|
|
|
62
|
+
| gpt-4.1-mini | 100% | 98% |
|
|
63
|
+
| gpt-4.1 | 100% | 79% |
|
|
64
|
+
| gpt-5.4-mini | ~100% | ~92% |
|
|
65
|
+
| gpt-5.4 | 100% | 98% |
|
|
66
|
+
| gpt-5.5 | 98% | 94% |
|
|
67
|
+
|
|
68
|
+
**Claude (email, baseline vs ponytail, n=40):**
|
|
69
|
+
|
|
70
|
+
| model | baseline | ponytail |
|
|
71
|
+
|---|--:|--:|
|
|
72
|
+
| claude-haiku-4-5 | 35/40 | **40/40** |
|
|
73
|
+
| claude-sonnet-4-6 | 0/40 * | **40/40** |
|
|
74
|
+
| claude-opus-4-8 | 39/40 | **40/40** |
|
|
75
|
+
|
|
76
|
+
Every OpenAI model slips regardless of size (gpt-4.1 full is the worst). Every Claude model
|
|
77
|
+
is **100%** under ponytail.
|
|
78
|
+
|
|
79
|
+
\* The Sonnet baseline `0/40` is a return-type artifact, not a logic failure, and should not
|
|
80
|
+
be read as "Sonnet cannot validate email." Unconstrained Sonnet over-engineers the validator
|
|
81
|
+
into a `dict` (`{is_valid, message}`) instead of a bool. The test calls the function as a
|
|
82
|
+
bool, and a non-empty dict is always truthy, so it "accepts" every address and scores 0.
|
|
83
|
+
Read dict-aware (via `is_valid`), its logic is about 75% correct (9/12). The honest point is
|
|
84
|
+
narrow: ponytail writes the plain correct bool the task implies, while the unconstrained
|
|
85
|
+
model over-builds the interface and trips a naive `if validate(x)` caller. `url`,
|
|
86
|
+
`creditcard`, and `ipv4` hold at ~100% under ponytail on both providers, because their lazy
|
|
87
|
+
stdlib choice (`ipaddress`, Luhn, scheme checks) is already strict. Only email's obvious
|
|
88
|
+
stdlib tool is a parser.
|
|
89
|
+
|
|
90
|
+
## The fix that wasn't
|
|
91
|
+
|
|
92
|
+
SKILL.md already says "never simplify away input validation" and "pick the stdlib option
|
|
93
|
+
correct on edge cases." We tried hard to push the OpenAI rate to 100% by editing the skill —
|
|
94
|
+
**8 distinct edits** across counter-pressure wording, a check-mandate, explicit-over-delegate,
|
|
95
|
+
a few-shot example, combinations, and three placements. Every one scored ≤ the current skill;
|
|
96
|
+
several were far worse (one cratered to 78%); all bloated median LOC. The definitive n=100
|
|
97
|
+
A/B of the most promising edit:
|
|
98
|
+
|
|
99
|
+
```
|
|
100
|
+
OLD skill: 96/100 (96.0%)
|
|
101
|
+
NEW skill: 95/100 (95.0%) -> within noise, no reliable effect
|
|
102
|
+
```
|
|
103
|
+
|
|
104
|
+
Counter-instructions backfire: piling validation rules onto the skill makes models overthink
|
|
105
|
+
and produce *more* broken validators, not fewer. The reflex to reach for `parseaddr` lives in
|
|
106
|
+
the OpenAI models' training, and no skill wording reliably overrides it — so nothing was
|
|
107
|
+
shipped. Adding skill text that doesn't work is the cargo-cult Ponytail exists to prevent.
|
|
108
|
+
|
|
109
|
+
## Conclusion
|
|
110
|
+
|
|
111
|
+
"Ponytail degrades model performance" is not supported. Across 12 edge-case traps, ponytail
|
|
112
|
+
holds baseline parity. On validation it is **100% on every Claude model**, which is its
|
|
113
|
+
target platform. The only blemish is an email-validator slip on OpenAI models (a
|
|
114
|
+
cross-provider `parseaddr` reflex, present at every size), documented here and not fixable by
|
|
115
|
+
skill text. The LOC win (about half the code) comes with no correctness tax on Claude.
|
|
116
|
+
|
|
117
|
+
## Reproduce
|
|
118
|
+
|
|
119
|
+
`robustness-audit.js`, `model-email.js` and `claude-email.js` were removed from `main` in #1042. Check out the last commit that still has them, then run the steps below:
|
|
120
|
+
|
|
121
|
+
```bash
|
|
122
|
+
git checkout 08e952d7a8057a57ce561ff1330d093fd92eec67
|
|
123
|
+
```
|
|
124
|
+
|
|
125
|
+
```bash
|
|
126
|
+
cd benchmarks
|
|
127
|
+
node robustness-audit.js --selftest # verify all 16 instruments (no API)
|
|
128
|
+
node robustness-audit.js # 16-task audit, gpt-5.4-mini, n=20
|
|
129
|
+
AUDIT_MODEL=gpt-4.1-mini node robustness-audit.js
|
|
130
|
+
|
|
131
|
+
# email cross-provider (the slip)
|
|
132
|
+
ME_MODELS="gpt-4.1,gpt-5.4,gpt-5.5" ME_N=50 node model-email.js # OpenAI (OPENAI_API_KEY)
|
|
133
|
+
node claude-email.js # Claude (ANTHROPIC_API_KEY)
|
|
134
|
+
```
|
|
135
|
+
`OPENAI_API_KEY` / `ANTHROPIC_API_KEY` read from `../.env`.
|