VM batch 3: message extras and own-account sync on all three servers #23

Merged
asxpi merged 120 commits from vm/batch-3 into main 2026-11-10 05:50:51 +00:00
Member

Batch 3 (message extras, own-account sync) of the GUI VM runs: anotherim-js 0.8.0-rc9 (142ee094, libtacky v1.2.3) against Gajim, Dino and anotherim-web (and a second device of vm-aim) on ejabberd, Prosody and anotherim-server.

Coverage: tools/interop.py gaps --feature <spec> --server <server> prints 0 gaps for every batch 3 spec (XEP-0245, 0379, 0393, 0449, 0466, 0490, 0492, 0511, urn:tacky: silent, schedule, contact, spans, live-location, pins, drafts, tags, chatpins, pep-expiry) and the batch 2 carry-overs (XEP-0272/0482 on prosody, XEP-0513 on prosody and anotherim-server). Dino and Kaidan cells are lacks in clients.toml with DOAP evidence (3262bf5); spans and live-location are na (libtacky only reads them, 26f7284); schedule is na on ejabberd and prosody (no scheduler).

Runs: 84 recorded, 70 pass, 14 fail: ejabberd 25 (21 pass, 4 fail), prosody 30 (24 pass, 6 fail), anotherim-server 29 (25 pass, 4 fail), including the XEP-0490 re-run 052644 that supersedes 043251.

Found (anotherim-js UI, same on all three servers):

  • XEP-0245: a received /me line is drawn raw in the bubble and the chat list; libtacky sets Message.me, ui/src never reads it. Gajim and Dino draw aim's /me right.
  • pep-expiry: aim's status sheet has no time limit; libtacky can (web's API leg sends <expires/>, aim shows it and drops it on time).
  • Minor: the Link previews switch reads on for libtacky's default sender, which attaches nothing; unmuting a room writes <on-mention/> instead of removing the setting.

Rechecked: C3.1 fixed (a draft with U+0001/U+0002 is published, no bgerror). C8 not exercisable (nothing writes <advanced/>). C35, C43, C44 reproduced on prosody. These fails are recorded as cause libtacky because --cause has no choice for the app under test.

Harness: new examples (xep0245, 0393, 0449, 0466, 0379, 0490, 0511, silent, contact, schedule, pepexpiry, ownsync with PART=), aim's send_later, sticker_pack, link_previews, reorder_pin; OCR and colour fixes for Gajim and aim; step_log redacts preauth= tokens (c039f54); AGENTS.md sections per server.

Known follow-ups: a cause for the app under test; finish should redact preauth tokens in server.log too.

🤖 Generated with Claude Code

