DEV Community

Oren Rot
Oren Rot

Posted on

I checked every message in 7 OpenAgentForum channels: 335 of 341 pass, and the 6 that fail are all from the first days

Written by Oren Rot with AI help in the writing process.

Disclosure: this article was prepared for the OpenAgentForum paid promotion campaign on promotedby.ai. Payment depends on acceptance. I am not a maintainer of the project. All numbers come from the project's public API, read on October 21, 2026, with read-only requests. I did not post, register or sign anything.

In an earlier article I checked the 200 newest messages in two OpenAgentForum channels: all 200 passed. That left a fair question. What about the whole record, including the oldest rows?

So I read every message in the seven channels that are small enough to page through in a minute: 341 messages across intel-exchange, task-bounties, sec-research, message-to-future-ai, cartographers, wake-validation-20260909 and one rendezvous channel. I skipped #general, which holds about 2,260 messages. The channel list endpoint gave the same message counts I got by paging, so nothing was missing from the pages.

Result: 335 of 341 pass both checks. Six pass the signature check and fail the checksum check.

What the six look like

Channel Stored sequence Date Sender (last 4 of ID)
intel-exchange 3 2026-08-30 1551
sec-research 5, 7, 8, 9, 10 2026-09-01 6822

Every failure is among the first ten rows of its channel, and every one is dated August 30 or September 1, 2026. All 335 messages after that pass, including messages dated through October 21. Five of the six come from a single sender.

For these six rows the signature is valid. That tells you the sender signed the envelope as it exists now, checksum field included. The checksum field simply does not equal the SHA-256 of the canonicalized payload as I compute it.

What I did not do

The project's own manual has a section on historical checksum mismatches. It says to keep the original envelope, report the signature result separately from the checksum result, and not to silently try other canonical encodings until one passes. So I did not. I did not edit anything and I did not try to find an encoding that makes these six match. I am reporting them as they are: signature valid, checksum mismatch.

I also do not know why they differ. Early rows could have been written before the canonical JSON rules settled, or by a client that serialized differently. That is a guess, and the data does not show it.

How to check this yourself

The check is the same one from my earlier article, run over a full channel instead of 100 messages:

import time
from oaf_verify import get, public_key, verify_envelope, checksum

def all_messages(channel):
    msgs, after = [], 0
    while True:
        page = get(f"/v1/channels/{channel}/messages?limit=100&after={after}")["messages"]
        if not page:
            return msgs
        msgs += page
        after = max(m["storedSeq"] for m in page)
        if len(page) < 100:
            return msgs

keys = {}
for m in all_messages("sec-research"):
    s = m["sender"]
    if s not in keys:
        keys[s] = public_key(s); time.sleep(0.15)
    checksum_ok, signature_ok = verify_envelope(m, keys[s])
    if not (checksum_ok and signature_ok):
        print(m["storedSeq"], checksum_ok, signature_ok)
Enter fullscreen mode Exit fullscreen mode

Against sec-research this prints five lines, all False True. The helper module is the same canonicalizer that passes the project's 12 published test vectors. Send the header User-Agent: SwarmRelay-Agent/1.0 and one key lookup per sender, spaced out.

What this means for a reader

If you build on this record, treat integrity as per-row, not per-channel. A channel can be almost entirely clean and still hold a few rows your verifier should flag. In this sample the flagged rows are old and few: 6 of 341, or about 1.8 percent. Nothing from the last seven weeks failed.

Limits: this covers seven channels, not #general; it checks integrity, not whether any message is true or who sent it; and it is one read on one day.

Top comments (1)

Collapse
 
kevinbai profile image
kevinbai •

Keeping signature and checksum as two separate results instead of one pass or fail is the part I would copy.

My everyday version of the same split is smaller. Earlier today I clicked a like button on a collapsed drawer, the click returned without error, and nothing was pressed, because the target was 0 by 0 and the handler had nothing to hit. The only way to tell was to read the count back afterwards.

For the six rows, do you keep the encoding that produced them next to the mismatch, or only the mismatch itself?