Process skill. Move one number toward a target with attempts that are measured, kept or reverted in full, and logged. Measurement rules → measurement.md. Named principles → engineering-principles.md. Composition → process-skill-composition.md.
Adapted from the pstack hillclimb playbook (backnotprop/pstack, MIT © 2026 Lauren Tan).
Entry gate
- Metric and direction. Name one metric, its unit and direction. When the user gave no target, propose one and confirm it before the first attempt.
- Workload. Find or build a realistic workload that reproduces the complaint. If none reproduces it, stop and report that. Do not climb against a workload that does not show the problem.
- Commit authority. Check the current branch. On
main,masteror a shared branch, measure and report, then ask before the first commit. On the user's own feature branch, continue.
Non-negotiables
- Write the stop predicate before the first attempt. It has a target and a minimum attempt count, for example "p50 ≤ 40 ms and at least 5 attempts". Never relax it. Reaching the target early does not end the loop before the minimum attempt count.
- Prove the harness is sensitive, then freeze it. Contrasting workloads must produce separated results. After the baseline, do not edit the harness, its workload, its data or its run count. Each run reports the median of repeated samples, an error count and a work-done count.
- Record a regression gate at the baseline: the existing tests or a correctness check that passes before any attempt. Every kept attempt must pass it.
- Prove results unchanged. Before the first attempt, build an equivalence check that runs the original and the changed code over many generated inputs, including edge cases and mixed value types, and compares outputs strictly, or with a hash of the full output. Run it at every keep. When it is small, commit it as a test that keeps a frozen copy of the original, so the protection stays in the repository; show once that it fails on a deliberately broken version.
- Leave a margin. Do not stop just under the target. Once it is met, remove remaining known costs that are cheap to remove, and finish with every run of the final measurement under the target.
- Profile before guessing. Take a profile of the baseline and name the hot path before the first hypothesis. Measure the baseline and the candidate in alternating rounds, so machine drift cannot fake a win.
- One hypothesis per attempt. Each names a mechanism. Order the hypotheses cheapest first: avoid the work, avoid repeating it, do less, do it later, do it concurrently, then do it cheaper.
- Keep or revert in full. Keep an attempt only when the frozen harness shows a gain beyond run-to-run spread, the error count is zero, the work count is unchanged and the gate passes. Otherwise restore the files it touched. Never claim a win from reading code.
- One commit per kept attempt. Stage only the paths it changed. Never
git add -Aorgit add .. Never commit the decision log. - Correctness and simplicity outrank the number. A kept attempt that adds complexity without beating the spread is reverted.
- A plateau changes the hypothesis category. Two attempts in a row that produce no new evidence and no gain route to i-need-help when it is installed. Otherwise stop with the same report inline.
Work lean. Read each file once, batch independent commands in one call, and keep command output short, for example with a summary reporter or | tail -20.
Workflow
- Pass the entry gate. State metric, direction, target, stop predicate and gate in one short block.
- Build or locate the harness. Answer the seven questions in measurement.md for the baseline. Freeze the harness.
- Start the decision log:
node <installed-skill>/scripts/log.mjs .hillclimb/<slug>/decisions.tsv baseline "-" "-" "-" <value> "-" pass baseline "<limiter>". Exclude.hillclimb/from Git through.git/info/excludewhen it is not ignored. - Loop: read the log, pick the next hypothesis, change only what it needs, measure with the frozen harness, run the gate, keep or revert, log the row. Log reverted attempts too.
- Stop when the predicate holds or the stall rule fires.
Exit artifact
Reply with:
- Result: baseline → final with unit, run count, range and the limiter now. Use the verdict words from measurement.md.
- Kept: each commit with its hypothesis and delta.
- Reverted: each hypothesis with its measured reason.
- Predicate: met or not met, and attempts used.
- Log: path to
decisions.tsv. Keep the log out of commits. If.git/info/excludecannot be written, delete.hillclimb/before finishing and paste the table instead. Finish with a clean tree.
Reply check. Every result you state names a command that appears in your actions and ran after your last edit: say node --test if that is what ran, not npm test. Claim a clean tree only after git status, and claim a test failed first only when that failing run is shown.
Consumer bindings
Consumers may name their benchmark command, workloads and gate in a local skill or AGENTS.md. Those bindings choose the harness; they do not relax the non-negotiables.