The repair loop of the Self-Healing Codebase Project. The first full run of the Agent Server feature map found a long list of bugs. Then an agent fixed them: every medium and low one, one pull request each, each proven against the map, and every choice that belonged to a maintainer written down for them to make.
The idea, in three parts
The feature mapEverything an agent can do with the OpenHands Agent Server, written for agents: 34 families, 931 sub-features, each with a stable ID and an exact recipe to drive it.
A CLI for agentscontrol-agent-server launches a real server, drives every REST, WebSocket and client step one command at a time, and keeps the evidence. Every command prints one JSON object.
Verify everythingA known bug stays in the map as a line with a predicate that describes how it fails today. When you can see every behavior, you can fix every behavior, and prove each fix.
The video
A walk through the most telling fixes: how a fix is proven, a sub-agent naming a missing skill, a failed run that froze the server, silent sockets after a delete, secret key rotation, and the one question still open. Drawn with Manim; narrated by Kokoro-82M, an open-weight speech model; the score is generated with numpy. Download (MP4, 12 MB) · Scene script, narration and music
How a fix is proven
Each bug from the run lives in the map as a line that ends in # bug: <predicate>, for example # bug: status eq 500 && body.exception contains 'not found'. A fix counts only when that line fails exactly as predicted on main twice (xfail), passes on the fix branch twice (xpass), and then loses its marker. From then on it is an ordinary check that guards the fix.
126pull requests, one per bug
2merged
124green, ready for review
~50with a Decision needed section
13 medium bugs; 14 more mediums that already had contributor pull requests, fixed again independently so the maintainers can keep the better one; 8 older reports the umbrella issue lists; and 93 low-severity bugs, each given its own issue first. All are tracked in umbrella issue #5653.
Decision needed
An agent can do the work, but some choices are not its to make. When an issue's triage left a real question open, the pull request says so near the top, in a section called Decision needed: the option implemented and the alternative, with what each costs. The section stays even when the recommended option is the one that was built, so the maintainer still sees the choice. This one is from #5754, one of the two fixes already merged:
Decision needed
Scope relative to the broader issue "Plugin or skill loading error should not prevent conversation from starting": its triage asks whether it absorbs #5630 or stays a separate umbrella.
Implemented: #5630 is kept separate. This PR fixes only sub-agent registration, for file-based and plugin-provided definitions, as #5630's triage scoped.
Alternative: folding #5630 into the broader issue would widen this PR to plugin loading and possibly a new client-facing notice, touching the server models, the TypeScript client and the UI.
The fixes in the video
#5754 (merged): a sub-agent naming a missing skill made the first message answer 500. Invalid definitions are now skipped with a warning.
#5780: a failed run froze the whole server for about five seconds, because a Rich traceback was rendered on the event loop. The slowest health probe went from about 4.5 seconds to under 150 ms.
#5757: deleting a conversation left its WebSockets open and silent. They now close with 1012, and a reconnect after a delete gets 4004 and stops.
#5758: changing the server's secret key left every stored secret unreadable. With OH_PREVIOUS_SECRET_KEYS, old values stay readable and move to the new key when saved.
#5830: a live ACP switch to a model the session does not offer answered 500. Whether to check the model list locally or translate the agent's error is still open, waiting on a maintainer.