Guide
Continuously improve your software with Scalpels and SoloThe ledger
· Ed Grosvenor
An hourly loop lives or dies on what it remembers. Without memory it reports the same slow query every hour, files the same issue twelve times by lunch, and has no idea what "since the last run" means.
The conductor keeps that memory in a single Solo scratchpad called Improvement ledger, rather than in its own conversation, so a fresh conductor can pick up exactly where the last one left off. It reads the ledger at the start of every run and writes it at the end. Because it is a scratchpad, you can open it in Solo at any time and see exactly what the loop believes.
Create it
Ask any Solo agent in the project to create it with scratchpad_write, tagged improvement-loop, from orders/ledger.md in the companion code. It looks like this:
# Improvement ledger
## Last run
- finished_at: never
- covered_until: 2026-10-15T00:00:00Z
## Apps
| Name | Repository | Scalpels team | app_deployment | Hone app | Wake app | Reel application |
| --- | --- | --- | --- | --- | --- | --- |
| Storefront | acme/storefront | acme | … | … | … | … |
## Open findings
| Fingerprint | Todo | Issue | First seen | Last seen | Hits |
| --- | --- | --- | --- | --- | --- |
## Runs
<!-- One line per run, newest last. -->
Set covered_until to the moment you want the first run to start reading from. A day ago is a good start: enough to prove the loop finds something, not so much that the first run files twenty issues.
Each section's job
Last run. covered_until is the end of the window the last successful run read. The next run reads from there to now. If a run fails halfway, it does not move covered_until, so the next run covers the gap. That is what makes the loop safe to miss: if the Mac was off for a weekend, Monday's first run reads the whole weekend.
Apps. The map from what you need. Adding an app to the loop is adding a row.
Open findings. Every problem the loop has filed and not yet closed, keyed by a fingerprint: a short, stable name for the problem that does not change from one hour to the next. The fingerprint is how the conductor knows the slow query it sees today is the same one it filed yesterday. Investigations defines the fingerprints.
Runs. One line per run: when it ran, the window it covered, and how many findings were new, repeated or resolved. When you want to know whether the loop is earning its keep, this is where you look.
Two rules that keep it honest
- Write with the revision. Every scratchpad write takes an
expected_revision. If the revision has moved, something else edited the ledger since the conductor read it. The conductor rereads and merges instead of overwriting. - One run at a time. The script that rings the conductor will not ring it while it is still busy. As a second guard, the conductor takes a Solo lock called
improvement-loopwithlock_acquirebefore it reads the ledger, and releases it withlock_releasewhen it is done. If the lock is already held, the run stops without doing anything.