Vibefed kb-fediverse-actor-statuses
git clone https://github.com/reiver/vibefed
T=$(mktemp -d) && git clone --depth=1 https://github.com/reiver/vibefed "$T" && mkdir -p ~/.claude/skills && cp -r "$T/skills/kb-fediverse-actor-statuses" ~/.claude/skills/reiver-vibefed-kb-fediverse-actor-statuses && rm -rf "$T"
skills/kb-fediverse-actor-statuses/SKILL.mdFediverse Actor Statuses (FEP-82f6) — Complete Reference
Overview
FEP-82f6 (authored by Gregory Klyushnikov / grishka, received 2025-05-12, status DRAFT — finalization expected ~2026-03-18) describes an ActivityPub extension that allows actors to publish a short status text on their profile, with optional expiration, structured metadata attachment, and history.
The feature replicates a well-known UX pattern from centralized platforms: early Facebook "is..." statuses (2006–2009), VKontakte taglines, Discord custom statuses, and GitHub profile statuses. These are distinct from regular posts — they cannot be interacted with (no likes, replies, boosts), cannot contain media attachments, and have a short character limit.
The proposal originates from Smithereen, a federated social network modeled after VKontakte, which already implements this feature. The JSON-LD namespace
http://smithereen.software/ns# (prefix sm:) reflects this
origin.
1. The ActorStatus Object
ActorStatus extends the ActivityPub Object type. It represents a single
status update.
Required Fields
| Field | Description |
|---|---|
| Unique identifier for this status update |
| ID of the actor whose status this is |
| Plain text content of the status |
| Timestamp when the status was created |
Optional Fields
| Field | Description |
|---|---|
| Timestamp when the status expires. If present and in the past, implementations MUST NOT display this status |
| Structured metadata about what the actor is doing (e.g., a song, a video game). If present, MUST contain a fallback human-readable plain text representation |
Example
{ "type": "ActorStatus", "id": "https://example.social/users/1/statuses/1747286633", "attributedTo": "https://example.social/users/1", "content": "is desperately trying to bring the old internet back", "published": "2025-05-15T05:23:53.539Z", "@context": [ "https://www.w3.org/ns/activitystreams", { "sm": "http://smithereen.software/ns#", "ActorStatus": "sm:ActorStatus" } ] }
Example with Expiration
{ "type": "ActorStatus", "id": "https://example.social/users/1/statuses/1747300000", "attributedTo": "https://example.social/users/1", "content": "at a conference until Friday", "published": "2025-05-15T09:00:00.000Z", "endTime": "2025-05-16T18:00:00.000Z" }
Example with Attachment (Now-Playing)
{ "type": "ActorStatus", "id": "https://example.social/users/1/statuses/1747350000", "attributedTo": "https://example.social/users/1", "content": "Radiohead — Everything In Its Right Place", "published": "2025-05-15T12:00:00.000Z", "attachment": { "type": "Audio", "name": "Everything In Its Right Place", "attributedTo": "Radiohead" } }
The
content field MUST contain a human-readable fallback so servers that
don't understand the structured attachment can still display meaningful
text.
2. Actor Fields
Two OPTIONAL fields are added to actor objects:
status
statusThe current status update. Rules:
- MUST NOT be present if the last status has expired or been cleared
- MUST contain an inlined
object (not a reference/link)ActorStatus - When present, it is always current and non-expired — consumers can rely on this
{ "type": "Person", "id": "https://example.social/users/1", "name": "Alice", "status": { "type": "ActorStatus", "id": "https://example.social/users/1/statuses/1747286633", "attributedTo": "https://example.social/users/1", "content": "is desperately trying to bring the old internet back", "published": "2025-05-15T05:23:53.539Z" } }
statusHistory
statusHistoryA collection of all past status updates. Behavior:
- If present, implementations MAY provide a UI to view the actor's status history (similar to early Facebook's status timeline)
- If absent, implementations SHOULD NOT store past status updates and MUST NOT expose them in the UI
- The presence or absence of this collection signals to remote servers whether the actor supports status history
3. Activities
Create — Set a New Status
Send
Create{ActorStatus} to followers.
{ "type": "Create", "actor": "https://example.social/users/1", "object": { "type": "ActorStatus", "id": "https://example.social/users/1/statuses/1747286633", "attributedTo": "https://example.social/users/1", "content": "is desperately trying to bring the old internet back", "published": "2025-05-15T05:23:53.539Z" }, "to": "https://example.social/users/1/followers" }
Upon receiving:
- Update the actor's current status
- If the actor has
, add the new status to itstatusHistory - If the actor does NOT have
, the previous status is considered deleted (as ifstatusHistory
d)Delete
After sending, the
status field on the actor object MUST be updated.
An Update{Actor} MUST NOT be sent — the Create already implicitly
updates the status field on remote servers.
Remove — Clear Status from Profile
Send
Remove{ActorStatus} to followers.
{ "type": "Remove", "actor": "https://example.social/users/1", "object": "https://example.social/users/1/statuses/1747286633", "to": "https://example.social/users/1/followers" }
Upon receiving:
- If the
ID matches the actor's current status, clear itobject - If the actor has
, the status stays in historystatusHistory - The actor's
field becomes absentstatus
Delete — Completely Remove a Status
Send
Delete{ActorStatus} to followers.
{ "type": "Delete", "actor": "https://example.social/users/1", "object": "https://example.social/users/1/statuses/1747286633", "to": "https://example.social/users/1/followers" }
Upon receiving:
- Remove the status from
as well as clearing from profilestatusHistory - If the actor has no
, this is identical tostatusHistoryRemove
No Update Allowed
Once published, a status object cannot be
d. This is a
deliberate design decision — if the user wants a different status, they
create a new one.Update
No Interactions
Statuses cannot be interacted with. Implementations:
- SHOULD NOT send any activities (Like, Announce, etc.) referring to
statuses as their
from non-owner actorsobject - MUST either ignore such activities (return 2xx) or reject them (return 4xx)
4. Remove vs Delete Semantics
The spec makes a deliberate distinction:
| Activity | Profile | History | Use case |
|---|---|---|---|
| Cleared | Kept (if exists) | "I'm done with this status, but it's part of my history" |
| Cleared | Removed | "I want this status to no longer exist anywhere" |
(no history) | Cleared | N/A | Identical to Delete when is absent |
This mirrors the Facebook/VK pattern where statuses accumulate in a timeline. Users can either move past them (they become history) or delete them entirely.
5. JSON-LD Context
{ "@context": [ "https://www.w3.org/ns/activitystreams", { "sm": "http://smithereen.software/ns#", "ActorStatus": "sm:ActorStatus", "status": { "@type": "@id", "@id": "sm:status" }, "statusHistory": { "@type": "@id", "@id": "sm:statusHistory" } } ] }
The namespace
http://smithereen.software/ns# originates from the
Smithereen project. ActorStatus is equivalent to
http://smithereen.software/ns#ActorStatus — they are the same type
expressed with and without the namespace prefix.
6. Character Limit
- Implementations MUST support statuses of up to 100 characters or emoji
- Implementations MAY allow longer statuses, but they MAY be truncated on the receiving side depending on display and storage constraints
- RECOMMENDED: apply a 100-character limit in the user-facing text input, but be more permissive when processing status updates from other servers
7. Comparison with Centralized Platform Statuses
| Platform | Feature | Interactable? | Media? | Limit | History? |
|---|---|---|---|---|---|
| Early Facebook (2006–2009) | "is..." status | No | No | Very short | Yes |
| VKontakte | Status/tagline | No | No | Short | Yes |
| Discord | Custom status | No | Emoji only | 128 chars | No |
| GitHub | Custom status | No | Emoji only | Short | No |
| Slack | Custom status | No | Emoji only | 100 chars | No |
| FEP-82f6 | ActorStatus | No | Attachment metadata | 100+ chars | Optional |
No existing Fediverse platform has a standardized actor status feature. Smithereen is the only known implementation.
8. Design Philosophy
The author's design philosophy is distinctive and worth understanding for implementers:
One FEP = One UX Pattern
"This FEP serves one particular UX use case and only that. Nothing less, nothing more." The proposal does not try to be a general-purpose mechanism. It captures a specific, well-understood UI pattern.
Clean Compatibility Break
"A clean compatibility break with all preexisting software is an explicit goal." Rather than reusing existing mechanisms (like the
featured
collection) for partial backward compatibility, the proposal introduces
a new type that servers either understand or don't. This avoids ambiguous
degradation where a status might misleadingly appear as a pinned post.
UI-to-Protocol Mapping
"I simply translated the actions that the user can take in the UI to AP activities, one-to-one." Each user action maps directly to one Activity type:
| User action | Activity |
|---|---|
| Set status | |
| Clear status | |
| Delete status | |
No side effects, no indirect mechanisms (like using
Update with
endTime changes to clear a status).
9. Why Certain Alternatives Were Rejected
Why Not Use the featured
Collection?
featuredsilverpill suggested placing
ActorStatus in featured for partial
compatibility. Rejected because:
- Mixing different object types in one collection causes database and UI complexity
- A clean break is preferred over a status misleadingly appearing as a pinned post
has different semantics (showcase content vs. current state)featured
Why No Update
Activity?
Updatesilverpill proposed
Update{ActorStatus} setting endTime to a past
date to clear statuses. Rejected because:
- It replaces an obvious action (
) with a non-obvious one (Remove
with a side effect)Update - It opens the door to restoring expired statuses by resetting
to a future dateendTime - The
activity directly and transparently maps to the user action of clearing a statusRemove
Why No Interactions?
SorteKanin asked why statuses can't have likes, replies, images, or long text. Rejected because adding these features would make statuses overlap with regular posts (
Note objects) and lose the distinct UX identity that
makes them useful.
10. Implementation Guidance
Sending a Status Update
- Create an
object withActorStatus
,id
,attributedTo
,content
, and optionallypublished
and/orendTimeattachment - Send
to the actor's followersCreate{ActorStatus} - Update the actor's
field with the new statusstatus - Do NOT send
— theUpdate{Actor}
implicitly updates remote copiesCreate
Receiving a Status Update
- On
: update the actor's displayed status. If you track history and the actor hasCreate{ActorStatus}
, add to it. If nostatusHistory
, discard the previous status.statusHistory - On
: if the object ID matches the current status, clear it. Keep in history if applicable.Remove{ActorStatus} - On
: clear from profile AND remove from history.Delete{ActorStatus} - Ignore any other activities (Like, Announce, etc.) targeting statuses.
Displaying Statuses
- Show on the actor's profile page
- Optionally show next to the actor's name in feeds, comments, etc.
- If
is present and in the past, do NOT displayendTime - If
is available, optionally provide a UI to browse itstatusHistory
Handling the Attachment Field
The
attachment field carries structured metadata (e.g., a song, a game).
If you can render it richly (album art, game icon), do so. If not, the
content field already contains a plain text fallback — just display that.
11. Known Issues and Considerations
- Single implementation: Smithereen is the only known implementation.
The
namespace reflects this single-origin status. Adoption by other platforms would validate the design.sm: - No standard attachment types: The spec does not define specific attachment schemas for now-playing, gaming, etc. Implementers must define their own structured formats or wait for community conventions.
- Expiration timing: Implementations must actively check
and stop displaying expired statuses. There is no push notification for expiration — it's poll-based on theendTime
value.endTime - No
: If a user makes a typo in their status, they must create a new one rather than editing. This is intentional but may surprise users accustomed to editing posts.Update - History privacy: The
collection is visible to "anyone who can see the actor itself." There is no mechanism for private or followers-only status history.statusHistory