The iOS and desktop smoke tests looked for the note "All results on this page are
already in your chats", which the app no longer shows. As nothing marks the end of
a search that adds no row, they wait out the request (it times out after 10 s),
retry once if it failed, and check the listed chat, no result row for it, no Open
and no note. The test plans, prompts and READMEs say the same, and New chat's
results as one group with the matching contacts first.
xdotool key reads a later argument that names one of its commands, exec among them, as that command, and mousemove takes a single word, so "ui key Return exec <program>" or "ui click restore exec ..." ran a program on the runner. The Claude session on the runner is limited to ui commands, and a program could read its token. Key names and numbers are now checked, and keys are pressed one per call.
Review: R1-D1, R1-D2
The first desktop run showed "2 subscribers" in the toolbar and the banner, which the check counting "1 subscriber" missed, and Escape doesn't close the chat list's menus on desktop.
Run: 011-search-redesign, slice 4 (feature CI fix)
The smoke test's search case and the Claude search prompt check the enable alert (Cancel sends nothing, Enable searches, the other layout doesn't ask), one list with Open and no headers, the load row's count, the Enter key searching the directory with "Connect to …" kept and no names part, Open reaching the prepared channel without an alert and with its subscriber count, the known channel as a chat row, New chat's card, and the right-click menu. Transient screens are read before their screenshots.
Run: 011-search-redesign, slice 4 (feature CI)
That menu opens over the server address's QR code, where OCR can miss its "yes" (run 39242250150 failed its setup three times on it), so the smoke test finds the menu's first item, which repeats the field's value and reads well, and clicks the row under it. The check that the role is now yes stays.
[claude-test:desktop] [ci-backend]
The artifact carrying the app job's stopped test backend to the Claude job holds its databases and server keys, which anyone signed in to GitHub can download for the day it is kept. The READMEs now say so, what someone could do with it, and why encrypting it isn't possible under the Claude job's one-secret rule.
Review R1-1, run 008-dirsearch-known-chats
[app-ci:ios] [ci-backend]
The app is built in the app job with that job's backend's directory address in DIRECTORY_SERVICE_LINK, and since master moved Claude into its own job, that job started a new backend with another address. The app job now uploads its stopped backend's work dir (without the binaries), and the Claude job restarts it with a new backend.sh resume: the same servers' keys and databases, so the same addresses. The relay, directory, names server and contacts start through the functions start uses, split out of it. The iOS Claude job's smoke test also gets BACKEND_DIR, as the app job's does.
[claude-test] [ci-backend]
After joining ci_channel, the scripted search case checks in both layouts that searching its name shows the note "All results on this page are already in your chats" and no Directory row, and that a search the local list doesn't match shows ci_channel as a chat row that opens it, not "#ci_channel" with "Join channel"; New chat shows it as a contact-style row. The Claude search test's part C expects the same.
Run: 008-dirsearch-known-chats, slice 5
[claude-test] [ci-backend]
Desktop always lists the chat open in the right pane, so with ci_channel open its Directory row was rightly hidden and step C.3 had nothing to click (run 39001925386). Also runs the iOS names session again: that run's backend stopped when the directory could not connect to a channel's link.
[claude-test] [ci-backend]
ci_channel's description matches "seed", so the list showed it and the step's premise was wrong; a name narrows the list instead. Desktop keeps the open chat in the filtered list, so "No chats found" can't be required while a chat is open (run 38994540038).
Part C joins a channel from its Directory row, then checks that the joined chat is not listed again by the directory when the local list shows it, that it is when the list doesn't, the empty result, an unregistered name, and that only the Search key resolves names. The session gets 120 turns for it.
[claude-test:desktop] [ci-backend]
With the test backend, the Claude job builds the app against the test directory, sets it up at the chat list and gives Claude the online search test; without it, the onboarding path stays.
With the test backend, the app is built against the test directory's address, and the smoke test runs a new search case: after the backend case's checks, in both layouts, "Search in Directory" and the full search with a SimpleX name, and with the toolbar at the bottom the full search in the New chat sheet.
A fresh client sends the directory the search the app sends and follows the cursor to the last page: each result must arrive once with its whole image, over at least two pages. The message search stays.