Pasture: Friendica joins, in the scenarios and the town
Friendica 2026.05 on the shared MySQL and Redis, with its worker daemon as a sidecar. friendica_settle repairs what its install leaves: the system user has no name, so the system account that signs its fetches is never made; the web container cannot see the sidecar's daemon, so a queued job waits for the five-minute cron unless the daemon is declared running; its log needs a file and debugging on. Accounts are saved through its API with locked=0 (a number: "true" reads as 0, unlocked), which makes them soapbox pages that take followers without following back, and each one's outbox is read once: a Follow that reaches an account Friendica has not cached makes it fetch the account from itself, signed, and checking that signature recursed for five minutes, holding PrivaPub's first follow past its timeout. scenarios/friendica.sh passes its 25 checks from a clean install: follows and unfollows, posts (a titled one with its title), comments, likes, Friendica's dislike as a downvote, boosts, edits (through its web editor: its Mastodon API never federates one) and deletes, both ways. The town gets a Friendica driver (HTTP Basic, its MySQL read through mysql_json, edits in the web editor, no bookmark on a reply) and specs/friendica-pair.json, which passes its 275 checks. On the way: - the checker knows Friendica's thread model: a non-public reply reaches an account only under posts it holds, and a Friendica account's non-public reply in a thread another server owns reaches nobody else there; - the seeder answers a follow request the target still holds whatever the follower's server says: Friendica reports a follow of someone already following its account as made at once (and shows that persona's followers-only posts while a locked persona still holds the request); - the selftest skips polls where a platform has none; the shared MySQL helpers move to peers/shared.sh. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01LsXgEaXee4GCU1hwYgPJXw
This commit is contained in:
1 parent
e485f7bd47
commit
a5d493a8c9
17 files changed
+513
-31
No files matched your search
@@ -534,6 +534,17 @@ tools/pasture/run.sh down # removes e
|
||||
its CA bundle (`wp-includes/certificates/ca-bundle.crt`) given Caddy's root, and WP-Cron run every five seconds by a
|
||||
sidecar (`DISABLE_WP_CRON`), since the plugin federates from it. Authors are actors; the REST API takes application
|
||||
passwords. `scenarios/wordpress.sh`, 17 checks.
|
||||
- **Friendica (2026.05):** the official image on the shared MySQL (database friendica) and Redis (db 7, for its cache,
|
||||
locks and sessions), installed by its autoinstall, with the image's worker daemon (`cron.sh`) as a sidecar sharing
|
||||
its files. `friendica_settle` repairs what the install leaves: it names the system user (uid 0), or Friendica never
|
||||
makes the system account that signs its fetches; it declares the daemon running (`worker_daemon_mode` in
|
||||
`key-value`), or the web container, which cannot see the sidecar's pid, never wakes it and everything waits for its
|
||||
five-minute cron; it makes the log file and turns logging on. `friendica_user` saves each account through the API
|
||||
with `locked=0` (a number: "true" reads as 0), which makes it a "soapbox" page that takes followers without asking and
|
||||
follows nobody back, and reads its outbox once: a Follow that reaches a user Friendica has not cached yet makes it
|
||||
fetch that user from itself, signed, and checking the signature recurses for about five minutes. Its API takes HTTP
|
||||
Basic (`nick:password`); an edit through it never federates, so the scenario edits in the web editor.
|
||||
`scenarios/friendica.sh`, 25 checks; the town's driver and `specs/friendica-pair.json`.
|
||||
- **SecureMode:** `PRIVAPUB_ENV="Federation__SecureMode=true" run.sh up …`, as production runs. A check of what an
|
||||
unsigned reader sees uses `unserved` and `gone_unsigned` (`lib/interop.sh`), which expect 401 when SecureMode is on and
|
||||
404 or 410 when it is off.
|
||||
@@ -560,12 +571,13 @@ tools/pasture/town.sh selftest [peer...] # each driver against its own server;
|
||||
tools/pasture/town.sh seed village # specs/village.json: 23 accounts on seven servers, about 11 minutes
|
||||
tools/pasture/town.sh check village # out/<run>/results.json; --deadline=0 re-sweeps an old run at once
|
||||
tools/pasture/town.sh report village # out/<run>/report.html, publishable (fake data, no tokens)
|
||||
tools/pasture/town.sh report village hollo-pair iceshrimp-pair pleroma-pair # several runs in one matrix
|
||||
tools/pasture/town.sh report village hollo-pair iceshrimp-pair pleroma-pair pixelfed-pair friendica-pair # one matrix
|
||||
tools/pasture/town.sh backlog --write # docs/INTEROP-BACKLOG.md
|
||||
```
|
||||
|
||||
- **Drivers** (`dialects/`): one class per platform on a dialect base (`mastodon_api`, `misskey_api`, `lemmy_api`,
|
||||
`privapub`). `stored()` reads the database (shared Postgres through `psql`, GoToSocial's sqlite copied out, Mongo);
|
||||
`privapub`). `stored()` reads the database (shared Postgres through `psql`, the shared MySQL through `mysql_json`,
|
||||
GoToSocial's sqlite copied out, Mongo);
|
||||
`seen()` asks the API as one account. A driver that cannot do something raises `Unsupported`, and the planner never
|
||||
asks for it (`gen.CAPS`).
|
||||
- **The plan** (`gen.py`) is a pure function of the spec and its seed; each run keeps its own `plan.json`, `ledger.jsonl`
|
||||
|
||||
Reference in new issue
Block a user