Commit Graph
4 Commits
Author SHA1 Message Date
thepraandClaude Opus 5.5 f6dbf71964 Everything on, phase 2 completed: SecureMode on in production, checked by the deploy
Build / Build (push) Successful in 5m5s
Deploy / privapub.thepra.dev (push) Failing after 4m39s
Owner decision 2026-10-04: SecureMode on once the pasture passes with it.

- Both clean pasture passes were run over all six peers:
  - normally: 246 passed, 0 failed;
  - with Federation__SecureMode=true: every federation check passed. The only failures were four checks expecting an
    unsigned GET to get 404 or 410 where SecureMode answers 401. Those checks now go through `unserved` and
    `gone_unsigned` (lib/interop.sh), which expect 401 when SecureMode is on.
- Circle posts now reach their member on GoToSocial and Mastodon, and survive Mastodon's signed refetch, as does a
  followers-only post. The GoToSocial expected failure is gone.
- appsettings.Production.json turns SecureMode on.
- The deploy now checks that an unsigned GET of @thepra answers 401 and that a browser is redirected. It reads
  @thepra's discoverability through the Mastodon API, since the actor is no longer readable unsigned.
- docs/INTEROP.md (Mastodon, GoToSocial), CLAUDE.md and ROADMAP updated.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01ELjqpznMFMNrJoJUj6K5p2
2026-10-04 03:34:48 +02:00
thepraandClaude Opus 5.5 fcd35f5043 Everything on, phase 2: circle posts for everyone, private posts on signed refetch, browsers past SecureMode
Circles (owner decision 2026-10-04: fix them for compatibility):
- Mastodon 4.7 and GoToSocial drop a post that names none of their accounts, and a circle post named only the circle
  and its /flock. OutboxPublisher.Publish now sends each member a copy that also names that member in `cc`, on the
  activity and on the object, and names no other member. The Create, every Update (edit, poll, quote approval, policy,
  through the new PublishUpdate) and the Delete (StatusService.Remove now uses Publish) all go that way.
- UpdateOf renders with the post's group, so an Update keeps a circle post's `audience` and a community post's `Page`
  and title.
- A reply to a circle post stays in the circle, whichever client wrote it.
- A circle post can no longer quote a post that needs permission: asking would show the circle post to its author.

Posts that are not public, on refetch (SignedFetchAuthorizer.MayRead):
- Followers-only, direct and circle posts are served to a signed request from someone they were for, or from the
  instance actor of a server where one of them lives. That is a follower or an addressed account, an addressed
  account, or a member. Everyone else still gets 404.
- Once deleted they answer those readers 410. Mastodon deletes its copy when a refetch answers 404.
- A circle refetch names the requesting member, or the members on the requesting server, as the delivered copy did.
- /grunts/create-{id} serves the same.
- /peasants/{name}/whispers/{id}, a DM's `context`, was never routed. It is now the conversation's posts, for its
  participants only.

SecureMode lets browsers through to the redirect to the public page, instead of answering them 401.

653 tests pass.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01ELjqpznMFMNrJoJUj6K5p2
2026-10-04 03:01:14 +02:00
thepraandClaude Opus 5.5 d4e9acdb79 T10: what GoToSocial had not yet been asked, and quick edits that were lost
The GoToSocial scenario gains 17 checks:
- alice's reply threads under gtsuser's post;
- gtsuser's edit arrives with edited_at and two history entries;
- unlike and unboost both ways;
- images with alt text both ways, theirs through our proxy;
- gtsuser follows a PrivaPub community and its announce brings the post;
- gtsuser's request to join a circle waits for the owner and is approved, and the
  circle post is never served unsigned;
- a locked persona holds gtsuser's follow, rejects it, then authorizes it;
- the deploy's Mastodon smoke check passes, signed in.

54 checks passed, three runs in a row. The circle post reaching gtsuser is an expected
failure: GoToSocial keeps no post addressed only to a collection it does not know.

It found a bug. An edit made within the second the post was published carries GoToSocial's
whole-second updated == published, and IsEdit wanted strictly newer, so the edit was taken
as a refresh and lost. A first edit now also counts when it is no older and the text,
warning or title actually changed. A bare refresh still never makes a revision.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01ELjqpznMFMNrJoJUj6K5p2
2026-10-03 12:54:01 +02:00
thepraandClaude Opus 5.5 e0f2eb7da7 T11: Mastodon 4.7.3 in the pasture
peers/mastodon.sh runs Mastodon's web and sidekiq containers on a shared Postgres and Redis
(peers/shared.sh). They trust Caddy's CA through SSL_CERT_FILE and reach private addresses
through ALLOWED_PRIVATE_ADDRESSES. Its users and tokens come from tootctl and rails runner.

scenarios/mastodon.sh adds 49 checks, as listed in docs/INTEROP.md: follows, posts,
replies, likes and boosts with undos, DMs, polls, FEP-044f quotes both ways, media through
the proxy, edits, deletes, locked follows, a circle request, reports, blocks and statistics.
Two are expected failures:
- inbound Block (P7);
- circle posts. Mastodon 4.7 loses the recipient of deliveries to its numeric
  /ap/users/<id>/inbox and then drops a post that names no local account. The fix on our
  side changes what a circle reveals, so it waits for the owner.

GoToSocial and Mastodon together: 86 passed, 0 failed.

The pasture now copies Caddy's root certificate reliably, readable by the peers, and
rebuilds the bundle each time. The CA directory is mounted shared (:z), because a private
:Z label locks out every container but the last. pfetch reaches PrivaPub's own https URIs
through Caddy. PRIVAPUB_ENV passes settings to PrivaPub, which scenarios/crawler.sh uses to
check the opt-in crawler against Mastodon: it visits, describes and reads the peers list.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01ELjqpznMFMNrJoJUj6K5p2
2026-10-03 12:30:05 +02:00