CLAUDE.md describes the code after P1.1
Build / Build (push) Successful in 1m7s
Deploy / privapub.thepra.dev (push) Successful in 1m1s

The route table lists the themed names now in use, the repo map gains
Jobs, Ids, Moderation, Domain and Web, and the invariants add the job
queue, VisibilityPolicy and the rule for which remote posts are stored.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_012CzABvBkbcFqoHdmi8b9WB
This commit is contained in:
thepraandClaude Opus 5.5 committed 2026-10-01 11:28:37 +02:00
1 parent 1c78da34a9
commit 60bf21b019
1 file changed
+28 -23
+28 -23
View File
@@ -37,26 +37,19 @@ actor-scoped route gets a name in the same spirit, agreed with the owner, and a
| Thing | Route | | Thing | Route |
|---|---| |---|---|
| Actor | `/peasants/{name}` (`/users/{name}` 301-redirects here) | | Actor | `/peasants/{name}` (`/users/{name}` 301-redirects here; browsers are sent to `/@{name}`) |
| Inbox | `/peasants/{name}/mouth` | | Inbox | `/peasants/{name}/mouth` |
| Outbox | `/peasants/{name}/anus` | | Outbox | `/peasants/{name}/anus` (`?page=true[&max_id=]` for pages) |
| Shared inbox | `/human-centipede` (also `/peasants/{name}/human-centipede`) | | Shared inbox | `/human-centipede` (also `/peasants/{name}/human-centipede`) |
| Followers | `/peasants/{name}/groupies` |
| Following | `/peasants/{name}/stalking` |
| Notes | `/peasants/{name}/scribbles/{id}` |
| Activities | `/peasants/{name}/grunts/{id}` (`create-{postId}` resolves) |
| DM context | `/peasants/{name}/whispers/{id}` |
| Token refresh | `/clientapi/user/sniff/again` | | Token refresh | `/clientapi/user/sniff/again` |
These are agreed for the roadmap and replace the conventional names still in the code today: Agreed for later phases: `/gossip`, `/drool`, `/echoes` (replies, likes, shares), `/trophies` (featured), `/tattoos`
(featured tags), `/flock` and `/wardens` (group members and moderators).
| Thing | Route | Replaces |
|---|---|---|
| Followers | `/groupies` | `/followers` |
| Following | `/stalking` | `/following` |
| Notes | `/scribbles/{id}` | `/posts/{id}` |
| Activities | `/grunts/{id}` | `/activities/{id}` |
| Replies, likes, shares | `/gossip`, `/drool`, `/echoes` | |
| Featured | `/trophies` | |
| Featured tags | `/tattoos` | |
| Group members | `/flock` | |
| Group moderators | `/wardens` | |
| DM context | `/whispers/{id}` | |
Routes other software looks up by name stay conventional: Routes other software looks up by name stay conventional:
- `/.well-known/*` and `/nodeinfo/*`; - `/.well-known/*` and `/nodeinfo/*`;
@@ -75,6 +68,8 @@ PrivaPub/ ASP.NET Core Web API, net10.0
Group, Post (posts + DMs), Admin, Data Group, Post (posts + DMs), Admin, Data
Infrastructure/ Infrastructure/
Http/ FederationHttp + SafeHttpHandlerFactory + IpRangeGuard: the only way out Http/ FederationHttp + SafeHttpHandlerFactory + IpRangeGuard: the only way out
Jobs/ JobQueue (leases), JobWorker, Backoff, HostCircuitBreaker
Ids/ PrivacyIds (day-only ids for personas and groups, published-time ids for remote posts)
Data/ Indexes (created at start), EntityMaps.Warm, Migrations/_NNN_*.cs Data/ Indexes (created at start), EntityMaps.Warm, Migrations/_NNN_*.cs
Cli/ AdminCommands (`PrivaPub admin promote|demote <root>`) Cli/ AdminCommands (`PrivaPub admin promote|demote <root>`)
RateLimiting.cs accounts (per client address) and inbox (per sending origin) policies RateLimiting.cs accounts (per client address) and inbox (per sending origin) policies
@@ -83,13 +78,18 @@ PrivaPub/ ASP.NET Core Web API, net10.0
WellKnownController (webfinger, nodeinfo), UsersController (redirect) WellKnownController (webfinger, nodeinfo), UsersController (redirect)
Actors/ LocalActorService (LocalActor, Keys, ReservedName), RemoteActorService Actors/ LocalActorService (LocalActor, Keys, ReservedName), RemoteActorService
(authoritative fetch, key verification, WebFinger), ActorDocument (parser) (authoritative fetch, key verification, WebFinger), ActorDocument (parser)
Objects/ Origin (same-origin rules), ContentSanitizer (HtmlSanitizer, Mastodon allowlist) Objects/ Origin, ActivityJson, NoteParser, Addressing, ContentSanitizer
Moderation/ DomainBlocks (suspend / silence / reject media)
Signing/ HttpSignatures (draft-cavage sign/verify) Signing/ HttpSignatures (draft-cavage sign/verify)
Inbox/ InboxService (Follow/Undo/Create/Delete/Update) Inbox/ InboxReceiver (verify, queue, 202) → InboxProcessor (job) → Handlers/{Follow,Undo,Create,Update,Delete}
Outbox/ DeliveryService + DeliveryWorker Outbox/ DeliveryService (queues jobs) + DeliveryJobHandler
Rendering/ ActivityPubRenderer (JsonObject builders) Rendering/ ActivityPubRenderer (Mastodon @context, actors, notes, collections)
Domain/
Content/ ContentRenderer (Markdown or plain text → HTML with h-card mentions and hashtags)
Privacy/ VisibilityPolicy (IsPublic expression, CanSee)
Web/Pages/ Razor: /@{user}, /@{user}/{id} (public posts only, strict CSP, noindex)
Services/ RootUsersService, GroupUsersService, PostsService, AppConfigurationService, … Services/ RootUsersService, GroupUsersService, PostsService, AppConfigurationService, …
Models/ Mongo entities: User/, Group/, Post/, Federation/, AppConfiguration Models/ Mongo entities: User/, Group/, Post/, Federation/, Jobs/, AppConfiguration
StaticServices/ DbEntities (Find<T> accessors), AuthTokenManager (JWT), PasswordHasher StaticServices/ DbEntities (Find<T> accessors), AuthTokenManager (JWT), PasswordHasher
Data/InitDb.cs first-run seeding (languages) Data/InitDb.cs first-run seeding (languages)
PrivaPub.ClientModels/ DTOs + validation resources shared with clients PrivaPub.ClientModels/ DTOs + validation resources shared with clients
@@ -157,8 +157,13 @@ cd /var/www/privapub.thepra.dev && sudo -u www-data ASPNETCORE_ENVIRONMENT=Produ
8. **Circles never federate.** A circle's actor, collections, WebFinger and inbox answer 404, and its posts are 8. **Circles never federate.** A circle's actor, collections, WebFinger and inbox answer 404, and its posts are
`IsLocalOnly`. Only communities are Group actors. `IsLocalOnly`. Only communities are Group actors.
9. **A DM joins a conversation only by `DmGroup.ParticipantsKey`**, the exact set of its participants; a remote 9. **A DM joins a conversation only by `DmGroup.ParticipantsKey`**, the exact set of its participants; a remote
`context` decides nothing. `context` decides nothing. DMs are `Post`s with `Visibility = Direct` and a `ConversationId` (`DmPost` is legacy).
10. **Durable delivery:** activities go out through the delivery queue, never inline in a request. 10. **Nothing slow happens inside a request.** Deliveries and inbox processing are `Job`s (`Infrastructure/Jobs`):
leased, retried on Mastodon's curve, at most two per host, paused per host by `RemoteInstance`. The inbox answers
202 once it has verified and queued; a handler must be idempotent (unique `ObjectURI`, job `DedupeKey`).
11. **Every "may anyone see this" goes through `VisibilityPolicy.IsPublic`;** a persona-specific read uses `CanSee`.
12. **Remote content is stored only when someone here asked for it:** a local persona addressed or mentioned, a reply to
a local post, or a community the author follows. Followers-only is detected by the author's stored `followers` URL.
## Privacy invariants ## Privacy invariants