~ knotless Search/
↑↓ move↵ open⇧↵ all results

grain.social/grain

photography-focused photo sharing platform

grain.social
1 collaborator
0
2

server: A login with no Bluesky profile makes a bare grain profile

Merged
Merged chadtmiller.com asked to merge into feature/rust from grain.social/grain:login/bare-profile

What changes

A web login always leaves the account with a grain profile. When an account has neither a grain profile nor a Bluesky profile, the login's seeding (crates/grain-serve/src/login/profile.rs) now makes a bare social.grain.actor.profile at self, holding only its createdAt. Before, it made nothing.

The other cases are unchanged:

  • A named grain profile is left as it is.
  • With a Bluesky profile, the grain profile is seeded from it.
  • An unnamed grain profile with no Bluesky profile is left as it is (Seeded::NoBluesky).

Why

grain-serve starts tracking an account only once it writes a grain profile or a group declaration, and drops the rest of an untracked account's records. The login seeding copied old grain's on-login hook, which writes nothing when there's no app.bsky.actor.profile. So an account with no Bluesky profile logs in, gets no grain profile, and everything it posts passes by.

That's hellsangel81.selfhosted.social (did:plc:5eswzrytpngfgviqyyfixtex). Its repo holds one story and nothing else. grain.social shows the story, because hatk indexes any grain record. next.grain.social has no row for the account at all.

The other fix considered was to track an account on any social.grain.* write. We kept the profile as what makes an account tracked, and made sure every login writes one. The iOS and Android apps sign in at the account's PDS, so grain-serve never sees their logins; they get the same rule in pulls of their own.

How it was checked

a_login_seeds_a_grain_profile_from_bluesky now covers the case where an account has neither profile. The login makes a bare profile, holding only $type and a valid createdAt. The account is then tracked, and seeding again returns NoBluesky and leaves the profile as it is. Built and tested on CI.

Shortcomings

An account that already slipped through, like hellsangel81, is fixed only by its next web login, or by the app once the app pulls land. Until then next doesn't show it, while grain.social does.

🤖 Generated with Claude Code

chadtmiller.com added 1 commit
Approved

This makes a login with neither a grain profile nor a Bluesky profile create a bare grain profile. The bare profile holds $type and createdAt, built with from_bluesky(&json!({}), None). The other cases keep their behavior: a named profile returns Named, an unnamed profile with no Bluesky profile returns NoBluesky, and a Bluesky profile seeds as before. The test covers the new case, including that tracks becomes true and that a second seeding is a no-op. I did not read the CI results. One nit: the module doc comment now has an overlong line, grain profile and no Bluesky profile is left as it is. Both are read from…, which is worth rewrapping.

Approved

The pull makes a login with neither a grain profile nor a Bluesky profile create a bare grain profile. The only change since my last review is a formatting commit on the test. The logic is as I read it before: (None, Some(_)) returns NoBluesky, (None, None) makes a bare profile, and a Bluesky profile seeds as before. The test covers the new case, including that the account becomes tracked and that seeding again changes nothing. The CI checks for this commit are still queued, so I haven't seen results. The doc-comment line I flagged last round, "grain profile and no Bluesky profile … Both are read from the account's PDS, which has", is still overlong at crates/grain-serve/src/login/profile.rs:14. Rewrap it if you want, but it shouldn't block the merge.

Merged as 93e66cb
Part of a stack of 2
  1. server: A login with no Bluesky profile makes a bare grain profile Landed as 93e66cb
  2. main