T14: Lemmy 1.0 in the pasture

peers/lemmy.sh runs the Lemmy 1.0.0-beta.2 backend on the shared Postgres. It trusts
Caddy's CA through SSL_CERT_FILE and reaches the pasture through
DANGER_FEDERATION_ALLOW_LOCAL_IP. Lemmy 0.19 cannot join: its rustls trusts only its
bundled roots. LEMMY_LOG sets RUST_LOG.

scenarios/lemmy.sh drives Lemmy through its v4 API. 20 checks pass, three runs in a row:
- communities both ways;
- a titled thread each way, and alice's mention of a Lemmy community becoming a thread
  there;
- the Lemmy community's announce reaching alice's home;
- comments both ways and alice's like as an upvote;
- private messages both ways;
- statistics.

Two expected failures: votes, which Lemmy sends only through the community as
Announce{Like|Dislike}, and a moderator's removal. Both belong to P7.

What it showed, in docs/INTEROP.md:
- Lemmy 1.0 keeps its user's thread in a remote community pending until the community
  announces it back. It clears the flag before answering that echo 400 ("Object is not
  remote"). Leaving the author's server out of the Announce, as tried here, left every
  such thread pending, so GroupDistributor now says why the echo stays.
- Every bare Announce{object} is answered 400, as Lemmy answers its own compatibility
  Announce(Page).

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01ELjqpznMFMNrJoJUj6K5p2
This commit is contained in:
thepraandClaude Opus 5.5 committed 2026-10-03 14:24:15 +02:00
1 parent e29da1b47a
commit aa7e43a61e
7 files changed
+182 -3

No files matched your search

+26 -1
View File
@@ -427,7 +427,7 @@ on a Page: pins live in `featured`, locks in `Lock`.
| Link posts: keep `Link.href`, the thumbnail `image` and alt text; build the card (Lemmy sends no title or description for the link) | P1 | `Status.card` |
| `ChatMessage` in and out (out only to Lemmy < 1.0 and Mbin; `Note` to everyone else) | P1 | `visibility: direct` |
| Outbound shape for Lemmy: both `to` and `cc`; the community in `to`; Public in the object, Create and Announce; votes and comments sent to the community inbox | P1 | — |
| Communities we host: announce to every follower instance including the author's; pick `Announce(object)` per peer by NodeInfo (as PieFed does) | P1 | — |
| Communities we host: pick `Announce(object)` per peer by NodeInfo (as PieFed does). Announcing to every follower instance, the author's included, is done and needed (pasture evidence below) | P1 | — |
| Flags from a `Service`-typed reporter actor with `to: [community]`; the reporter stays anonymous | P2 | — |
| `Warn` → `moderation_warning` notification; `Resolve{Flag}` | P2 | AccountWarning |
| Remote communities: `description`, `language[]`, private (`locked`), `discoverable`; post tags | P2 | `Account.locked`, own `privapub.flairs[]` |
@@ -435,6 +435,31 @@ on a Page: pins live in `featured`, locks in `Lock`.
| `Feed` actors | P2 | group-like account |
| Read 1.0 `context`, grouped by root post; cross-post detection by URL | P3 | — |
**Pasture evidence (2026-10-03, Lemmy 1.0.0-beta.2, `tools/pasture/scenarios/lemmy.sh`):** 20 checks pass and 3 are
expected failures:
- communities both ways: Lemmy follows ours and alice follows Lemmy's, each Accept arriving;
- a Lemmy thread in our community arrives with its title, and our titled community post reaches Lemmy;
- the Lemmy community's Announce brings its thread to alice's home;
- alice's post mentioning a Lemmy community lands in it, titled from its first line (Lemmy repeats that line in the
body);
- comments both ways, and alice's like counted as an upvote;
- private messages both ways: 1.0 takes our single-recipient direct `Note`, and sends its own as `Note`s;
- statistics.
What it showed:
- **1.0 keeps its user's thread in a remote community `federation_pending` until the community announces it back**, and
clears the flag *before* answering that echo 400 (`Object is not remote`). Without the echo the thread stays pending,
so `GroupDistributor` sends the `Announce{Create}` to the author's own server on purpose.
- **Every bare `Announce{object}` is answered 400** (`Failed to parse object`: Lemmy dereferences it expecting an
activity), as Lemmy answers the compatibility `Announce(Page)` it sends itself. Both 400s show up as dead deliveries
in the statistics.
- **Votes travel only to the community**, which relays them as `Announce{Like}` and `Announce{Dislike}`. They are
dropped as `unsupported` until P7 (expected failures), as is a moderator's removal.
- Lemmy logs no refused activity at `warn`; the reason is in the 400's body, which our delivery does not keep. The
scenario's API notes: `sort` values are lowercase (`new`), private messages and mentions are in
`account/notification/list`, and `resolve_object` takes both `!community@host` and `@user@host`.
- 0.19 cannot join the pasture: its rustls trusts only its bundled roots, never Caddy's CA.
### PieFed 1.7.17 and Mbin 1.10.1
- **PieFed sends Lemmy's set plus:**