# Public threads elsewhere (owner decision 2026-10-06): alice's public post names its `replies` and `context`, so a # Mastodon reader who follows alice, opening the thread, finds carol's reply although nobody on Mastodon follows carol # (Mastodon reads a thread's replies at most every fifteen minutes, five minutes after it first holds the post: the # scenario makes its copy look older). Needs the mastodon peer. M=https://mastodon.test:6443 mcurl() { curl -sk --resolve mastodon.test:6443:127.0.0.1 "$@"; } . "$here/peers/mastodon.sh" m_rails() { podman exec pasture-mastodon bin/rails runner "$1" 2>/dev/null | tail -1; } echo "threads" AT=$(privapub_token alice_thread); CT=$(privapub_token carol_thread) [ -n "$AT" ] && [ -n "$CT" ] && ok "PrivaPub tokens for alice_thread and carol_thread" || { ko "PrivaPub tokens"; return 1; } MT=$(mastodon_token) MH="Authorization: Bearer $MT" run=$(date +%s) alice_on_m=$(mcurl -H "$MH" "$M/api/v2/search?q=@alice_thread@privapub.test&resolve=true&type=accounts" | j "print(d['accounts'][0]['id'])") mcurl -o /dev/null -X POST -H "$MH" "$M/api/v1/accounts/$alice_on_m/follow" until_true 45 '[ "$(mcurl -H "$MH" "$M/api/v1/accounts/relationships?id[]=$alice_on_m" | j "print(d[0][\"following\"])")" = "True" ]' \ && ok "mastouser follows alice" || ko "mastouser never followed alice" root=$(curl -s -X POST -H "Authorization: Bearer $AT" "$P/api/v1/statuses" -d "status=a question for the thread $run&visibility=public") root_uri=$(echo "$root" | j "print(d['uri'])") reply_uri=$(curl -s -X POST -H "Authorization: Bearer $CT" "$P/api/v1/statuses" -d "status=an answer from carol $run&visibility=public&in_reply_to_id=$(echo "$root" | j "print(d['id'])")" | j "print(d['uri'])") until_true 45 '[ "$(m_rails "puts Status.exists?(uri: \"$root_uri\")")" = "true" ]' && ok "alice's post reaches Mastodon" || ko "alice's post never reached Mastodon" # (PrivaPub never sends it there; a relay Mastodon has just left, in the scenario before, may still pass it on) p_sent_to_mastodon() { podman exec pasture-mongo mongosh --quiet PrivaPub --eval "print(db.Job.find({Kind: 0, CreatedAt: {\$gt: new Date(Date.now() - 600000)}}).toArray().filter(j => j.Payload.includes('\"Inbox\":\"https://mastodon.test') && j.Payload.includes('$1')).length)"; } [ "$(p_sent_to_mastodon "$reply_uri")" = "0" ] && ok "carol's reply is not delivered there" || ko "PrivaPub delivered carol's reply to Mastodon unasked" m_rails "Status.find_by(uri: \"$root_uri\").update_columns(created_at: 10.minutes.ago, fetched_replies_at: nil)" >/dev/null root_on_m=$(m_rails "puts Status.find_by(uri: \"$root_uri\").id") mcurl -o /dev/null -H "$MH" "$M/api/v1/statuses/$root_on_m/context" until_true 60 '[ "$(m_rails "puts Status.exists?(uri: \"$reply_uri\")")" = "true" ]' \ && ok "opening the thread on Mastodon finds carol's reply through its replies" || ko "Mastodon never found carol's reply"