| name | hill-climb |
| description | Metric-driven optimization loop: baseline a number, profile the cost, then
accept or revert one change per iteration on measured evidence until the
target is hit or the curve plateaus. Use when the user says "make this
faster", "reduce memory", "speed up CI", "get p99 under 200ms", "improve the
frame rate", "cut the bundle size", "make the tests run quicker", or "reduce
token cost". Requires one number, a repeatable command that prints it, and a
fixed dataset; the loop stops and says so when the harness is too noisy to
measure the improvement being chased.
|
| user-invocable | true |
| allowed-tools | ["Read","Write","Edit","Bash","Glob","Grep","Skill","Agent"] |
| routing | {"not_for":"one-shot micro-optimizations with no measurement (just make the edit), work with no measurable metric or no repeatable measure command, correctness bugs and crashes (debugging skills), boolean done-criteria loops with no continuous metric (objective-loop), capacity planning and infrastructure sizing","triggers":["make this faster","speed this up","reduce memory usage","speed up CI","make the build faster","make the tests run quicker","get p99 under","reduce latency","improve the frame rate","cut the bundle size","reduce token cost","optimize until it hits","profile and optimize","performance regression","hill climb on this metric"],"complexity":"Complex","category":"meta","pairs_with":["objective-loop","verification-before-completion","test-driven-development","performance-optimization-engineer","phaser-gamedev","threejs-builder","game-design","nodejs-api-engineer","testing-automation-engineer"]} |
Hill Climb
The toolkit's metric-driven optimization loop. One number moves; everything else
stays fixed. Each iteration states one hypothesis, makes one change, runs the
correctness floor, re-measures, and either accepts the change or reverts it. The
ledger of what was tried and what failed ships with the code.
Sibling to objective-loop: that loop verifies boolean criteria and reschedules;
this loop optimizes a continuous metric against variance. Route here whenever the
goal is a number moving in a direction.
Phase 1: SPEC
Fill these fields from the request. Interview only for what is missing.
| Field | Meaning | Required | Default |
|---|
| METRIC | One number, with units and direction (lower or higher is better) | yes | — |
| MEASURE | A deterministic command that prints that number, repeatable | yes | — |
| TARGET | The value that ends the loop | yes | — |
| FLOOR | Correctness gate command(s) that must exit 0 every iteration | yes | — |
| FIXTURE | Dataset, workload, or input identity, pinned to a commit or checksum | yes | — |
| Variance tolerance | Spread below which a delta means nothing | no | 2x the baseline spread |
| Iteration budget | Iterations before a forced stop | no | 8 |
| Plateau threshold K | Consecutive non-improving iterations that stop the loop | no | 3 |
Rules:
- One METRIC per loop. Two numbers with a trade-off need one of them promoted to the FLOOR (for example: "p99 latency drops, memory stays under 500 MB").
- MEASURE prints the number and nothing that requires interpretation. Wrap noisy tools in a script that emits one value.
- A hill climb against a varying dataset measures nothing. Pin FIXTURE before Phase 2 — same input rows, same seed, same machine class, same warm/cold state.
- FLOOR is executed, not asserted. Name the command.
- A domain playbook fills this table fast:
references/domain-playbooks.md carries pre-filled blocks for frame rate, API latency, CI time, test runtime, bundle size, memory, token cost, and game-design quality.
- A judgment score can be the METRIC only under the frozen-rubric contract in that reference: rubric frozen at SPEC time, graded in a fresh context by an agent that did not author the change, wider accept threshold. Without a freezable rubric the request is not hill-climbable — that reference names where it goes instead.