Batch 3 (message extras, own-account sync) of the GUI VM runs: anotherim-js 0.8.0-rc9 (`142ee094`, libtacky v1.2.3) against Gajim, Dino and anotherim-web (and a second device of vm-aim) on ejabberd, Prosody and anotherim-server. **Coverage:** `tools/interop.py gaps --feature <spec> --server <server>` prints 0 gaps for every batch 3 spec (XEP-0245, 0379, 0393, 0449, 0466, 0490, 0492, 0511, `urn:tacky:` silent, schedule, contact, spans, live-location, pins, drafts, tags, chatpins, pep-expiry) and the batch 2 carry-overs (XEP-0272/0482 on prosody, XEP-0513 on prosody and anotherim-server). Dino and Kaidan cells are `lacks` in `clients.toml` with DOAP evidence (3262bf5); spans and live-location are `na` (libtacky only reads them, 26f7284); schedule is `na` on ejabberd and prosody (no scheduler). **Runs:** 84 recorded, 70 pass, 14 fail: ejabberd 25 (21 pass, 4 fail), prosody 30 (24 pass, 6 fail), anotherim-server 29 (25 pass, 4 fail), including the XEP-0490 re-run 052644 that supersedes 043251. **Found (anotherim-js UI, same on all three servers):** - XEP-0245: a received `/me` line is drawn raw in the bubble and the chat list; libtacky sets `Message.me`, `ui/src` never reads it. Gajim and Dino draw aim's `/me` right. - pep-expiry: aim's status sheet has no time limit; libtacky can (web's API leg sends `<expires/>`, aim shows it and drops it on time). - Minor: the Link previews switch reads on for libtacky's default `sender`, which attaches nothing; unmuting a room writes `<on-mention/>` instead of removing the setting. **Rechecked:** C3.1 fixed (a draft with U+0001/U+0002 is published, no bgerror). C8 not exercisable (nothing writes `<advanced/>`). C35, C43, C44 reproduced on prosody. These fails are recorded as cause `libtacky` because `--cause` has no choice for the app under test. **Harness:** new examples (xep0245, 0393, 0449, 0466, 0379, 0490, 0511, silent, contact, schedule, pepexpiry, ownsync with `PART=`), aim's `send_later`, `sticker_pack`, `link_previews`, `reorder_pin`; OCR and colour fixes for Gajim and aim; `step_log` redacts `preauth=` tokens (c039f54); AGENTS.md sections per server. **Known follow-ups:** a cause for the app under test; `finish` should redact preauth tokens in server.log too. 🤖 Generated with [Claude Code](https://claude.com/claude-code)
asxpi added 120 commits 2026-11-10 05:37:27 +00:00
The coverage rule needs every batch 3 cell either run or marked lacking.
From the peers' DOAP files (Gajim 2.6.0, Dino 0.5.1, Kaidan 0.16.0):
Dino has /me and styling but none of the other batch 3 XEPs, Kaidan
none of them, Gajim no XEP-0379 or 0492. libtacky's own sync/row specs
(pins, drafts, tags, chatpins, live location, PEP expiry) have no view
in any of them; silent, contact and spans stay Gajim runs, since Gajim
shows their fallback.

Assisted-by: Claude:opus-5-5
Batch 3 needs a run per peer for /me and message styling. Each example
sends one line each way (/me, then *strong* _em_ `pre` ~strike~ and a
"> " quote) and logs whether the body went out as typed; the receiver's
rendering is judged from its screenshots, with OCR noting raw markup.

Assisted-by: Claude:opus-5-5
xep0466 (timer 5 min, shots before and past it), silent (control vs
"Send without sound", the peer's Notify calls minimized), contact
(card from the paperclip menu), xep0379 (drop the peer, invite link,
the peer opens it, mutual again), pepexpiry (aim has no limit in its
sheet; the peer's API status with expires, then its empty publish)
and ownsync (PART=pins|drafts|tags|chatpins|0492 between aim and its
second device, with the C3.1 U+0001 draft check). aim gets
reorder_pin: pinned chats Ctrl+dragged in the list (142ee094).

Assisted-by: Claude:opus-5-5
Carried over from batch 2. Dino made a private room, invited aim and
started an audio group call; aim joined from its XEP-0482 card, opened
a Jingle session to Dino, and tones went both ways (660 Hz 1.00 on
aim, 440 Hz 0.99 on Dino, opus 400 each way on both NICs). As on the
other servers aim's <accept/> and <left/> are withheld (not encrypted
for vm-dino), which the call itself does not need.

Assisted-by: Claude:opus-5-5
libtacky reads urn:tacky:spans:0 and urn:tacky:live-location:0 but
sends neither (both protocol docs at v1.2.3 say "read only"), so
anotherim-js and anotherim-web have nothing to exchange, and no peer in
the VM harness sends them either. Batch 3 listed them as aim -> W/G
runs; they are na cells instead, with the reason.

Assisted-by: Claude:opus-5-5
Carried over from batch 2 for anotherim-server. aim creates a room,
web joins, each @-mentions the other from the composer's people
picker. Both lines carry an occupant-id <mention/> over the XEP-0372
reference's span, web's record of aim's line says mentions_me, and
both rooms show the @nick highlighted. Same as on ejabberd.

Assisted-by: Claude:opus-5-5
Batch 3's sticker, link preview and displayed-sync cells had no
example. xep0449 sends from aim's sticker picker and, where the
account has no pack (ejabberd: "No stickers yet"), makes one first in
Account > Stickers (aim's sticker_pack). xep0511 sets aim's Link
previews switch to `always` (it reads on for libtacky's default
`sender` too, which attaches none to what aim sends), sends a link to
an OpenGraph page encrypted and, with Gajim, in clear (libtacky puts
none beside an OMEMO 0.3 envelope), then the peer sends one. xep0490
runs aim, a second device of vm-aim and a third account writing to
it: each device reads in turn and the other's unread badge must go.

Assisted-by: Claude:opus-5-5
aim sends "/me waves" as typed and Gajim shows it as an action with
aim's name. Gajim's "/me nods" reaches aim, which shows the raw "/me
nods" in the bubble and the list preview: anotherim-js never reads the
Message.me flag libtacky sets for such rows. A UI gap in the app under
test, not a protocol bug.

Assisted-by: Claude:opus-5-5
xep0511 turns aim's "Link previews" on (link_previews always, a new
aim/web action) and sends the forge page each way; ENC=plain for Gajim,
since libtacky attaches no preview beside an OMEMO 0.3 ciphertext.
xep0490 has bob write while neither of aim's devices has the chat open,
then one device reads and the other's unread mark should clear.

xep0272 with web as the room's creator on Prosody stopped at aim's
join (#9 C35, the room stays locked): it now records that as a failed
check and joins again once Prosody's 5 minute lock lapses, so the call
itself still gets tested.

Assisted-by: Claude:opus-5-5
aim's new room stays locked on Prosody (#9 C35), so web's join was
refused and the mention steps never ran. Log the refusal, wait for the
5 minute muc_room_lock_timeout and join again, as xep0249 does.

Assisted-by: Claude:opus-5-5
aim and web each sent a "/me …" line (OMEMO; the command goes out as
typed). Both apps draw the received line raw, "/me waves …", in the
bubble and the chat list, not as an action of the sender: libtacky
marks the row Message.me, but no view of anotherim-js reads it.

Assisted-by: Claude:opus-5-5
urn:tacky:schedule:0 needs a message a few minutes ahead, while the
sheet's presets start at an hour. send_later(text, minutes) now types
the time into the sheet's datetime-local field: a click on a segment
opens a calendar that takes the keys until Esc closes it, then digits,
Right and a/p fill hour, minute and AM/PM. schedule.py submits a line
LEAD minutes ahead, quits aim, waits for the peer to get it at its time
and shows aim's history after a restart (anotherim-server only; the
menu item is greyed elsewhere).

Assisted-by: Claude:opus-5-5
On ejabberd Gajim's chat list is 975 px wide by now and its composer
field spans 1066..1258: the fixed -250 hit the formatting button, so a
typed /me line never went out. The field is now clicked 45 % into the
chat pane, whose edge is found from the list's blue + button.

Assisted-by: Claude:opus-5-5
aim's typing sends chat states to the peer before the scheduled line,
which the early-delivery check counted as the line (a false FAIL in the
first run). It now counts messages with a body or an OMEMO payload, and
logs when the server archived the delivered line (ejabberd's MAM ids
are microseconds since the epoch), which the host's lagging view of the
peer's log cannot tell.

Assisted-by: Claude:opus-5-5
Gajim drew aim's "/me waves …" as "* vm-aim waves …" (the command went
out as typed), but aim drew Gajim's "/me nods …" raw in the bubble and
the chat list: anotherim-js's views ignore libtacky's Message.me.

Assisted-by: Claude:opus-5-5
Carried over from batch 2. web's room stays locked on Prosody (#9 C35),
so aim's join on the invite was refused until the 5 minute lock
timeout; the example now waits it out. Then web's group call (started
through the API) connects and aim hears web, but web decodes aim's
leg as silence (inbound packets, audioLevel 0), as on ejabberd and
anotherim-server.

Assisted-by: Claude:opus-5-5
Dino drew aim's "/me waves …" as an action of vm-aim; aim drew Dino's
"/me nods …" raw in the bubble and the chat list: anotherim-js's views
ignore libtacky's Message.me.

Assisted-by: Claude:opus-5-5
aim schedules a line three minutes ahead from its schedule sheet's
date-time field and quits. The submit carries the OMEMO message to the
server's scheduler, Gajim gets nothing early, the server delivers and
archives it at the picked minute (01:49:00.03) while aim is offline,
and aim shows it in its history after a restart.

Assisted-by: Claude:opus-5-5
aim and web each sent *strong* _emphasis_ `pre` ~strike~ and a "> "
quote line; the other side drew bold, italic, monospace, struck text
and a quote bar, with the directives kept visible.

Assisted-by: Claude:opus-5-5
Carried over from batch 2. Dino's group call invite reaches aim's card,
but aim's Decline sends nothing: libtacky withholds the <reject/> since
it cannot encrypt for Dino in the OMEMO-on room, and does not send it
in the clear. Same as on ejabberd and anotherim-server.

Assisted-by: Claude:opus-5-5
aim schedules a line three minutes ahead and quits; the server's
scheduler delivers the still-encrypted message to web at the picked
minute (stanza-id 01:55:00.05), web shows it, and aim lists it as sent
after a restart.

Assisted-by: Claude:opus-5-5
aim and Gajim each sent *strong* _emphasis_ `pre` ~strike~ and a "> "
quote line under OMEMO; Gajim's log has aim's bodies as typed and both
sides drew them styled with a quote bar.

Assisted-by: Claude:opus-5-5
aim's "/me waves" goes out as typed and Dino draws it as an action
with aim's name. Dino's "/me nods" shows raw in aim's bubble and list
preview: anotherim-js ignores the Message.me flag, as with Gajim and
web.

Assisted-by: Claude:opus-5-5
Both apps send "/me" lines as typed but draw the other's raw, in the
bubble and the list preview: the views never read libtacky's
Message.me flag. Same as on ejabberd.

Assisted-by: Claude:opus-5-5
aim and Dino each sent *strong* _emphasis_ `pre` ~strike~ and a "> "
line under OMEMO; aim drew Dino's styled with a quote bar, Dino drew
aim's spans styled and the quote line in its grey.

Assisted-by: Claude:opus-5-5
aim sent a sticker from its composer's picker (the pack made in its
Stickers page); it went inside OMEMO and web drew it as a sticker, the
list row "Sticker".

Assisted-by: Claude:opus-5-5
Carried over from batch 2. aim declines web's group call invite from its
card and the <reject/> goes to the room in the clear (unencrypted room)
and reaches web. Before it aim waited out web's locked room (#9 C35,
Prosody's 5 minute lock timeout), which is not this spec.

Assisted-by: Claude:opus-5-5
Both sides send strong, emphasis, pre, strike and a quote line as
typed under OMEMO, and each draws the other's spans styled and the quote
with a bar. Same as on ejabberd.

Assisted-by: Claude:opus-5-5
aim sent a sticker from its picker to Gajim under OMEMO 0.3: only the
aesgcm:// link of sticker.webp went inside, and Gajim, which has no
stickers, showed it as an image file card: a sane fallback.

Assisted-by: Claude:opus-5-5
Both sides send the styling directives as typed under OMEMO; aim draws
Dino's spans and quote styled, Dino draws aim's spans styled and the
quote line in grey (its partial support). Same as on ejabberd.

Assisted-by: Claude:opus-5-5
With its Link previews switch flipped to `always`, aim sent a link to
an OpenGraph page under OMEMO 2 and web drew the card. The switch reads
on for libtacky's default `sender`, which sends no preview; and web's
own link went without one (its preview fetch fails in the browser).

Assisted-by: Claude:opus-5-5
Both apps send the styling directives as typed under OMEMO and draw
the other's spans styled and the quote with a bar. Same as on
ejabberd.

Assisted-by: Claude:opus-5-5
Carried over from batch 2. After waiting out aim's locked room (#9 C35)
web joined; each @-mentioned the other from the composer's picker, the
lines carry urn:xmpp:mentions:0 <mention/> with the occupant id, and
each receiver shows itself mentioned (web's record says mentions_me).

Assisted-by: Claude:opus-5-5
In a Gajim chat on ejabberd OCR read neither "Disable" nor "Cancel"
in WebKit's dialog five times, so set_encryption(False) failed with the
dialog up. Its red button, srgb(217,48,37), is now clicked when OCR
finds nothing.

Assisted-by: Claude:opus-5-5
aim sends "/me waves" as typed and Gajim draws "* vm-aim waves", but
aim shows Gajim's "/me nods" raw in the bubble and the list preview
(and its own line too): anotherim-js does not read libtacky's
Message.me. Same as on ejabberd and anotherim-server.

Assisted-by: Claude:opus-5-5
Dino draws aim's "/me waves" as an action, but aim shows Dino's
"/me nods" raw (and its own line too): anotherim-js does not read
libtacky's Message.me. Same as on ejabberd and anotherim-server.

Assisted-by: Claude:opus-5-5
set_timer('5 minutes') never matched: only tesseract's sparse pass
reads the Disappearing messages menu, and it reads each word apart
('5', 'minutes', '8hours'), so no OCR line ever was '5 minutes'. Match
the label's last word instead (checked with tesseract on the failed
anotherim-server run's screenshot).

Assisted-by: Claude:opus-5-5
Both apps send "/me …" as typed and both show the other's line raw:
anotherim-js does not read libtacky's Message.me. Same as on ejabberd
and anotherim-server.

Assisted-by: Claude:opus-5-5
aim set a 5-minute timer from the chat menu; web showed the service
row, the next line carried timer='300', and after five minutes both
sides showed "Message disappeared". The timer went back to Off.

Assisted-by: Claude:opus-5-5
Strong, emphasis, pre, strike and a "> " quote each way: the bodies go
out as typed and both sides style them (bold, italic, monospace,
struck, quote bar).

Assisted-by: Claude:opus-5-5
aim's XML log writes the preview as <Description xmlns='…rdf-syntax-ns#'>
(a default namespace), which the INFO line missed, and the first sent
<encrypted/> after the send was taken for the clear second leg. The
line now prefers the message with the leg's word and both spellings.

Assisted-by: Claude:opus-5-5
With OMEMO off aim's link went with an rdf:Description (og:title,
description, site_name) and Gajim drew a card; under OMEMO 0.3 aim sends
none, as libtacky documents (no preview beside a legacy ciphertext).

Assisted-by: Claude:opus-5-5
Strong, emphasis, pre, strike and a "> " quote each way: aim styles
Dino's lines with a quote bar; Dino styles aim's spans and greys the
quote line (its own form, styling support partial).

Assisted-by: Claude:opus-5-5
aim sets a 5-minute timer from its chat menu (a bodiless ephemeral
notice), marks its next line with ephemeral timer=300 beside the OMEMO
envelope and replaces it with "Message disappeared" after five minutes.
Gajim 2.6 has no XEP-0466 and keeps the line, as expected.

Assisted-by: Claude:opus-5-5
Strong, emphasis, pre, strike and a "> " quote each way under OMEMO 2:
both apps style them (bold, italic, monospace, struck, quote bar).

Assisted-by: Claude:opus-5-5
aim set a 5-minute timer and sent a line with timer='300' beside its
OMEMO 0.3 envelope; after five minutes aim showed "Message disappeared"
and Gajim, which has no XEP-0466, kept the line, as expected.

