Skip to content

Answering in a filing's thread corrects it, instead of searching - #52

Merged
arthware-dev merged 2 commits into
mainfrom
fix/archivist-thread-corrections
Aug 2, 2026
Merged

Answering in a filing's thread corrects it, instead of searching#52
arthware-dev merged 2 commits into
mainfrom
fix/archivist-thread-corrections

Conversation

@arthware-dev

Copy link
Copy Markdown
Contributor

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-nio floor moves 0.24 to 0.25 for room_get_event_relations. That affects every bot, so it wants a lockfile pass.
  • The tests for reading a thread were being handed one that already contained a re-filed confirmation, so they would have passed against a bot that never posts one there. They now also assert the bot puts it there.
  • Every new assertion was checked red against the unmodified code before going green: 6 routing failures, then 2 placement failures.
  • Full unit suite green (2123 passed, 8 skipped). The e2e test is written but not run against the rig.

Why it survived a release

The nearest thing to coverage for thread behaviour, tests/integration/test_room_modes_e2e.py, is marked xfail(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.

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.
@arthware-dev

Copy link
Copy Markdown
Contributor Author

Verified on the live rig, both directions

Ran the e2e against the running Simpsons instance (real Synapse, real archivist, mock LLM), first with the fix and then with archivist.py reverted to main while keeping the test in place.

With the fix — passes:

SCENARIO   Homer corrects a filing from inside its thread
GIVEN      the #documents room exists and Homer has access
WHEN       Homer uploads the invoice and the archivist files it
  ✓      filed doc #100, event $iKRK2nHjZUFw4nnJHJphU_BcO2WYyY9Qkf86zq-bdw4
AND        the filing answered in a thread rooted at Homer's upload
  .      thread root = $xbUsIQf3eh-86hoOqe4u3JqK-UfOU18shZc4ko4Dz04
WHEN       Homer types a correction inside that thread
THEN       the archivist posts a document.reclassified confirmation
  ✓      reclassified #100 with hint "this one is Marge's, not mine"
1 passed

Pre-fix, same test, same rig — fails:

assert reclassified, \
    "archivist never reclassified — an in-thread correction was read as a search"
E   AssertionError: archivist never reclassified — an in-thread correction was read as a search
1 failed

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 (grep -c '_is_filing_envelope' /stacklets/docs/bot/archivist.py returned 0).

The instance was returned to its prior branch and restarted; bot-runner and curator are clean afterwards.

Also worth knowing

The running bot-runner already carries matrix-nio 0.26.0 with room_get_event_relations present, so the floor bump in this PR is a declaration catching up with reality rather than a functional change for existing instances. A fresh install still needs it.

Unit suite: 2123 passed, 8 skipped. Every new assertion was checked red before green — 6 routing, 2 placement, and now the e2e.

@arthware-dev
arthware-dev merged commit 633485a into main Aug 2, 2026
1 check passed
@arthware-dev
arthware-dev deleted the fix/archivist-thread-corrections branch August 2, 2026 08:40
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant