ActivityPub + WebFinger: what v1 needs
Normative references
- ActivityPub (W3C Recommendation): https://www.w3.org/TR/activitypub/
- WebFinger (RFC 7033): https://datatracker.ietf.org/doc/html/rfc7033
- JSON Resource Descriptor (RFC 6415): https://datatracker.ietf.org/doc/html/rfc6415
- Mastodon implementation requirements (practical interop): https://docs.joinmastodon.org/spec/activitypub/
Required server endpoints
GET /.well-known/webfinger?resource=acct:<name>@<domain>GET /users/:name(actor document)POST /users/:name/inboxGET /users/:name/outbox
Required response shapes
- WebFinger returns
application/jrd+jsonwith: subject: "acct:<name>@<domain>"a
linksentry whererelisself,typeisapplication/activity+json, andhrefpoints to actor URL.Actor JSON includes stable IDs and key fields used by Mastodon interop:
id,type: "Person",preferredUsername,inbox,outbox,publicKey.Inbox accepts ActivityStreams activities at minimum for v1:
Createwith embeddedNoteobjects.Outbox exposes authored activities (newest first), with stable IDs and timestamps.
Delivery and security expectations
- Serve ActivityPub resources as ActivityStreams JSON (
application/activity+json) and support standardAcceptnegotiation. - Verify HTTP Signatures for signed inbox deliveries and include signatures for outbound federation requests (Mastodon requires this in practice).
- Keep object IDs globally unique and stable URLs.
- Deduplicate by activity/object ID to avoid replay loops.
Implementation checklist for this repo
- Add service objects:
WebFingerServiceActivityPubActorServiceActivityPubInboxServiceActivityPubOutboxServiceHttpSignatureServiceKeep Kemal routes thin and JSON-only for API paths.
Add request/response models for:
WebFinger JRD documents
Actor documents
Create/NoteactivitiesAdd tests for:
WebFinger subject/link correctness
actor field completeness
signed inbox acceptance and invalid-signature rejection
duplicate activity rejection
Meshtastic: what v1 needs
Normative references
- Meshtastic protocol buffers (source of wire constraints): https://github.com/meshtastic/protobufs
mesh.optionspayload limits (Data.payload): https://github.com/meshtastic/protobufs/blob/master/meshtastic/mesh.options- Meshtastic MQTT integration (gateway bridge behavior): https://meshtastic.org/docs/software/integrations/mqtt/
Payload/metadata constraints
Data.payloadmax length is defined as233bytes inmesh.options.- Keep canonical message text short and compact metadata small to remain relay-friendly.
- Use deterministic dedupe keys and message IDs to suppress rebroadcast loops.
- Keep relay hop metadata bounded (
relay_hopsalready constrained in code).
Bridge/relay behavior for v1
- Treat the Meshtastic envelope as canonical for peer transport.
- On inbound mesh message:
- parse envelope
- validate limits
- dedupe by message ID and dedupe key
store once
On outbound relay:
enqueue with retry/backoff
mark delivered/failed explicitly
avoid auto-expanding payload fields that threaten mesh limits
For a public web node with mesh bridge:
map mesh channel traffic to public timeline policy rules
never assume all mesh messages are public by default
Implementation checklist for this repo
- Add Meshtastic adapter boundary object around protobuf encode/decode.
- Add serialization tests proving encoded payloads remain within configured byte budget.
- Add end-to-end tests for dedupe and retry transitions between inbox and outbound queue.