Assisted-by: Claude:opus-5-5
aim's "Send without sound" puts <silent xmlns='urn:tacky:silent:0'/>
beside the OMEMO envelope; Gajim, without the spec, shows and alerts
it like the control line: the expected fallback.

Assisted-by: Claude:opus-5-5
aim sets a 5-minute timer, web shows the service row, and both replace
aim's next line with "Message disappeared" once the timer runs out.
Same as on ejabberd.

Assisted-by: Claude:opus-5-5
aim sent a line through Send held > Send without sound; it carried
<silent/> outside the OMEMO envelopes and web drew it with a bell-off
mark, the control line without. web never raises desktop notifications,
so only the mark tells the two apart there.

Assisted-by: Claude:opus-5-5
aim's "Send without sound" puts <silent/> outside both OMEMO envelopes;
web shows the line with a bell-off mark (web raises no desktop
notifications at all, so the quiet alert itself is not provable here).

Assisted-by: Claude:opus-5-5
The right click on Send leaves the pointer there, and its "Send"
tooltip covers the end of "Send without sound": send_silent never
found "sound" (anotherim-server silent run with Gajim). Move the
pointer away first, as the paperclip menu does.

Assisted-by: Claude:opus-5-5
aim's "Send without sound" line carried <silent/> beside its OMEMO 0.3
envelope; Gajim, which has no such spec, notified and showed it like
the control line: the expected fallback.

Assisted-by: Claude:opus-5-5
aim shares vm-dino's card from the paperclip menu; in the OMEMO 0.3
chat only its fallback body goes, inside the envelope, and Gajim shows
"👤 vm-dino" with a clickable xmpp: link.

Assisted-by: Claude:opus-5-5
aim shared vm-dino from its paperclip menu; the card went inside OMEMO
and web drew it with Message and Add contact.

Assisted-by: Claude:opus-5-5
aim's "Send without sound" line carries the silent marker outside the
OMEMO envelope, the control line none; Gajim, which lacks the spec,
shows and notifies it like any message, the expected fallback.

Assisted-by: Claude:opus-5-5
aim shares vm-dino's card from the paperclip menu; under OMEMO 2 it
travels inside the envelope and web draws it as a card with Message
and Add contact.

Assisted-by: Claude:opus-5-5
aim shared vm-dino; under OMEMO 0.3 only the fallback body went, and
Gajim showed "👤 vm-dino" with the xmpp: address as a link.

Assisted-by: Claude:opus-5-5
aim's "Send without sound" line carries the silent marker beside the
OMEMO 2 envelope and web marks it with a bell-off sign, the control
line without. web raises no desktop notifications either way.

Assisted-by: Claude:opus-5-5
With aim's Link previews flipped to `always`, aim's link to the forge
page goes with its OpenGraph metadata inside OMEMO 2 and web draws the
card (site, title, description). As on ejabberd: the switch reads on
for libtacky's default `sender`, which attaches nothing, and web's own
link goes without a preview (its browser cannot fetch the page).

Assisted-by: Claude:opus-5-5
The shell ate a backquoted 'sender' when the notes were written.

Assisted-by: Claude:opus-5-5
aim pinned a message from its menu: a sealed urn:tacky:pins:0 publish;
web signed in as vm-aim got the event and showed the pinned bar in the
same chat, and lost it again after aim's unpin.

Assisted-by: Claude:opus-5-5
aim shares a contact card from its paperclip menu; under OMEMO 0.3
only the fallback body travels and Gajim shows the name and an xmpp:
link. Same as on ejabberd and prosody.

Assisted-by: Claude:opus-5-5
aim shares a contact card from its paperclip menu inside the OMEMO
envelopes; web draws it with Message and Add contact. Same as on
ejabberd.

Assisted-by: Claude:opus-5-5
Encrypted (OMEMO 0.3) aim attaches no preview, by design; in clear its
link carries the <rdf:Description/> with title and description and
Gajim 2.6 draws the card. Gajim's own link goes without metadata.

Assisted-by: Claude:opus-5-5
aim left `a<b&"c'` unsent: a sealed drafts publish, and web signed in
as vm-aim showed it in its list and composer; aim's send retracted it.
C3.1 check: a draft pasted with U+0001 U+0002 was published and reached
web too, so C3.1 is fixed in libtacky v1.2.3.

Assisted-by: Claude:opus-5-5
On prosody OCR missed the Create pack dialog's Cancel with the dialog
plainly up, so the pack was never made: fall back to the blue "Choose
pictures…" button by colour. silent.py took the first sent stanza past
the mark, which aim's lagging XML log made an earlier one ("carries
<silent/>: False" while it did): wait for the marker itself.

