vm: Dino on anotherim-server, anotherim-web runs, test card #11

Merged
asxpi merged 66 commits from vms/runs-2 into main 2026-11-09 00:00:57 +00:00
Member

More GUI VM runs and harness work after #10.

Runs (vm:, all agent-judged, driven = "vm"):

  • Dino on anotherim-server, now that the test server allows SCRAM-SHA-1 (5ca94bd): 10 runs.
  • Dino call retest with a working fake camera (P3 in #9).
  • anotherim-js (desktop) vs anotherim-web, the browser build of the same commit, on all three servers: 39 runs, 37 pass; fails are C35 and P2. New findings C39 and M28 in #9.

Harness (vms:):

  • --client web --web DIR: anotherim-web in Chromium, XML log over DevTools, fake camera/mic via Chromium capture files.
  • fake camera fixed (gst plugin path, c137b7b) and fed a TV test card (label, corners, clock, frame counter).
  • keyring crash recovery, screensaver off, clock sync after freeze.
  • vms/AGENTS.md, vms/scenarios/, vms/tools/: the agents' toolbox (scenarios get consolidated on vms/consolidate).

Issue #9 links to these runs on this branch; after the merge they're also on main.

🤖 Generated with Claude Code

More GUI VM runs and harness work after #10. Runs (`vm:`, all agent-judged, `driven = "vm"`): - Dino on anotherim-server, now that the test server allows SCRAM-SHA-1 (5ca94bd): 10 runs. - Dino call retest with a working fake camera (P3 in #9). - anotherim-js (desktop) vs anotherim-web, the browser build of the same commit, on all three servers: 39 runs, 37 pass; fails are C35 and P2. New findings C39 and M28 in #9. Harness (`vms:`): - `--client web --web DIR`: anotherim-web in Chromium, XML log over DevTools, fake camera/mic via Chromium capture files. - fake camera fixed (gst plugin path, c137b7b) and fed a TV test card (label, corners, clock, frame counter). - keyring crash recovery, screensaver off, clock sync after freeze. - `vms/AGENTS.md`, `vms/scenarios/`, `vms/tools/`: the agents' toolbox (scenarios get consolidated on `vms/consolidate`). Issue #9 links to these runs on this branch; after the merge they're also on main. 🤖 Generated with [Claude Code](https://claude.com/claude-code)
Dino 0.5.1 knows only PLAIN and SCRAM-SHA-1, and anotherim-server
offers only SCRAM-SHA-256/512(-PLUS), so Dino could not sign in to the
test server ("No supported mechanism provided by server") and had no
runs there.

Patch the copied ejabberd.yml before the image is built: store
scram_sha1 as a third hash and stop disabling SCRAM-SHA-1(-PLUS).
PLAIN stays off. The upstream anotherim-server repo is unchanged. An
account has the SHA-1 hash only after its password is set again; on
2026-11-08 that was done for vm-dino only, with its unchanged password.
Dino then signed in with SCRAM-SHA-1; Gajim, Kaidan and anotherim-js
still sign in.

Assisted-by: Claude:opus-5-5
AnotherIM 0.8.0-rc9 (develop 142ee094, libtacky v1.2.3) and Dino 0.5.1
in vms/ VMs on anotherim-server, now that it offers SCRAM-SHA-1.

Both directions under OMEMO 0.3: each correction carries <replace/>
with the original's id, and each side shows a single edited bubble
with the corrected text (shot-2, shot-4).

Assisted-by: Claude:opus-5-5
AnotherIM 0.8.0-rc9 (develop 142ee094, libtacky v1.2.3) and Dino 0.5.1
in vms/ VMs on anotherim-server.

Messages both ways go as OMEMO 0.3 (eu.siacs.conversations.axolotl) in
both logs and show decrypted on both screens. AnotherIM flags Dino's
device as using the older OMEMO 0.3 and offers it for review.

Assisted-by: Claude:opus-5-5
anotherim-js's browser build is the same app as the desktop AppImage on
another transport (XMPP over WebSocket, the wasm backend in a worker, the
store in OPFS), so runs of the AppImage against it test the two builds
against each other.

--client web --web DIR serves DIR (make web's dist/web) on localhost in
the guest, opens it in a Chromium app window and grants camera,
microphone and notifications over DevTools. The web build has no XML log
of its own, so interop-web turns each account's XML console on through
the page's anotherim.store.api and writes every element to /out/web.log
in the desktop XML log's JSON lines (backlog included), which the aim
regexes read as they are. Sign-in clicks are found by OCR with tesseract
5 (the driver's 4.1 misses the address field), and the password is
typed only once the address shows in the focused field.

With --record a web peer is clients.toml's anotherim-web, its log
peer-anotherim-web.log and its version taken from DIR's name.

Assisted-by: Claude:opus-5-5
No audio from Dino in a video call is a known Dino bug (the user,
2026-11-09), not anotherim-js: mark both runs cause peer, as #9 now
lists it under the peers (P3).

Assisted-by: Claude:opus-5-5
AnotherIM 0.8.0-rc9 (develop 142ee094, libtacky v1.2.3) and Dino 0.5.1
in vms/ VMs on anotherim-server.

Each side answers the other's receipt request with <received/> naming
the message id, and the sender's ticks turn delivered (shot-1, shot-6).
Neither raised a desktop notification while its window had focus.

Assisted-by: Claude:opus-5-5
Chromium killed at shutdown leaves SingletonLock naming the node it ran
on; booted as another node (machine, then peer) it took the profile for
one in use on another computer and never opened a window.

Assisted-by: Claude:opus-5-5
The desktop AppImage and the browser build of the same commit (rc9,
142ee094, libtacky v1.2.3) corrected a message each way over OMEMO 2;
each side showed a single bubble with the corrected text marked edited.
<replace/> travels inside the SCE envelope, so only screens show it.

Assisted-by: Claude:opus-5-5
AnotherIM 0.8.0-rc9 (develop 142ee094, libtacky v1.2.3) and Dino 0.5.1
in vms/ VMs on anotherim-server.

AnotherIM sends <displayed/> for Dino's message only once its chat is
opened, and Dino's tick turns to read. Dino has the chat open from
start, so it marks AnotherIM's message displayed at once, and
AnotherIM shows it as seen.

Assisted-by: Claude:opus-5-5
The desktop AppImage and the browser build of the same commit (rc9,
142ee094, libtacky v1.2.3) corrected a message each way over OMEMO 2;
each side showed a single bubble with the corrected text marked edited.
<replace/> travels inside the SCE envelope, so only screens show it.

Assisted-by: Claude:opus-5-5
Both builds of rc9 encrypt with OMEMO 2 and decrypt each other's
messages; each side lists the other's devices with fingerprints as
undecided. The receipts and read markers for the encrypted messages go
in the clear.

Assisted-by: Claude:opus-5-5
Both builds of rc9 encrypt with OMEMO 2 and decrypt each other's
messages; each side lists the other's devices with fingerprints as
undecided. The receipts and read markers for the encrypted messages go
in the clear.

Assisted-by: Claude:opus-5-5
AnotherIM 0.8.0-rc9 (develop 142ee094, libtacky v1.2.3) and Dino 0.5.1
in vms/ VMs on anotherim-server.

A thumbs-up each way: <reactions/> names the target message's id, and
both screens show 👍1 under the right message (shot-3, shot-6).

Assisted-by: Claude:opus-5-5
Each OMEMO 2 message got a receipt from the other build within a
second and the sender's ticks turned to delivered, both ways. The
receipts travel unencrypted beside the encrypted messages.

Assisted-by: Claude:opus-5-5
Each OMEMO 2 message got a receipt from the other build within a
second and the sender's ticks turned to delivered, both ways. The
receipts travel unencrypted beside the encrypted messages.

Assisted-by: Claude:opus-5-5
AnotherIM 0.8.0-rc9 (develop 142ee094, libtacky v1.2.3) and Dino 0.5.1
in vms/ VMs on anotherim-server.

A reply each way under OMEMO 0.3: <reply/> carries the quoted message's
id, with a XEP-0428 fallback, and both screens draw the quote above the
answer (shot-4, shot-7). Dino's <reply to=> names its own full JID, but
AnotherIM attributes the quote by id anyway.

Assisted-by: Claude:opus-5-5
Each build sent <displayed/> only when its user opened the chat, and the
other build turned the message's ticks to read, both ways. The markers
travel unencrypted beside the OMEMO 2 messages.

Assisted-by: Claude:opus-5-5
Each build sent <displayed/> only when its user opened the chat, and the
other build turned the message's ticks to read, both ways. The markers
travel unencrypted beside the OMEMO 2 messages.

Assisted-by: Claude:opus-5-5
AnotherIM 0.8.0-rc9 (develop 142ee094, libtacky v1.2.3) and Dino 0.5.1
in vms/ VMs on anotherim-server, with fake 440/660 Hz microphones.

An audio call and then a video call from AnotherIM to Dino, both via
XEP-0353 propose/proceed and Jingle RTP over ICE-UDP. In both calls each
side hears the other's tone (share 0.99-1.00). On ejabberd, AnotherIM
played no audio from Dino in a video call (a known Dino bug); that did
not happen here. The video areas show black, and video is not judged.

Assisted-by: Claude:opus-5-5
A thumbs-up reaction from each build showed under the right message on
the other. In the OMEMO 2 chat the reactions travel unencrypted, as
libtacky leaves bodyless signals out of the envelope.

Assisted-by: Claude:opus-5-5
A thumbs-up reaction from each build showed under the right message on
the other. In the OMEMO 2 chat the reactions travel unencrypted, as
libtacky leaves bodyless signals out of the envelope.

Assisted-by: Claude:opus-5-5
AnotherIM 0.8.0-rc9 (develop 142ee094, libtacky v1.2.3) and Dino 0.5.1
in vms/ VMs on anotherim-server.

An image each way in an OMEMO 0.3 chat. Each sender gets a slot from
the server and puts the encrypted file in the S3 upload bucket. The
link goes inside OMEMO, and the picture shows inline on the other side
(shot-4, shot-8). Neither side used SFS.

Assisted-by: Claude:opus-5-5
A reply from each build showed on the other with a quote of the right
message. Under OMEMO 2 the reply element and its fallback travel inside
the envelope, so only the screens show them.

Assisted-by: Claude:opus-5-5
A reply from each build showed on the other with a quote of the right
message. Under OMEMO 2 the reply element and its fallback travel inside
the envelope, so only the screens show them.

Assisted-by: Claude:opus-5-5
AnotherIM 0.8.0-rc9 (develop 142ee094, libtacky v1.2.3) and Dino 0.5.1
in vms/ VMs on anotherim-server.

AnotherIM created a new room (201) and Dino joined it through Join
Channel. Groupchat messages each way show on both sides, and Dino lists
vm-aim as moderator. AnotherIM still sends no instant-room config, but
anotherim-server opens such a room, so this works here, while on
Prosody the room stays locked.

Assisted-by: Claude:opus-5-5
Each build retracted its own message and the other replaced it with
"Message retracted". The retraction goes unencrypted beside the OMEMO 2
chat with a plain fallback body; the retracted text stays encrypted.

Assisted-by: Claude:opus-5-5
fake_av's camera pipeline never ran: makeSearchPath took
gst_all_1.gstreamer's default output, bin, which has no
lib/gstreamer-1.0, so coreelements (capsfilter) was missing and
gst-launch failed with "could not link videotestsrc0 to videoconvert0
with caps ...". The audio pipeline has no caps filter and worked, which
hid it: every fake-av.log so far has the error.

With exclusive_caps=1 an unfed v4l2loopback is an output-only device,
so clients saw no camera; Dino logged "No preferred device for outgoing
video". Fed, GStreamer's device monitor lists FakeCam as Video/Source.

Assisted-by: Claude:opus-5-5
Each build retracted its own message and the other replaced it with
"Message retracted". The retraction goes unencrypted beside the OMEMO 2
chat with a plain fallback body; the retracted text stays encrypted.

Assisted-by: Claude:opus-5-5
With aim's link down for 30 s, a message the web sent arrived once when
the link came back, on the same stream with stream management acks; no
duplicate on screen. The outage was too short for a resumption.

Assisted-by: Claude:opus-5-5
interop check failed the pass because the logs never show muc#owner or
jabber❌conference: AnotherIM sends no instant-room configuration,
which anotherim-server does not need, and Dino joined by address, not
by invitation. Record that in markers_missing.

Assisted-by: Claude:opus-5-5
AnotherIM 0.8.0-rc9 (develop 142ee094, libtacky v1.2.3) and Dino 0.5.1
in vms/ VMs on anotherim-server, in a room AnotherIM created and Dino
joined.

AnotherIM published an autojoin bookmark when it joined. After a quit
and restart it read the bookmark back and rejoined the room by itself.
Bookmarks are per account, so this checks AnotherIM's own round trip,
with a peer in the room.

Assisted-by: Claude:opus-5-5
With aim's link down for 30 s, a message the web sent arrived once when
the link came back, on the same stream with stream management acks; no
duplicate on screen. The outage was too short for a resumption.

Assisted-by: Claude:opus-5-5
The desktop AppImage and the browser build of the same commit (rc9,
142ee094, libtacky v1.2.3) corrected a message each way over OMEMO 2;
each side showed a single bubble with the corrected text marked edited.
<replace/> travels inside the SCE envelope, so only screens show it.

Assisted-by: Claude:opus-5-5
Both builds of rc9 encrypt with OMEMO 2 and decrypt each other's
messages; each side lists the other's devices with fingerprints as
undecided. The receipts and read markers for the encrypted messages go
in the clear.

Assisted-by: Claude:opus-5-5
Each OMEMO 2 message got a receipt from the other build within a
second and the sender's ticks turned to delivered, both ways. The
receipts travel unencrypted beside the encrypted messages.

Assisted-by: Claude:opus-5-5
Each build sent <displayed/> only when its user opened the chat, and the
other build turned the message's ticks to read, both ways. The markers
travel unencrypted beside the OMEMO 2 messages.

Assisted-by: Claude:opus-5-5
Retest of the video-call finding with Dino's camera working (the fake
camera was never fed before: see the vms: interop-gst fix). Dino no
longer logs "No preferred device for outgoing video", and AnotherIM
shows Dino's live test pattern, so Dino sends video. In this run
AnotherIM still played no audio from Dino (speaker all zero, share
0.00) in both the audio-only and the video call, while Dino heard
AnotherIM's 440 Hz (0.99/1.00).

The next two runs with the same setup carried audio both ways, so this
silence is intermittent; which side drops it is not established.

Assisted-by: Claude:opus-5-5
Repeat with Dino's camera working. Audio call and video call carried
audio both ways: AnotherIM hears Dino's 660 Hz (share 1.00 in both),
Dino hears AnotherIM's 440 Hz (0.99, 1.00). PipeWire dumps during the
calls show each client's playback stream on the recorded sink and
capture from the fake mic. Video areas black in the screenshots.

Assisted-by: Claude:opus-5-5
Second repeat with Dino's camera working. In the video call AnotherIM
hears Dino's 660 Hz (share 1.00) and shows Dino's live test pattern,
Dino hears AnotherIM's 440 Hz (0.99); the audio call before it carried
audio both ways too. So Dino 0.5.1 sends audio and video in a video
call when it has a camera.

Assisted-by: Claude:opus-5-5
Both runs' fake camera was never fed, so Dino had no camera. Retests
with a working camera carried Dino's audio in the video call twice and
were silent once, and anotherim-server carried it without a camera, so
the silence is intermittent rather than the missing camera. Verdicts
unchanged.

Assisted-by: Claude:opus-5-5
Browser.grantPermissions failed as a whole on the clipboard permission
names and the error went unread, so Chromium asked for the microphone
in a prompt during a call (the web side stuck on Connecting) and never
had the notification permission. Grant notifications, camera and
microphone only, fail loudly, and keep --use-fake-ui-for-media-stream
behind it, with --test-type so its warning bar does not shift the page.

Assisted-by: Claude:opus-5-5
After 13 minutes offline aim resumed its session and ran its MAM
catch-up; the two messages the web sent meanwhile came by both ways and
showed once each, in order, at their send times.

Assisted-by: Claude:opus-5-5
A pasted picture from each build was uploaded (the browser's PUT going
cross-origin to Prosody's file share), sent over OMEMO 2 and shown
inline on the other.

Assisted-by: Claude:opus-5-5
The room the desktop build created was never unlocked (no muc#owner
submit after the 201), so Prosody refused the browser build's join with
item-not-found. libtacky's known missing instant-room submit.

Assisted-by: Claude:opus-5-5
Both builds publish an autojoin bookmark with publish-options; after a
reload the browser build fetched it and went for the room at once. The
room itself was gone (the locked-room bug destroys it with its last
occupant), so the rejoin could not be shown on Prosody.

Assisted-by: Claude:opus-5-5
After 13 minutes offline aim's resumption failed as the session had
timed out; it started anew and caught up through MAM. The two messages
the web sent meanwhile showed once each, in order, at their send times.

Assisted-by: Claude:opus-5-5
A pasted picture from each build was uploaded (the browser's PUT going
cross-origin to ejabberd's upload), sent over OMEMO 2 and shown
inline on the other.

Assisted-by: Claude:opus-5-5
The VM runs of 2026-11-08 were driven by scenario scripts and shell
helpers kept in each agent's scratchpad, so every agent rediscovered
the same click positions, OCR blind spots and client quirks. Move the
ejabberd agent's set into the repo so the next one starts from it:

- vms/scenarios/: receipts/markers, reactions/replies/retraction,
  OMEMO, network faults, calls, uploads, carbons, MUC and bookmarks,
  with a shared prelude (OCR via host tesseract, domain from aim's JID).
- vms/tools/: vmrun, sheet, finish and commit for a recorded run,
  parametrised by SERVER, LIBTACKY and APPIMAGE.
- vms/AGENTS.md: how to use them, per-client positions and pitfalls,
  the results of the 91 VM runs and the bugs behind the 12 fails, and
  the rule that agents add what they learn here.

Assisted-by: Claude:opus-5-5
The fake camera showed a bouncing ball, which says nothing about whose
video a screenshot shows, whether it is cropped or whether it froze.

fake_av() now feeds SMPTE bars with the sender's label in the middle
("<client> → <freq> Hz", or label=), TL/TR/BL/BR in the corners, a wall
clock at the top and a frame counter at the bottom. harness-test.py
grabs one frame per VM from /dev/video10 into /out/camera-<freq>.png;
it passes with Gajim and Dino on prosody.

Assisted-by: Claude:opus-5-5
The desktop build created a room, the browser build joined it, both
listed each other as members and saw each other's lines. ejabberd does
not keep the unconfigured room locked, unlike Prosody.

Assisted-by: Claude:opus-5-5
The run joins a room and talks in it; nothing in it configures the room,
changes roles or invites, so interop check wants the reason.

Assisted-by: Claude:opus-5-5
Chromium in the guest lists no v4l2loopback camera, fed or not, before
or after its start, so every video call the web build answered ended in
general-error. For client web, fake_av also writes its tone as a WAV and
the test card as a y4m, and interop-web hands them to Chromium as its
camera and microphone (--use-fake-device-for-media-stream with the file
flags) when they exist at launch: call fake_av before start for web.

Assisted-by: Claude:opus-5-5
Both builds published an autojoin bookmark for the shared room; after a
page reload the browser build fetched its bookmarks and rejoined the
room from them.

Assisted-by: Claude:opus-5-5
Audio and video calls from the desktop build to the browser build
connected over the server's STUN/TURN and each side heard the other's
tone. The web's test card showed on aim; aim's video stayed black on the
web, as aim's camera never showed in the VMs before either.

Assisted-by: Claude:opus-5-5
Audio and video calls from the desktop build to the browser build
connected over ejabberd's STUN/TURN and each side heard the other's
tone. The web's test card showed on aim; aim's video stayed black on the
web, as aim's camera never showed in the VMs before either.

Assisted-by: Claude:opus-5-5
Both calls were proposed, answered and accepted, but with no STUN/TURN
offered by the test Prosody each VM has only a host candidate behind its
own NAT, so ICE failed and both ended in connectivity-error. The same
calls connect on the other two servers.

Assisted-by: Claude:opus-5-5
A thumbs-up reaction from each build showed under the right message on
the other. In the OMEMO 2 chat the reactions travel unencrypted, as
libtacky leaves bodyless signals out of the envelope.

Assisted-by: Claude:opus-5-5
A reply from each build showed on the other with a quote of the right
message. Under OMEMO 2 the reply element and its fallback travel inside
the envelope, so only the screens show them.

Assisted-by: Claude:opus-5-5
Each build retracted its own message and the other replaced it with
"Message retracted". The retraction goes unencrypted beside the OMEMO 2
chat with a plain fallback body; the retracted text stays encrypted.

Assisted-by: Claude:opus-5-5
A pasted picture from each build was uploaded (the browser's PUT going
cross-origin to the server's S3 bucket), sent over OMEMO 2 and shown
inline on the other.

Assisted-by: Claude:opus-5-5
The desktop build created a room, the browser build joined it, both
listed each other as members and saw each other's lines. anotherim-server does
not keep the unconfigured room locked, unlike Prosody.

Assisted-by: Claude:opus-5-5
Both builds published an autojoin bookmark for the shared room; after a
page reload the browser build fetched its bookmarks and rejoined the
room from them.

Assisted-by: Claude:opus-5-5
With aim's link down for 30 s, a message the web sent arrived once when
the link came back, on the same stream with stream management acks; no
duplicate on screen. The outage was too short for a resumption.

Assisted-by: Claude:opus-5-5
vm: XEP-0313 anotherim-js vs anotherim-web on anotherim-server, pass
All checks were successful
/ check (pull_request) Successful in 4m18s
f81da4ea8f
After 13 minutes offline aim's resumption was refused and its MAM
catch-up alone brought the two messages the web sent meanwhile; they
showed once each, in order, at their send times. The script's live-only
waiter timed out; the screens and the MAM results decide.

Assisted-by: Claude:opus-5-5
asxpi merged commit 7f10ccbb34 into main 2026-11-09 00:00:57 +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!11
No description provided.