mirror of
https://github.com/fluxerapp/fluxer
synced 2026-10-17 04:55:42 +09:00
feat(threads): ship threads and the Plutonium page to everyone (#3277)
This commit is contained in:
1 parent
1515a8487f
commit
f8505d19f7
53 files changed
+296
-2008
No files matched your search
@@ -36,7 +36,6 @@ Missing settings use the defaults documented below. Invalid stored configuration
|
||||
| gateway_rollout | [Gateway rollout configuration](#gateway-rollout-configuration-object) object | Gateway admission and dispatch tuning |
|
||||
| push_relay | [push relay configuration](#push-relay-configuration-object) object | Operator consent to the Fluxer-run push relay |
|
||||
| domain_migration | [domain migration configuration](#domain-migration-configuration-object) object | Web domain migration rollout |
|
||||
| plutonium_page | [Plutonium page configuration](#plutonium-page-configuration-object) object | Plutonium page rollout |
|
||||
| captcha | [captcha configuration](#captcha-configuration-object) object | ALTCHA proof-of-work captcha settings |
|
||||
| experiment_delivery | [experiment delivery configuration](#experiment-delivery-configuration-object) object | Cadence every client polls the experiments route on |
|
||||
| registration | [registration configuration](#registration-configuration-object) object | Registration policy, issued URLs, and pending registrations |
|
||||
@@ -160,27 +159,6 @@ Only the official web client acts on this configuration. On any other instance i
|
||||
Setting `enabled` to false stops new migrations and also stops forwarding from the legacy origin for clients that already moved. Excluding an account only stops a migration that has not started yet.
|
||||
:::
|
||||
|
||||
## Plutonium page configuration object
|
||||
|
||||
The instance rollout that replaces the Plutonium settings tab with a full Plutonium page, makes app pages linkable in chat, and uses a minimal gift purchase modal. [Experiments](/http-api/experiments/#plutonium-page-assignment-object) defines what a client resolves from it.
|
||||
|
||||
### Structure
|
||||
|
||||
| Field | Type | Description |
|
||||
| --- | --- | --- |
|
||||
| enabled | boolean | Whether the rollout runs at all (default false) |
|
||||
| config_version | integer | Revision counter, raised by Fluxer and never accepted from a request |
|
||||
| rollout_basis_points | integer | Share of accounts the rollout selects, in basis points (0-10000, default 0) |
|
||||
| rollout_salt | string | Salt of the sampling hash (1-64 printable ASCII characters, default `plutonium-page-v1`) |
|
||||
| included_user_ids | array[snowflake] | Accounts the rollout always selects, up to 1000 entries (default empty) |
|
||||
| included_guild_ids | array[snowflake] | Guilds whose members the rollout always selects, up to 1000 entries (default empty) |
|
||||
| include_premium_users | boolean | Whether the rollout always selects accounts with active premium (default false) |
|
||||
| excluded_user_ids | array[snowflake] | Accounts the rollout never selects, up to 1000 entries (default empty) |
|
||||
|
||||
Every field is present on read. An absent document or missing field uses the defaults above.
|
||||
|
||||
`excluded_user_ids` wins over every other rule. Otherwise the rollout selects an account in `included_user_ids`, a member of a guild in `included_guild_ids`, or a premium account while `include_premium_users` is true, whatever `rollout_basis_points` says.
|
||||
|
||||
## Captcha configuration object
|
||||
|
||||
The ALTCHA proof-of-work check that the API issues and verifies itself on gated operations. [CAPTCHA handling](/topics/captcha/) defines the challenge exchange and lists the gated operations.
|
||||
@@ -633,7 +611,6 @@ The body has one optional object for each section. Fluxer leaves an absent secti
|
||||
| gateway_rollout? | object | Any subset of the [Gateway rollout configuration](#gateway-rollout-configuration-object) fields, each bound as documented there |
|
||||
| push_relay? | object | `relay_consent_accepted` from the [push relay configuration](#push-relay-configuration-object) |
|
||||
| domain_migration? | object | Any subset of the [domain migration](#domain-migration-configuration-object) fields |
|
||||
| plutonium_page? | object | Any subset of the [Plutonium page](#plutonium-page-configuration-object) fields |
|
||||
| captcha? | object | Any subset of the [captcha configuration](#captcha-configuration-object) fields |
|
||||
| experiment_delivery? | object | Any subset of the [experiment delivery](#experiment-delivery-configuration-object) fields |
|
||||
| registration? | object | `mode` and `admin_registration_urls_enabled` |
|
||||
@@ -651,8 +628,6 @@ The body has one optional object for each section. Fluxer leaves an absent secti
|
||||
|
||||
`domain_migration` takes every [domain migration configuration](#domain-migration-configuration-object) field except `config_version`, each bound as documented there. Fluxer raises `config_version` by one on each request that supplies at least one of them. A section that is absent, or present with no field set, writes nothing and leaves `config_version` alone.
|
||||
|
||||
`plutonium_page` works the same way, over the [Plutonium page configuration](#plutonium-page-configuration-object) fields and its own `config_version`.
|
||||
|
||||
`captcha` takes any subset of the [captcha configuration](#captcha-configuration-object) fields, each bound as documented there. Fluxer merges the supplied fields over the stored ones. The section has no `config_version`.
|
||||
|
||||
`experiment_delivery` takes both [experiment delivery configuration](#experiment-delivery-configuration-object) fields, each bound as documented there. It is a section of its own, so a write to it changes no `config_version` and changes no assignment, only the cadence on which clients ask for one.
|
||||
@@ -693,7 +668,7 @@ On a self-hosted deployment, billing and the `everyone` premium mode exclude eac
|
||||
| 400 | [error response](/admin-api/#error-response) | A policy transition is refused, returned as `INSTANCE_POLICY_TRANSITION_NOT_ALLOWED` |
|
||||
|
||||
:::caution[Sections are applied one after another]
|
||||
The order is `gateway_rollout`, `push_relay`, `domain_migration`, `plutonium_page`, `captcha`, `experiment_delivery`, `sso`, `registration`, `app_public` branding, legal, and registration fields, `integrations`, `media`, `policy`, `billing`, and finally `app_public.setup`. A failure part way through leaves the earlier sections written.
|
||||
The order is `gateway_rollout`, `push_relay`, `domain_migration`, `captcha`, `experiment_delivery`, `sso`, `registration`, `app_public` branding, legal, and registration fields, `integrations`, `media`, `policy`, `billing`, and finally `app_public.setup`. A failure part way through leaves the earlier sections written.
|
||||
:::
|
||||
|
||||
### Side effects
|
||||
|
||||
@@ -1,47 +1,13 @@
|
||||
---
|
||||
# SPDX-License-Identifier: AGPL-3.0-or-later
|
||||
title: Admin threads
|
||||
description: The channel_threads rollout configuration, guild thread lookup, and thread deletion.
|
||||
description: Guild thread lookup and thread deletion.
|
||||
draft: true
|
||||
---
|
||||
|
||||
import RouteHeader from '@/components/RouteHeader.astro';
|
||||
|
||||
The Admin API reads and deletes [threads](/http-api/threads/) whether or not the `channel_threads` experiment is active for their guild. The rollout itself is part of the [instance configuration](/admin-api/instance/#instance-configuration-object) under `channel_threads`.
|
||||
|
||||
## Channel threads configuration object
|
||||
|
||||
The instance rollout of threads, forum channels, and media channels. A guild is enabled by the guild fields, and a user within it by the user fields.
|
||||
|
||||
### Structure
|
||||
|
||||
| Field | Type | Description |
|
||||
| --- | --- | --- |
|
||||
| enabled | boolean | Whether the rollout runs at all (default false) |
|
||||
| config_version | integer | Revision counter, raised by Fluxer and never accepted from a request |
|
||||
| ever_enabled<sup>1</sup> | boolean | Whether `enabled` was ever true |
|
||||
| guild_basis_points | integer | Share of guilds the rollout selects, in basis points (0-10000, default 0) |
|
||||
| guild_salt | string | Salt of the guild sampling hash (1-64 printable ASCII characters, default `channel-threads-guild-v1`) |
|
||||
| enabled_guild_ids | array[snowflake] | Guilds the rollout always selects, up to 1000 entries (default empty) |
|
||||
| disabled_guild_ids | array[snowflake] | Guilds the rollout never selects, up to 1000 entries (default empty) |
|
||||
| user_basis_points | integer | Share of accounts the rollout selects, in basis points (0-10000, default 0) |
|
||||
| user_salt | string | Salt of the account sampling hash (1-64 printable ASCII characters, default `channel-threads-user-v1`) |
|
||||
| included_user_ids | array[snowflake] | Accounts the rollout always selects, up to 1000 entries (default empty) |
|
||||
| excluded_user_ids<sup>2</sup> | array[snowflake] | Accounts and bots the rollout never selects, up to 1000 entries (default empty) |
|
||||
|
||||
<sup>1</sup> Set by Fluxer on the first write with `enabled` true, never cleared, and never accepted from a request
|
||||
|
||||
<sup>2</sup> An excluded moderation bot sees no thread and cannot act on one
|
||||
|
||||
Every field is present on read. An absent document or missing field uses the defaults above.
|
||||
|
||||
`disabled_guild_ids` wins over `enabled_guild_ids`, and `enabled_guild_ids` wins over `guild_basis_points`. The user fields follow the same order. A bot follows the guild fields and `excluded_user_ids` alone. A user also needs a client that declares `channel_threads`.
|
||||
|
||||
A user outside the rollout in an enabled guild sees no thread, forum, or media channel while other members do. Set `user_basis_points` to 10000 before enabling a guild outside staff.
|
||||
|
||||
:::caution[Disabling keeps the stored threads]
|
||||
Setting `enabled` to false hides every thread, forum, and media channel and stops automatic archiving. Re-enabling shows the stored data again.
|
||||
:::
|
||||
The Admin API reads and deletes [threads](/http-api/threads/) in any guild.
|
||||
|
||||
## List guild threads
|
||||
|
||||
|
||||
@@ -7,8 +7,8 @@ draft: true
|
||||
|
||||
A session receives [threads](/http-api/threads/) through the Dispatch events below. A guild ready object in [Ready](/gateway/events/#ready), [Guild Create](/gateway/events/#guild-create), and [Guild Sync](/gateway/events/#guild-sync) has `threads` only when the session can view threads in that guild. A client treats the presence of that key as the signal that threads, forums, and media channels exist in the guild.
|
||||
|
||||
:::note[Threads need the `channel_threads` experiment]
|
||||
A user session receives thread data only when it sets `CHANNEL_THREADS` in Identify and the experiment is active for the guild and the account. A bot session needs no flag.
|
||||
:::note[Threads need the `CHANNEL_THREADS` capability]
|
||||
A user session receives thread data only when it sets `CHANNEL_THREADS` in Identify. A bot session needs no flag.
|
||||
:::
|
||||
|
||||
## Session flag
|
||||
|
||||
@@ -6,7 +6,7 @@ description: The experiment assignments envelope, the revalidation and polling c
|
||||
|
||||
import RouteHeader from '@/components/RouteHeader.astro';
|
||||
|
||||
An experiment is an instance-wide rollout that an operator configures. For each account, Fluxer works out from that configuration whether the account is in the rollout and which settings the account receives. The single route on this page resolves every experiment the server defines and returns them in one envelope, together with the polling cadence they share. This server defines `domain_migration` and `plutonium_page`.
|
||||
An experiment is an instance-wide rollout. For each account, Fluxer works out whether the account is in the rollout and which settings the account receives. The single route on this page resolves every experiment the server defines and returns them in one envelope, together with the polling cadence they share. This server defines `domain_migration` and `plutonium_page`. Only `domain_migration` is configured by an operator. `plutonium_page` is on for every account.
|
||||
|
||||
Every assignment is advice. A client that ignores one behaves as it does with the rollout off, and no route and no Gateway event reports what a client actually ran.
|
||||
|
||||
@@ -53,17 +53,17 @@ Only the official web client acts on this assignment, and only on its legacy ori
|
||||
|
||||
## Plutonium page assignment object
|
||||
|
||||
One resolution of the instance Plutonium page rollout against one account. This server version writes the key on every response.
|
||||
The Plutonium page state for one account. This server version writes the key on every response, always with `enabled` true.
|
||||
|
||||
### Structure
|
||||
|
||||
| Field | Type | Description |
|
||||
| --- | --- | --- |
|
||||
| enabled | boolean | Whether the caller's client shows the full Plutonium page in place of the Plutonium settings tab |
|
||||
| enabled | boolean | Whether the caller's client shows the full Plutonium page in place of the Plutonium settings tab, always true |
|
||||
|
||||
A caller is drawn by the operator's account or guild allowlist, by having premium when the operator includes premium users, or by the sampled share of the account population. `enabled` is false in every other case, the rollout being off included.
|
||||
The rollout is complete and has no operator setting. The key stays for clients that still read it.
|
||||
|
||||
The assignment only changes what the client shows. A selected client replaces the Plutonium settings tab with a full Plutonium page, makes app pages linkable in chat, and uses a minimal gift purchase modal. The server applies no part of it on its own.
|
||||
The assignment only changes what the client shows. An enabled client replaces the Plutonium settings tab with a full Plutonium page, makes app pages linkable in chat, and uses a minimal gift purchase modal. The server applies no part of it on its own.
|
||||
|
||||
## Get experiment assignments
|
||||
|
||||
|
||||
@@ -9,8 +9,8 @@ import RouteHeader from '@/components/RouteHeader.astro';
|
||||
|
||||
A forum channel holds posts, and every post is a public [thread](/http-api/threads/) with its own first message. A media channel is a forum channel whose posts center on attachments. Neither accepts a message of its own.
|
||||
|
||||
:::note[Every route needs the `channel_threads` experiment]
|
||||
A route on this page answers 404 `NOT_FOUND` unless the experiment is active for the guild and the caller. A user session also declares `channel_threads` in the `X-Fluxer-Features` header, and a bot needs no declaration.
|
||||
:::note[Every route needs the `channel_threads` client capability]
|
||||
A route on this page answers 404 `NOT_FOUND` to a user session that does not declare `channel_threads` in the `X-Fluxer-Features` header. A bot needs no declaration.
|
||||
:::
|
||||
|
||||
## Forum channel fields
|
||||
|
||||
@@ -9,8 +9,8 @@ import RouteHeader from '@/components/RouteHeader.astro';
|
||||
|
||||
A thread member records that a user joined a [thread](/http-api/threads/). A thread holds at most 1,000 members, and adding one more returns 400 `MAX_THREAD_MEMBERS`.
|
||||
|
||||
:::note[Every route needs the `channel_threads` experiment]
|
||||
A route on this page answers 404 `NOT_FOUND` unless the experiment is active for the guild and the caller. A user session also declares `channel_threads` in the `X-Fluxer-Features` header, and a bot needs no declaration.
|
||||
:::note[Every route needs the `channel_threads` client capability]
|
||||
A route on this page answers 404 `NOT_FOUND` to a user session that does not declare `channel_threads` in the `X-Fluxer-Features` header. A bot needs no declaration.
|
||||
:::
|
||||
|
||||
## Thread member object
|
||||
|
||||
@@ -11,8 +11,8 @@ A thread is a channel inside a guild text, announcement, forum, or media channel
|
||||
|
||||
[Thread members](/http-api/thread-members/) defines joining, leaving, and member lists. [Forums](/http-api/forums/) defines forum and media channels, where every thread is a post.
|
||||
|
||||
:::note[Every route needs the `channel_threads` experiment]
|
||||
A route on this page answers 404 `NOT_FOUND` unless the experiment is active for the guild and the caller. A user session also declares `channel_threads` in the `X-Fluxer-Features` header, and a bot needs no declaration.
|
||||
:::note[Every route needs the `channel_threads` client capability]
|
||||
A route on this page answers 404 `NOT_FOUND` to a user session that does not declare `channel_threads` in the `X-Fluxer-Features` header. A bot needs no declaration.
|
||||
:::
|
||||
|
||||
## Thread object
|
||||
@@ -539,7 +539,7 @@ Sending a message in a thread adds a user sender who is not a member. A mentione
|
||||
| Message search result | threads | The threads that contain a returned message |
|
||||
| Message search result | members | A thread member object for each of those threads the caller joined |
|
||||
| Audit log | threads | The threads referenced by the returned entries |
|
||||
| Experiment assignments | channel_threads | `active` and `config_version`, present only for an account in the rollout |
|
||||
| Experiment assignments | channel_threads | `active` and `config_version`, present for every account |
|
||||
|
||||
The guild audit log records thread creation, update, and deletion as action types 110, 111, and 112.
|
||||
|
||||
|
||||
Reference in new issue
Block a user