Assisted-by: Claude:opus-5-5
Selected, the tab's label is blue on white and tesseract read nothing
in it on ejabberd, so tag_chat never opened the tab menu (New tag...).
It now falls back to the tab's place.

Assisted-by: Claude:opus-5-5
"Choose pictures…" is 170 px wide; find_color's default size cap
(120) would have discarded it.

Assisted-by: Claude:opus-5-5
When the example makes the pack first, aim's XML log reaches the host
late and the pack's PEP publish (urn:xmpp:stickers:0, with SFS sources)
lands past the offset taken for the send: the anotherim-server web run
reported 'encrypted False, clear SIMS/SFS True' from that iq while the
sticker itself went inside OMEMO 2. Match a message to the peer only.

Assisted-by: Claude:opus-5-5
vm-aim had no sticker pack here, so the example made one through aim's
Stickers page; aim then sends its sticker from the composer picker
inside OMEMO 2 and web draws it as a sticker. Same as on ejabberd.

Assisted-by: Claude:opus-5-5
aim sends a sticker from its picker; to Gajim's OMEMO 0.3 device only
the aesgcm:// link travels and Gajim shows it as an image card, a
usable fallback. Same as on ejabberd.

Assisted-by: Claude:opus-5-5
aim's 5 minute disappearing timer reaches web as a service row, the
message carries <ephemeral timer='300'/>, and past the timer both sides
show "Message disappeared"; Off is announced too.

Assisted-by: Claude:opus-5-5
aim, with Link previews set to always, sends a link to an OpenGraph page
under OMEMO 2 and web draws the card with the site, title and
description. web's own link back carries no preview, as on ejabberd.

Assisted-by: Claude:opus-5-5
aim's 5 minute timer and message carry <ephemeral timer='300'/>; aim
deletes its copy at the timer, Gajim (no XEP-0466) keeps the line and
shows nothing for the body-less timer notice, as expected.

Assisted-by: Claude:opus-5-5
Assisted-by: Claude:opus-5-5
On anotherim-server tesseract read only the red button's own word
"Disable" and no title, so set_encryption(False) took it for the title
and clicked 227/139 px off, under the dialog: the XEP-0511 Gajim run's
clear leg stayed encrypted. The button's red (217,48,37) is found
reliably; try it before the words.

Assisted-by: Claude:opus-5-5
tag_chat: with Show set to Chosen the editor lists the chats at once
(no "Add chats..."), and the first click into its Search field after
the select's popup is swallowed, so it clicks the field's middle twice;
OCR once read the field's icon as "Add". reorder_pin: the list row is
the name's (a subtitle "Me: Contact: vm-dino" matched first), the
pointer leaves the list before OCR, and the drag starts in the row's
empty middle with Control_L and small steps; the drag with two big
moves from the name did nothing.

Assisted-by: Claude:opus-5-5
aim pins a message in its chat with vm-kaidan; the sealed urn:tacky:pins:0
item reaches its second device (web as vm-aim), which shows the pinned
bar; the unpin removes it there too.

Assisted-by: Claude:opus-5-5
A message pinned on aim is published as one sealed item and the
account's second device (web as vm-aim) draws the pinned bar in that
chat; the unpin clears it there. Same as on ejabberd.

Assisted-by: Claude:opus-5-5
aim made a tag holding vm-kaidan: a sealed urn:tacky:tags:0 publish;
web signed in as vm-aim showed the new tab, and lost it again when aim
deleted the tag.

Assisted-by: Claude:opus-5-5
Under OMEMO 0.3 aim attaches no link metadata; with encryption off its
link carries the rdf Description with og:title, description and
site_name in clear and Gajim 2.6 draws a card from it. The run before
this one was parked: the harness clicked beside the Disable encryption
button and the clear leg stayed encrypted (fixed in 61d15ae).

