Docs & Rules

TheZwiss/backspaceGitHubLast refreshed Oct 3, 2026

This is a public, read-only report. Striff reads this repository's docs, turns each sentence that makes a claim about the code into a rule, and checks the rule against the code on the default branch. How this works

maind42ec02listed 7h ago

Is this yours? Install to manage it

Once installed, Striff checks every pull request.

77
77
1
1
1
76
14
6
2
6
4
14
1
12
7
6
4
44 docs, listed Oct 3
TheZwiss/backspaceOpen repository

TheZwiss/backspace — documented rules

77 of 77 rules, printed October 3, 2026.

The sentence in your docs
Read Oct 2
**GET / PATCH /api/settings/instance** (routes/settings.ts, admin, the pair GeneralPanel uses) gain supportCardEnabled: the shared type InstanceAdminSettings gains the field, rowToAdminSettings maps it, and the PATCH accepts a boolean and otherwise answers sendError(reply, 400, 'field_not_boolean', { field: 'supportCardEnabled' }), the existing code the route uses for its other boolean fields.
InstanceAdminSettings has a supportCardEnabled field
HoldsPR #378 · Oct 2
Read Oct 2
429 with the shared error body ({ error, code: 'rate_limited', statusCode: 429 }, see [localization.md](localization.md)) plus retryAfter in whole seconds, and the plugin's own Retry-After header.
ErrorBody has error
Holds
Read Oct 2
429 with the shared error body ({ error, code: 'rate_limited', statusCode: 429 }, see [localization.md](localization.md)) plus retryAfter in whole seconds, and the plugin's own Retry-After header.
ErrorBody has code
Holds
Read Oct 2
429 with the shared error body ({ error, code: 'rate_limited', statusCode: 429 }, see [localization.md](localization.md)) plus retryAfter in whole seconds, and the plugin's own Retry-After header.
ErrorBody has statusCode
Holds
Read Oct 2
Space.directoryListed is carried on every space response and in the WebSocket ready payload.
Space has directoryListed
HoldsPR #378 · Oct 2
Read Oct 2
The target is named one of two ways (SendFriendRequest in packages/shared/src/types.ts):
SendFriendRequest is in packages/shared/src
Holds
Read Oct 2
instanceId (InstanceInfoResponse.instanceId, string) is this instance's persistent **epoch** — the incarnation UUID minted once by ensureDefaults and stable across restarts (see database.md → Instance Settings).
InstanceInfoResponse has instanceId
Holds
Read Oct 2
InstanceStreamingLimits.directoryEnabled is also carried on GET /settings/streaming, read-only there, so a non-admin's space settings can tell whether the instance allows listing.
InstanceStreamingLimits has directoryEnabled
Holds
Read Oct 2
TelemetryStatus is { enabled: boolean | null, id: string | null, lastDay: string | null, lastError: { day, status } | null, askDue: boolean }, where enabled: null means the instance was never asked and askDue says whether the admin should see the ask now (always while never answered, never after a yes, and after a no again from the next minor release on; telemetry.md §7).
TelemetryStatus has enabled
Holds
Read Oct 2
TelemetryStatus is { enabled: boolean | null, id: string | null, lastDay: string | null, lastError: { day, status } | null, askDue: boolean }, where enabled: null means the instance was never asked and askDue says whether the admin should see the ask now (always while never answered, never after a yes, and after a no again from the next minor release on; telemetry.md §7).
TelemetryStatus has id
Holds
Read Oct 2
TelemetryStatus is { enabled: boolean | null, id: string | null, lastDay: string | null, lastError: { day, status } | null, askDue: boolean }, where enabled: null means the instance was never asked and askDue says whether the admin should see the ask now (always while never answered, never after a yes, and after a no again from the next minor release on; telemetry.md §7).
TelemetryStatus has lastDay
Holds
Read Oct 2
TelemetryStatus is { enabled: boolean | null, id: string | null, lastDay: string | null, lastError: { day, status } | null, askDue: boolean }, where enabled: null means the instance was never asked and askDue says whether the admin should see the ask now (always while never answered, never after a yes, and after a no again from the next minor release on; telemetry.md §7).
TelemetryStatus has lastError
Holds
Read Oct 2
TelemetryStatus is { enabled: boolean | null, id: string | null, lastDay: string | null, lastError: { day, status } | null, askDue: boolean }, where enabled: null means the instance was never asked and askDue says whether the admin should see the ask now (always while never answered, never after a yes, and after a no again from the next minor release on; telemetry.md §7).
TelemetryStatus has askDue
Holds
Read Oct 2
**FederationRelayRequest.sourceInstanceId** stamps the sender's current epoch on every relay;
FederationRelayRequest has sourceInstanceId
HoldsPR #378 · Oct 2
Read Oct 2
**needsAttentionReason** ('auth_failures' | 'peer_reset_detected' | 'repeer_incomplete' | null) is now included on each GET /federation/peers peer object so the client can raise the persistent Reset-cleanup banner only for reset-detected peers and surface an "incomplete Re-peer" warning for repeer_incomplete.
FederationPeer has needsAttentionReason
HoldsPR #378 · Oct 2
Read Oct 2
**State.** A conversation is { key, copies: Map<origin, DmCopy>, pinnedOrigin }, a copy is { origin, channel, keySource }, at most one copy per key and origin.
DmConversation has key
Holds
Read Oct 2
**State.** A conversation is { key, copies: Map<origin, DmCopy>, pinnedOrigin }, a copy is { origin, channel, keySource }, at most one copy per key and origin.
DmConversation has copies
Holds
Read Oct 2
**State.** A conversation is { key, copies: Map<origin, DmCopy>, pinnedOrigin }, a copy is { origin, channel, keySource }, at most one copy per key and origin.
DmConversation has pinnedOrigin
Holds
Read Oct 2
**State.** A conversation is { key, copies: Map<origin, DmCopy>, pinnedOrigin }, a copy is { origin, channel, keySource }, at most one copy per key and origin.
DmCopy has origin, channel and keySource
Holds
Read Oct 2
RemoteLoginRequiredError is an HttpError carrying a registered code (federation_different_password, 409, or federated_registration_closed, 403, by reason), minted by the client rather than by a route, so describeError says it in the user's language anywhere it does surface as a message.
RemoteLoginRequiredError extends HttpError
Holds
Read Oct 2
The live ConnectedInstance.error field is a separate, unrendered string for the console and stays English.
ConnectedInstance has an error field
Holds
Read Oct 2
A settings section carries a count (SettingsSection.badgeCount) when the number matters, or a dot (SettingsSection.badgeDot) when only the existence does.
SettingsSection has badgeCount
Holds
Read Oct 2
A settings section carries a count (SettingsSection.badgeCount) when the number matters, or a dot (SettingsSection.badgeDot) when only the existence does.
SettingsSection has badgeDot
Holds
Read Oct 2
inRecoveryMode (private to the store, guards loadFile(recovery.html) re-entry / loop prevention) and updateConfirmed (local to main.ts:initAutoUpdater, controls whether updater errors get pushed to the renderer).
RecoveryStateStore has inRecoveryMode
Holds
Read Oct 2
keybinds: KeybindConfig[] — current bindings synced from renderer
KeybindManager has keybinds
Holds
Read Oct 2
pressedKeys: Set<number> — currently held keys (djb2 hashes)
KeybindManager has pressedKeys
Holds
Read Oct 2
activeActions: Set<string> — actions whose keybind is currently satisfied
KeybindManager has activeActions
Holds
Read Oct 2
window: BrowserWindow | null — target for IPC sends
KeybindManager has window
Holds
Read Oct 2
started: boolean — whether uIOhook is running
KeybindManager has started
Holds
Read Oct 2
Space carries directoryListed everywhere a space is serialised: the spaces routes, the explore routes, and the WebSocket ready payload.
Space has directoryListed
Holds
Read Oct 2
GET /api/settings/streaming (InstanceStreamingLimits, readable by any signed-in user) carries directoryEnabled too, so the space settings panel of a non-admin can tell whether the instance allows listing.
InstanceStreamingLimits has directoryEnabled
Holds
Read Oct 2
Each entry is { origin, instanceName, federatedRegistrationOpen, id, name, description, icon, banner, avatarColor, visibility, memberCount, createdAt }, the DirectoryEntry shape in packages/shared.
DirectoryEntry is in packages/shared
Holds
Read Oct 2
directoryBrowseEnabled lives on InstanceAdminSettings, behind GET /api/settings/instance, which is admin-only, and a member surface must not carry an admin-only read.
InstanceAdminSettings has directoryBrowseEnabled
Holds
Read Oct 2
**Naming a message across instances.** Each instance holds its own copy of a federated message under its own local id, so a relay event that points at another message names it with FederationMessageRef { messageId, messageHomeInstance }: the message's id on the instance that created it, and that instance's origin.
FederationMessageRef has messageId
Holds
Read Oct 2
**Naming a message across instances.** Each instance holds its own copy of a federated message under its own local id, so a relay event that points at another message names it with FederationMessageRef { messageId, messageHomeInstance }: the message's id on the instance that created it, and that instance's origin.
FederationMessageRef has messageHomeInstance
Holds
Read Oct 2
Replies (message.replyTo, filled by dmReplyRefForRelay in queueDmRelay and in the sync endpoint) and reactions (reaction.messageId + reaction.messageHomeInstance, filled by the WS reaction handlers and in the sync endpoint) both use it.
Reaction has messageId
Holds
Read Oct 2
Every entry carries id, federatedId, ownerId, ownerHomeUserId, ownerHomeInstance, createdAt, name, icon, metadataUpdatedAt, members and lastMessage, with null (or 0 for metadataUpdatedAt) where the channel has no value.
DmChannel has id
Holds
Read Oct 2
Every entry carries id, federatedId, ownerId, ownerHomeUserId, ownerHomeInstance, createdAt, name, icon, metadataUpdatedAt, members and lastMessage, with null (or 0 for metadataUpdatedAt) where the channel has no value.
DmChannel has federatedId
Holds
Read Oct 2
Every entry carries id, federatedId, ownerId, ownerHomeUserId, ownerHomeInstance, createdAt, name, icon, metadataUpdatedAt, members and lastMessage, with null (or 0 for metadataUpdatedAt) where the channel has no value.
DmChannel has ownerId
Holds
Read Oct 2
Every entry carries id, federatedId, ownerId, ownerHomeUserId, ownerHomeInstance, createdAt, name, icon, metadataUpdatedAt, members and lastMessage, with null (or 0 for metadataUpdatedAt) where the channel has no value.
DmChannel has ownerHomeUserId
Holds
Read Oct 2
Every entry carries id, federatedId, ownerId, ownerHomeUserId, ownerHomeInstance, createdAt, name, icon, metadataUpdatedAt, members and lastMessage, with null (or 0 for metadataUpdatedAt) where the channel has no value.
DmChannel has ownerHomeInstance
Holds
Read Oct 2
Every entry carries id, federatedId, ownerId, ownerHomeUserId, ownerHomeInstance, createdAt, name, icon, metadataUpdatedAt, members and lastMessage, with null (or 0 for metadataUpdatedAt) where the channel has no value.
DmChannel has createdAt
Holds
Read Oct 2
Every entry carries id, federatedId, ownerId, ownerHomeUserId, ownerHomeInstance, createdAt, name, icon, metadataUpdatedAt, members and lastMessage, with null (or 0 for metadataUpdatedAt) where the channel has no value.
DmChannel has name
Holds
Read Oct 2
Every entry carries id, federatedId, ownerId, ownerHomeUserId, ownerHomeInstance, createdAt, name, icon, metadataUpdatedAt, members and lastMessage, with null (or 0 for metadataUpdatedAt) where the channel has no value.
DmChannel has icon
Holds
Read Oct 2
Every entry carries id, federatedId, ownerId, ownerHomeUserId, ownerHomeInstance, createdAt, name, icon, metadataUpdatedAt, members and lastMessage, with null (or 0 for metadataUpdatedAt) where the channel has no value.
DmChannel has metadataUpdatedAt
Holds
Read Oct 2
Every entry carries id, federatedId, ownerId, ownerHomeUserId, ownerHomeInstance, createdAt, name, icon, metadataUpdatedAt, members and lastMessage, with null (or 0 for metadataUpdatedAt) where the channel has no value.
DmChannel has members
Holds
Read Oct 2
Every entry carries id, federatedId, ownerId, ownerHomeUserId, ownerHomeInstance, createdAt, name, icon, metadataUpdatedAt, members and lastMessage, with null (or 0 for metadataUpdatedAt) where the channel has no value.
DmChannel has lastMessage
Holds
Read Oct 2
On the client every 429 throws RateLimitError, an HttpError with status 429, the body's own code when the route sends one and rate_limited otherwise, plus retryAfter, so describeError localizes it like any other server error and the auth pages keep their countdown.
RateLimitError extends HttpError
Holds
Read Oct 2
**MessageWithUser** extends Message with: user: User, attachments: Attachment[], embeds: Embed[], reactions: Reaction[], replyTo?: MessageWithUser | null
MessageWithUser extends Message
Holds
Read Oct 2
**MessageWithUser** extends Message with: user: User, attachments: Attachment[], embeds: Embed[], reactions: Reaction[], replyTo?: MessageWithUser | null
MessageWithUser has user
Holds
Read Oct 2
**MessageWithUser** extends Message with: user: User, attachments: Attachment[], embeds: Embed[], reactions: Reaction[], replyTo?: MessageWithUser | null
MessageWithUser has attachments
Holds
Read Oct 2
**MessageWithUser** extends Message with: user: User, attachments: Attachment[], embeds: Embed[], reactions: Reaction[], replyTo?: MessageWithUser | null
MessageWithUser has embeds
Holds
Read Oct 2
**MessageWithUser** extends Message with: user: User, attachments: Attachment[], embeds: Embed[], reactions: Reaction[], replyTo?: MessageWithUser | null
MessageWithUser has reactions
Holds
Read Oct 2
**MessageWithUser** extends Message with: user: User, attachments: Attachment[], embeds: Embed[], reactions: Reaction[], replyTo?: MessageWithUser | null
MessageWithUser has replyTo
Holds
Read Oct 2
**DmMessageWithUser** extends DmMessage with: user: User, attachments: Attachment[], embeds: Embed[], reactions: Reaction[], replyTo?: DmMessageWithUser | null
DmMessageWithUser extends DmMessage
Holds
Read Oct 2
**DmMessageWithUser** extends DmMessage with: user: User, attachments: Attachment[], embeds: Embed[], reactions: Reaction[], replyTo?: DmMessageWithUser | null
DmMessageWithUser has user
Holds
Read Oct 2
**DmMessageWithUser** extends DmMessage with: user: User, attachments: Attachment[], embeds: Embed[], reactions: Reaction[], replyTo?: DmMessageWithUser | null
DmMessageWithUser has attachments
Holds
Read Oct 2
**DmMessageWithUser** extends DmMessage with: user: User, attachments: Attachment[], embeds: Embed[], reactions: Reaction[], replyTo?: DmMessageWithUser | null
DmMessageWithUser has embeds
Holds
Read Oct 2
**DmMessageWithUser** extends DmMessage with: user: User, attachments: Attachment[], embeds: Embed[], reactions: Reaction[], replyTo?: DmMessageWithUser | null
DmMessageWithUser has reactions
Holds
Read Oct 2
**DmMessageWithUser** extends DmMessage with: user: User, attachments: Attachment[], embeds: Embed[], reactions: Reaction[], replyTo?: DmMessageWithUser | null
DmMessageWithUser has replyTo
Holds
Read Oct 2
All friend events use the friendship field of FederationRelayEvent:
FederationRelayEvent has a friendship field
Holds
Read Oct 2
Profile snapshots (FederationRelayProfileSnapshot) carry { username, displayName, avatar, avatarColor, banner, bio } for hydrating replicated user stubs on the receiving instance.
FederationRelayProfileSnapshot has username
Holds
Read Oct 2
Profile snapshots (FederationRelayProfileSnapshot) carry { username, displayName, avatar, avatarColor, banner, bio } for hydrating replicated user stubs on the receiving instance.
FederationRelayProfileSnapshot has displayName
Holds
Read Oct 2
Profile snapshots (FederationRelayProfileSnapshot) carry { username, displayName, avatar, avatarColor, banner, bio } for hydrating replicated user stubs on the receiving instance.
FederationRelayProfileSnapshot has avatar
Holds
Read Oct 2
Profile snapshots (FederationRelayProfileSnapshot) carry { username, displayName, avatar, avatarColor, banner, bio } for hydrating replicated user stubs on the receiving instance.
FederationRelayProfileSnapshot has avatarColor
Holds
Read Oct 2
Profile snapshots (FederationRelayProfileSnapshot) carry { username, displayName, avatar, avatarColor, banner, bio } for hydrating replicated user stubs on the receiving instance.
FederationRelayProfileSnapshot has banner
Holds
Read Oct 2
Profile snapshots (FederationRelayProfileSnapshot) carry { username, displayName, avatar, avatarColor, banner, bio } for hydrating replicated user stubs on the receiving instance.
FederationRelayProfileSnapshot has bio
Holds
Read Oct 2
Field name, Type string, Required yes, Validation trimmed, 1-100 chars
CreateSpaceRequest has a name field
Holds
Read Oct 2
Field icon, Type string, Required no, Validation Upload filename
CreateSpaceRequest has an icon field
Holds
Read Oct 2
Field banner, Type string, Required no, Validation Upload filename
CreateSpaceRequest has a banner field
Holds
Read Oct 2
Field avatarColor, Type AvatarColor, Required no, Validation Must be in AVATAR_COLORS random if omitted
CreateSpaceRequest has an avatarColor field
Holds
Read Oct 2
Field visibility, Type SpaceVisibility, Required no, Validation 'public' / 'request' / 'private' defaults to 'private'
CreateSpaceRequest has a visibility field
Holds
Read Oct 2
Field description, Type string, Required no, Validation trimmed, max 200 chars
CreateSpaceRequest has a description field
Holds
Read Oct 2
AudioManager.releaseInputStream() closes that gap: it disconnects inputSource, detaches each capture track's onended handler and .stop()s it, nulls currentStream, resets currentInputDeviceId to 'default', and bumps streamGeneration so the next join re-acquires instead of short-circuiting.
AudioManager has a releaseInputStream method
Holds
Read Oct 2
Input device changes flow through AudioManager.setInputDevice(deviceId) (serialized chain).
AudioManager has a setInputDevice method
Holds
Read Oct 2
When inputDeviceId === 'default' and a stream is active, AudioInputSection shows a Currently using: <label> subline by reading AudioManager.getCurrentInputDeviceId() and looking up the label in inputLabels.
AudioManager has a getCurrentInputDeviceId method
Holds
Read Oct 2
Mic device changes therefore unpublish/republish via AudioManager.getFreshTrack().
AudioManager has a getFreshTrack method
Holds
77 rules from 12 docs

See these where the change is. The browser extension puts a pull request's doc findings, and a diagram of what it changed, on the GitHub page itself, so the code and what your docs say about it are side by side.