docs: plan report/block/hide, decide M8's open items, plan demo content
- website/USER_SAFETY.md (new): report, block and hide on the website and in the app, S1-S5 decided by the org lead, five questions open. - android/PLAN.md: M8's three open items decided (keep the rating and add report/block/hide; conservative data safety; UnifiedPush on specialUse with restart on boot), the order to the cutover, and M21 (Teams and the team forum in the app, planned, not scheduled). - website/DEMO_MODE.md: DM32 and section 11, the demo content plan (two seed passes; moderation, Teams/forum/reports, event history, Rust stats). Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01E14m6SuuY6i1vASFeGDBeY
This commit is contained in:
@@ -1003,20 +1003,46 @@ push, and Play (M6–M8) follow the designed app.
|
||||
for 14 days in a row** before it can apply for production. runicgateway.com `/beta`
|
||||
collects them.
|
||||
|
||||
**Open, each waiting for a decision:**
|
||||
**The three open questions, decided (org lead, 2026-10-29):**
|
||||
- **Content rating.** The questionnaire answered "Social or Communication: moderated chat;
|
||||
users or user-generated content can be reported". The app shows other players' chat (the
|
||||
Rust feed) but has no report or block action, and Play's user-generated-content policy
|
||||
expects both where that is declared. Either retake the questionnaire, or add report/block
|
||||
to the app.
|
||||
- **Data safety's premise.** The generated notes answer "not collected" almost everywhere,
|
||||
because the app talks only to a deployment the user chose. The notes call it the answer
|
||||
most likely to be questioned in review. Declaring user IDs and messages as collected,
|
||||
encrypted in transit and needed for the app to work, is the conservative alternative.
|
||||
Rust feed) but had no report or block action, and Play's user-generated-content policy
|
||||
expects both where that is declared. **Decided: keep the answer and make it true** with
|
||||
report, block and hide, on the website and in the app. The plan of record is
|
||||
[`website/USER_SAFETY.md`](../website/USER_SAFETY.md): a block lives on the account and
|
||||
applies everywhere; a member can hide an item for themself, and staff can hide it for
|
||||
everyone. In the app it goes on chat lines. The team forum in the app is planned as M21.
|
||||
- **Data safety's premise.** The generated notes answered "not collected" almost everywhere,
|
||||
because the app talks only to a deployment the user chose. **Decided: the conservative,
|
||||
more accurate answers.** Each kind of data the app sends to the deployment is declared
|
||||
collected, not shared, encrypted in transit and required for the app to work. That is
|
||||
what Play counts as collection, since the data leaves the device, whoever runs the server.
|
||||
runicgateway.com's generator (`scripts/playDataSafety.mjs`, from `src/data/collection.mjs`)
|
||||
changes to say so after an audit of what the app actually transmits. The published privacy
|
||||
page keeps saying that *we* receive nothing, which stays true.
|
||||
- **The push foreground service.** Play asks for a declaration (and a video) for the
|
||||
`dataSync` service that holds the ntfy connection. Google reserves `dataSync` for transfers,
|
||||
and Android 15 limits it to six hours a day. This brings forward §13's "FCM flavor for
|
||||
Play?" question.
|
||||
`dataSync` service that holds the ntfy connection. Google reserves `dataSync` for
|
||||
transfers, and Android 15 limits it to six hours a day. **Decided: keep UnifiedPush.** The
|
||||
service changes to the `specialUse` type with a `PROPERTY_SPECIAL_USE_FGS_SUBTYPE` reason,
|
||||
as ntfy does on Play; `specialUse` has no daily limit. **Push also restarts after a
|
||||
reboot** when the member had it on and is signed in, which `specialUse` allows from
|
||||
`BOOT_COMPLETED` and `dataSync` does not. This also fixes a crash: `PushService` does not
|
||||
handle `onTimeout`, so on Android 15+ with target 36 (`edge` since step 1) the six-hour
|
||||
cut-off would crash the app. The declaration's video is recorded on the emulator (turn push
|
||||
on, the ongoing notification, a push arriving), and the org lead uploads it. §13's "FCM
|
||||
flavor for Play?" is therefore answered **no**.
|
||||
|
||||
**The order from here** (org lead, 2026-10-29):
|
||||
1. **Push** (`edge`): `specialUse` and the restart on boot. One PR.
|
||||
2. **Data safety** (runicgateway.com): the audit and the generator. One PR.
|
||||
3. **Report, block and hide** across `website`, `Module-Rust`, the kit and this app
|
||||
(`USER_SAFETY.md` §7).
|
||||
4. **The cutover**, `edge` → `main`, once 1-3 have landed, so the first Play bundle carries
|
||||
all of it. **Before it merges, the org lead enrolls the existing keystore as the app-signing
|
||||
key** in Play Console (App integrity, "use my own key"). `PLAY_SERVICE_ACCOUNT_JSON` is
|
||||
already set, so the release run will call Play, and the signing choice is permanent. On the
|
||||
draft app, CI's commit is refused as expected; the first bundle is then uploaded by hand
|
||||
(step 2 above).
|
||||
10. **M9 — Native SSO login** (post-v1, additive; independent of M8): in-app "Sign in with Google /
|
||||
Discord" via the **Mobile SSO Authorization Bridge** (§4.2). **Backend-first**, mirroring M7's
|
||||
split:
|
||||
@@ -1828,9 +1854,39 @@ push, and Play (M6–M8) follow the designed app.
|
||||
just as wrong. A maintenance error kind, read from that body, is the likely fix. It is
|
||||
outside M20 and waits for a decision.
|
||||
|
||||
22. **M21 — Teams and the team forum in the app** (post-v1; planned 2026-10-29, **not scheduled**).
|
||||
The org lead asked for it with M8's user-safety decision (`../website/USER_SAFETY.md` S4). It
|
||||
revives the deferred *Platform Teams in the app* below, whose revival trigger (Team pages,
|
||||
roster and forums on the website) has long since been met.
|
||||
|
||||
**Scope:**
|
||||
- **A Teams entry** in the menu: the member's own Teams (`GET /player/teams`) and the public
|
||||
list (`GET /public/teams`), then a Team's page (`/public/teams/:slug`, its members and
|
||||
activity).
|
||||
- **The forum**, for a Team the member can read (`GET /player/teams/:slug/access`): threads
|
||||
(`…/forum/threads`), a thread's posts (`…/forum/threads/:id`), reply and new thread
|
||||
(`POST …/threads`, `…/threads/:id/posts`), and editing their own post (`PATCH …/posts/:id`).
|
||||
Leaders get pin, lock and hide through the existing `…/moderate` routes.
|
||||
- **Report, hide for me and block** on every thread and post, as on chat lines
|
||||
(`USER_SAFETY.md` §4).
|
||||
- **Deep links** for the four Team push streams, which today open the app and no more, and the
|
||||
per-Team mute list (`GET|PUT /auth/me/notifications/teams`; its DTO field has no default,
|
||||
see the trap noted below).
|
||||
- **Uploads: view only** to begin with. Sending a file from the phone is a later decision,
|
||||
because uploads carry the operator's liability acknowledgement (`TEAMS.md` §5.5).
|
||||
|
||||
**What it changes for Play:** members can then post from the app, so the data-safety
|
||||
declaration gains "user-generated content: collected" and the content rating stays as
|
||||
answered. runicgateway.com's `collection.mjs` gains the row in the same change.
|
||||
|
||||
**Before it starts:** USER_SAFETY.md's build order is done (the report/block/hide routes M21
|
||||
reuses), and the questions it will raise (offline drafts, uploads, the order of the Teams tab
|
||||
in the menu) go to the org lead first.
|
||||
|
||||
### Deferred (not a milestone)
|
||||
|
||||
- **Platform Teams in the app** — **deferred 2026-08-17, no app work scheduled.** The website is
|
||||
- **Platform Teams in the app** — **revived as M21 on 2026-10-29** (above); the text below is the
|
||||
2026-08-17 deferral, kept for its reasoning. **Deferred 2026-08-17, no app work scheduled.** The website is
|
||||
building Teams as a core platform primitive (pages, roster, activity feed, forums, notifications —
|
||||
[`../website/TEAMS.md`](../website/TEAMS.md)), and the app has no story for any of it. Deferred
|
||||
deliberately rather than scheduled: this milestone list is already behind, and adding a large new
|
||||
@@ -2147,7 +2203,8 @@ it is a UX convenience, not a v1 requirement — deferred at M3, descoped at M6;
|
||||
No backend publish token — **decided** (the content-free-tickle design does not require one; optional
|
||||
`NTFY_PUBLISH_TOKEN` is honored if ever set).
|
||||
- FCM flavor: build it for the Play release or ship Play on UnifiedPush too? Decide at M8. (The M7
|
||||
Part 2 `PushTransport` seam keeps this swap cheap.)
|
||||
Part 2 `PushTransport` seam keeps this swap cheap.) **Decided at M8 (2026-10-29): UnifiedPush on
|
||||
Play too**, with the service moved to the `specialUse` type.
|
||||
- Deep-link / share targets for wiki pages and posts (share/open-in-app). *Notification-tap* deep-links
|
||||
are **resolved** for M7 Part 2 (stream→screen map, work item 7).
|
||||
- iOS: none planned (this is the Android-only choice); revisit only if cross-platform is later
|
||||
|
||||
Reference in New Issue
Block a user