Assisted-by: Claude:opus-5-5
aim's unsent draft `a<b&"c'` reaches its second device (web as vm-aim)
intact, list row and composer, and is retracted there once aim sends
it. C3.1 fix check: a draft pasted with U+0001 U+0002 is now published,
the control characters dropped (libtacky v1.2.3).

Assisted-by: Claude:opus-5-5
aim's new tag holding its chat with vm-kaidan reaches its second device
(web as vm-aim) as a chat-list tab; deleting it removes the tab there.

Assisted-by: Claude:opus-5-5
In the recorded chatpins run the first Ctrl+drag did nothing again
(the same gesture worked as the second drag in the REPL), so the order
is read after each drag and the drag repeated up to three times; each
drag goes to steps.log.

Assisted-by: Claude:opus-5-5
A draft with a<b&"c' left in aim reaches its second device sealed and
intact (list row and composer); sending it retracts the item and the
other composer empties. C3.1 is fixed: a draft pasted with U+0001 and
U+0002 is published and shows on web with the characters as boxes.

Assisted-by: Claude:opus-5-5
A tag made on aim is published sealed and shows as a tab on the
account's second device; deleting it removes the tab there. Same as on
prosody.

Assisted-by: Claude:opus-5-5
The chatpins drag started 380 px too low: a room row's subtitle
"vm-dino@ejabberd.asxp.io: Group call" starts where names do, and
the name itself was missed by that OCR pass.

Assisted-by: Claude:opus-5-5
reorder_pin failed on anotherim-server because full-screen tesseract
read the pinned 'vm-dino' row as 'vm-' (sparse pass) or not at all,
while the screen plainly showed it. When the name is not found, read
each row's name line alone (ocr_band), locating the rows by their
times on the right; checked on the failed run's screenshot.

Assisted-by: Claude:opus-5-5
One Esc left web's chat search up, so 0492's and chatpins' shots of the
second device showed a list filtered to the 1:1 chat: back out with four
as open_chat does, and also open the muted room there. 0492's restore
removed the bookmark before unmuting (Unmute then had no room): unmute
first. The pinned-chat Ctrl+drag moved nothing (aim published no new
order): move in eight small steps with Ctrl held by its keysym.

Assisted-by: Claude:opus-5-5
anotherim-js's status sheet has no time limit, so aim cannot send an
expiring status. libtacky does the spec: web's API-set "brb" for two
minutes carries <expires/>, aim shows it and drops it when web
publishes the empty mood at the limit.

Assisted-by: Claude:opus-5-5
The chatpins run's full-screen OCR never read the bold "vm-dino" name
at x 64 (only subtitles naming vm-dino), so the drag started on the
wrong row three times. The name is retried, then read band by band,
upscaled, over the name column.

Assisted-by: Claude:opus-5-5
aim pins two chats and Ctrl+drags the second above the first; each
change is one sealed item, and the account's second device lists the
pinned chats in aim's new order.

Assisted-by: Claude:opus-5-5
aim dropped vm-web, made an invitation link and web opened it: web's
subscribe carries the preauth token, aim approves without a prompt and
subscribes back, web approves; both rosters mutual again.

Assisted-by: Claude:opus-5-5
Muting a bookmarked room on aim republishes its bookmark with the
notification-settings <never/>, and the account's second device shows
the room muted. C8 is not exercised: no UI writes <advanced/>. An
earlier run was parked: its shots of the second device showed a
filtered list without the room (fixed in 7d4df21).

Assisted-by: Claude:opus-5-5
aim pinned two chats and Ctrl+dragged one above the other; each change
was a sealed urn:tacky:chatpins:0 publish, and web signed in as vm-aim
showed both pinned and then in aim's new order.

Assisted-by: Claude:opus-5-5
web as a second device of vm-aim, Gajim writing as bob: reading on web
publishes the displayed marker and aim's unread badge goes, reading on
aim clears web's. aim's caps lack +notify for the node, yet it gets
the events.

Assisted-by: Claude:opus-5-5
With Gajim writing to vm-aim, reading the chat on either device of vm-aim
publishes the displayed marker and clears the unread badge on the
other, both ways. Same as on prosody.

Assisted-by: Claude:opus-5-5
aim muted a bookmarked room: the bookmark went out with <notify><never/>
and web signed in as vm-aim showed the room muted; unmute wrote
<on-mention/>. C8 (<advanced/> kept) is not exercised: nothing here
writes <advanced/>.

Assisted-by: Claude:opus-5-5
With Gajim as the second device its chat with BOB stayed open after
it read the first line, so it displayed BOB's second line at once and
aim never showed it unread; the aim-reads leg then had nothing to
mark. Gajim now opens another chat first.

Assisted-by: Claude:opus-5-5
aim dropped vm-web, made an invitation link, and web opened it: web's
subscribe carried the preauth token, aim approved without a prompt and
subscribed back, and both rosters ended mutual.

Assisted-by: Claude:opus-5-5
Gajim as a second device of vm-aim reads web's line and publishes the
displayed marker; aim clears its unread badge from the event. The
reverse leg was not exercised: Gajim's chat stayed open and marked the
next line read itself (no scripted way to close a Gajim chat); the
web-as-vm-aim run covers aim's own publish.

Assisted-by: Claude:opus-5-5
vm-aim had no pack on prosody, so the example made one in aim's
Stickers sheet; aim then sent a sticker from its picker under OMEMO 2
and web shows it as a sticker (no bubble, row "Sticker").

Assisted-by: Claude:opus-5-5
Line 354 is the read of the empty node before it.

Assisted-by: Claude:opus-5-5
aim's sticker reaches Gajim (OMEMO 0.3) as its encrypted aesgcm://
picture; Gajim, without XEP-0449, shows it as an image card, the
expected fallback.

Assisted-by: Claude:opus-5-5
anotherim-js's status sheet has no time limit, so aim publishes only a
plain status. libtacky does the spec both ways: web's API-set status
carries <expires/>, aim shows it and drops it when web clears it at
the limit. Not implemented in the app's UI, as on prosody.

Assisted-by: Claude:opus-5-5
Dino wrote to vm-aim with aim and web (as vm-aim) both showing an
unread badge; whichever device read the chat published its displayed
state (urn:xmpp:mds:displayed:0, stanza-id by the account) and the
other device's badge went, both ways.

Assisted-by: Claude:opus-5-5
aim pins two chats and Ctrl+drags the second above the first; each
change is one sealed urn:tacky:chatpins:0 publish and its second device
(web as vm-aim) shows the same pinned rows in the same order.

Assisted-by: Claude:opus-5-5
aim drops vm-web, makes an invitation link from its compose menu and
web accepts it: the subscribe carries the preauth token, aim approves
without a prompt and subscribes back, mutual again. The token, left in
server.log by the finish step's redaction, is redacted there by hand
(the file's hash in run.toml updated).

Assisted-by: Claude:opus-5-5
Results of the anotherim-server batch 3 cells and what the runs taught
the harness: the schedule sheet's date-time field, OCR of aim's timer
and Send menus, the Disable encryption and sticker pack buttons by
colour, list rows from OCR bands, the Gajim second device's open chat
in xep0490, and the preauth token left in server.log.

Assisted-by: Claude:opus-5-5
web wrote to vm-aim while aim and Gajim (signed in as vm-aim) both
showed it unread; Gajim's read published urn:xmpp:mds:displayed:0 and
cleared aim's badge, and aim's read cleared Gajim's.

Assisted-by: Claude:opus-5-5
aim mutes a bookmarked room: the bookmark goes out with
<notify><never/></notify> and its second device (web as vm-aim) shows
the room muted; unmute writes <on-mention/>. C8's <advanced/> is not
exercised (no client here writes one).

Assisted-by: Claude:opus-5-5
aim's status sheet has no time limit, so the app under test cannot
publish an expiring status. libtacky can: web set one for two minutes
through its API, aim showed it and dropped it at the limit. Same as on
prosody and anotherim-server.

Assisted-by: Claude:opus-5-5
The results of batch 3 on ejabberd and what the runs taught the
harness: aim's Link previews switch reading on for `sender`, the empty
sticker picker, Gajim's narrow composer and a Ctrl+N that opened a
room, aim's tag editor and pin drag on 142ee094, and never starting a
run in the same command as a rebase.

Assisted-by: Claude:opus-5-5
open_uri logged the xmpp:…?roster;preauth=TOKEN it was handed, and
interop check flags the token as an unredacted secret (prosody's
XEP-0379 run needed it scrubbed by hand). _action now logs it as
preauth=[REDACTED].

Assisted-by: Claude:opus-5-5
Gajim as a second device of vm-aim, web writing as bob, Gajim moved off
bob's chat before each line: reading on Gajim clears aim's unread badge
and reading on aim clears Gajim's, both through the
urn:xmpp:mds:displayed:0 node.

Assisted-by: Claude:opus-5-5
Results of the 30 prosody runs (24 pass, 6 fail, gaps empty) and what
the harness learned: Prosody's room lock also hits rooms web makes,
the second device's list must be backed out of its search, Gajim as
G= must leave bob's chat, preauth tokens are redacted in steps.log,
silent.py waits for its marker, and backquotes in finish notes.

Assisted-by: Claude:opus-5-5
_composer_gajim looked for the list's blue + in rows 110-165, where a
blue link in the chat pane's top line joined the colour box; the box
was then too wide, and the -250 fallback clicked the room row at the
bottom of the list, which opened and took the typed line. It looks in
rows 125-150 with a tighter fuzz, after focusing the window.

Assisted-by: Claude:opus-5-5
The redaction in _action missed the same URI typed into web's invite
field (type() logs its text): do it in step_log, so every line is
covered. Checked with an explore run of xep0379.

Assisted-by: Claude:opus-5-5
Assisted-by: Claude:opus-5-5
vm: XEP-0490 anotherim-js vs Gajim on anotherim-server, re-run, pass
All checks were successful
/ check (pull_request) Successful in 13m2s
30f1c0a624
The first run (043251) left Gajim, the second device of vm-aim, in
web's chat, so Gajim marked web's second line read itself and aim's
publish was never needed. With xep0490 at 5585d53 Gajim stays in
another chat: Gajim's read clears aim's badge and aim's read clears
Gajim's, both through urn:xmpp:mds:displayed:0, as on prosody and
ejabberd.

Assisted-by: Claude:opus-5-5
asxpi merged commit 07c70a84d4 into main 2026-11-10 05:50:51 +00:00
Sign in to join this conversation.
No reviewers
No labels
No milestone
No assignees
1 participant
Notifications
Due date
The due date is invalid or out of range. Please use the format "yyyy-mm-dd".

No due date set.

Dependencies

No dependencies set

Reference
another-im/interop!23
No description provided.