My first patch to Ergo
Building Slirc · Part 3 of 4 · Start at part 1
I was testing message deletion in Slirc when I found an Ergo bug: deleting a message from one channel could affect a copy in another.
A message sent to multiple IRC targets gets one msgid, but Ergo stores one history row per target. HistServ replied, “Successfully deleted message.” It could have deleted the copy from another channel instead.
One message, two channels
An IRC message has a msgid. You can send one message to more than one channel at once, like PRIVMSG #a,#b :hello. Ergo stores a history row in each channel, with the same msgid:
| Channel | msgid | History row |
|---|---|---|
| #a | m42 | 101 |
| #b | m42 | 102 |
The old database lookup searched for m42 and stopped at the first row. It didn't check which channel the delete named. An operator's HistServ delete for #a could remove the #b copy and still report success, leaving #a untouched. For regular users, finding the wrong copy could make a valid delete fail its permission check.
Keep the channel in the lookup
The fix passes the channel through both lookup and deletion. Ergo now matches the msgid and channel name together, then removes the matching row from that channel. A delete for #a leaves the copy in #b alone. I made the same change for SQLite, MySQL and PostgreSQL.
The regression test stores the same msgid in two channels, deletes it from one, then checks that the other copy is still there. The patch is in Ergo PR #2462.
@@ DeleteMsgid-_, id, _, _, err := s.lookupMsgid(ctx, msgid, true)+rows, err := s.db.QueryContext(ctx, `SELECT history.id FROM history+ INNER JOIN sequence ON history.id = sequence.history_id+ WHERE sequence.target = ? AND history.msgid = ?;`, target, msgid)@@-err = s.deleteHistoryIDs(ctx, []uint64{id})+err = s.deleteHistoryIDs(ctx, ids) @@+db.DeleteMsgid("#unregistered", "shared-msgid")+// The #other copy remains; the #unregistered copy is gone.
That fix belongs in Ergo. It's the server's job to keep the permission check and history deletion on the same channel. It doesn't change who can delete messages; it makes sure the request affects the channel it was authorized for.
So, that means you know Go, right?
Not really. I don't know Go. But I knew the bug: deleting the message in #a should leave its copy in #b. GPT-6 Luna helped me turn that into a patch. I reviewed the diff and regression test to make sure the other target stayed untouched.
That's what I like about working with AI. I can explain what I need, understand the trade-offs, and review the code well enough to decide whether I'm comfortable submitting it. I don't need to know the language already. This time, I learned enough to send a PR to Ergo.
The PR is still open. I’ve published patched Ergo images for AMD64 and ARM64 and deployed them to Slirc.org.
What's next
- October 6th: pre-launch. The waiting list gets into app.slirc.org.
- October 12th: the source code goes public.
Join the waiting list, and see you on the 6th.