Answering in a filing's thread corrects it, instead of searching - #52
Conversation
The archivist files a document and replies in a thread. Answering in that thread is how you tell it that it got something wrong, but the message came back as search results instead. Replying to your own original upload did the same. The bot had learned to answer in a thread without learning to read one: it looked at a single reply pointer, and inside a thread that pointer is a rendering aid aimed at the newest message there, not at the filing. Anything posted after the filing, a todo link or a status line, broke the connection. It now asks the thread which filing it belongs to, so both ways of replying reach the classifier. Mentioning the bot by name is still a question, not a correction. Needs matrix-nio 0.25 for reading a thread's events.
The reply confirming a re-file went to the main timeline instead of the thread the correction was typed in. On its own that is just noise, but corrections chain by asking the thread what the newest classification is, so a confirmation posted outside it left every later correction working from the original filing again. Fixing one thing then fixing a second undid the first. The capture side already answered in the thread; only documents did not. The tests for reading a thread were handed one that already contained a re-filed confirmation, so they would have agreed with a bot that never posts one there. They now also check the bot puts it there.
Verified on the live rig, both directionsRan the e2e against the running Simpsons instance (real Synapse, real archivist, mock LLM), first with the fix and then with With the fix — passes: Pre-fix, same test, same rig — fails: So the test reproduces the reported bug against real containers, not just against a fixture. Confirmed inside the container that it was genuinely running pre-fix code before that run ( The instance was returned to its prior branch and restarted; bot-runner and curator are clean afterwards. Also worth knowingThe running bot-runner already carries Unit suite: 2123 passed, 8 skipped. Every new assertion was checked red before green — 6 routing, 2 placement, and now the e2e. |
Summary
The archivist files a document and replies in a thread. Answering in that thread is how you tell it that it got something wrong, but the message came back as search results. Replying to your own original upload did the same.
The bot had learned to answer in a thread without learning to read one. It resolved a correction from a single reply pointer, and inside a thread that pointer is a rendering aid aimed at the newest message there, not at the filing. Anything posted after the filing, a todo link or a status line, broke the connection. It now asks the thread which filing it belongs to, so both ways of replying reach the classifier. Mentioning the bot by name is still a question, not a correction.
Second commit fixes the other half. The confirmation of a re-file went to the main timeline rather than the thread the correction came from. On its own that is noise, but corrections chain by asking the thread for the newest classification, so a confirmation posted outside it left every later correction working from the original filing. Fixing one thing then fixing a second undid the first. The capture side already answered in the thread; only documents did not.
The routing change made the dispatcher smaller rather than larger: the separate document and capture correction branches collapsed into one, and the duplicated envelope-type checks became a shared predicate. The thread lookup lives in the bot framework, not in the archivist, since it is a generic Matrix capability.
Notes for review
matrix-niofloor moves 0.24 to 0.25 forroom_get_event_relations. That affects every bot, so it wants a lockfile pass.Why it survived a release
The nearest thing to coverage for thread behaviour,
tests/integration/test_room_modes_e2e.py, is markedxfail(strict=False), which reports success whether it passes or fails. That is indistinguishable from having no test while looking like coverage. Tracked as FAM-6, not fixed here.The general shape is in
docs/design-notes.md: whoever teaches the sender a relation owns teaching the reader the same one. Half a relation is worse than none, because the send side looks right in the client while routing silently degrades.