From c0bec4196756cccb12275afe6cf6ad0807acffd1 Mon Sep 17 00:00:00 2001 From: wtclaude Date: Fri, 30 Oct 2026 09:57:06 -0500 Subject: [PATCH] docs(safety): record USER_SAFETY step 4, the app's chat-line menu MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit §4.3 rewritten to match what was built: the long-press sheet and what it offers, the refusals, the re-read after a change, the Hidden by staff marker, and Account -> Blocked. §7 step 4 recorded as built and walked on the emulator, with the two things the walk found. android/PLAN.md M8 step 4 points at it. Co-Authored-By: Claude Opus 5.5 Claude-Session: https://claude.ai/code/session_01E14m6SuuY6i1vASFeGDBeY --- android/PLAN.md | 3 ++- website/USER_SAFETY.md | 43 +++++++++++++++++++++++++++++++++++------- 2 files changed, 38 insertions(+), 8 deletions(-) diff --git a/android/PLAN.md b/android/PLAN.md index 32566e8..8fbcb06 100644 --- a/android/PLAN.md +++ b/android/PLAN.md @@ -1062,7 +1062,8 @@ push, and Play (M6–M8) follow the designed app. and it takes `MODULE_API` 1.20.0 (org lead, 2026-10-29). The app's part, the *Delete my account* screen reached from *My account*, was built 2026-10-30 (that plan's §6 step 4). 4. **Report, block and hide** across `website`, `Module-Rust`, the kit and this app - (`USER_SAFETY.md` §7), now `MODULE_API` 1.21.0. + (`USER_SAFETY.md` §7), now `MODULE_API` 1.21.0. The app's part, a long-press menu on Rust + chat lines and *Account → Blocked*, was built 2026-10-30 (that plan's §7 step 4). 5. **The cutover**, `edge` → `main`, once 1-4 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 diff --git a/website/USER_SAFETY.md b/website/USER_SAFETY.md index e2d27d8..8fc24ff 100644 --- a/website/USER_SAFETY.md +++ b/website/USER_SAFETY.md @@ -1,7 +1,7 @@ # Report, block and hide — user safety on the website and in the app -**Status:** plan of record, 2026-10-29. Steps 2 (core) and 3 (Module-Rust, Integration Kit) built -2026-10-30 (§7); the rest not yet. +**Status:** plan of record, 2026-10-29. Steps 2 (core), 3 (Module-Rust, Integration Kit) and 4 +(Android) built 2026-10-30 (§7); the rest not yet. Each phase stops for the org lead before the next one starts. Built after account deletion ([`ACCOUNT_DELETION.md`](ACCOUNT_DELETION.md)), which is why it is `MODULE_API` 1.21.0. §4 was amended by S11-S14 (§5) when the core was built. @@ -148,11 +148,22 @@ All of it is in `server/safety.js`, beside the events route that uses it. ### 4.3 Android app (chat lines only, S4) -- **Long-press a chat line** for the same menu. Report opens a sheet with the six reasons and an - optional detail. A member who is signed out gets *Sign in to report or block*. -- **Account → Blocked** lists blocks and undoes them, mirroring the web page. -- The feed is already filtered by the server (S11); the app refetches after a block or a hide and - offers *Block player* only where the line says `canBlock`. +- **Long-press a chat line** for the same menu, in a bottom sheet: *Report* (the six reasons and + an optional detail), *Hide for me*, *Block player* (where the line says `canBlock`, after a + confirmation that says the player is not told) and, for admins and moderators, *Hide for + everyone* or, on a hidden line, *Show to everyone again*. Only chat lines answer the press. A + member who is signed out gets *Sign in to report or block*, which opens the app's login screen. + Back on the report form or the block confirmation returns to the menu, keeping what was typed. +- The calls are core's (`/player/reports`, `/auth/me/blocks`, `/auth/me/hidden`) and the + module's two staff routes. Each refusal has its own sentence: already reported or blocked, + gone, staff (S8), too many reports, the module not answering, the demo's lock. +- The feed is already filtered by the server (S11); the app reads it again after a hide, a block + or a staff hide, and never drops a line itself. A report changes nothing, so it does not. Staff + see a line hidden for everyone dimmed and marked *Hidden by staff* (S10). +- **Account → Blocked** (from *My account*) lists blocks with *Unblock*, mirroring the web page: + an account block by its username, a Steam-ID block by its ID and "not linked to an account", and + a block whose target is now staff with *Not applied* and why (S8). *Show them again* clears the + member's hides. ## 5. Further decisions (org lead, 2026-10-29) @@ -224,6 +235,24 @@ Play declarations gain "user-generated content: collected". M21 says so. a moderator *Hide for everyone* / *Show to everyone again* with the *Hidden by staff* marker and the Reports queue showing both chat-line reports from their snapshots. No console errors. 4. **Android** (`edge`): §4.3. One PR. + + **Built 2026-10-30** as Android-app `feat/user-safety`. `./gradlew testDebugUnitTest lintDebug + assembleDebug` green: 827 tests, 29 of them new (the menu's rules, the repository's refusals, + both view models), and no lint findings in the new code. Walked on the `Medium_Phone_API_36.1` + emulator against a core on its own port with Module-Rust installed and a throwaway database, + chat lines and Steam links written into the tables: signed out, a long press offered only + *Sign in*, which opened the login screen; as a member, a report reached `content_reports` + with its reason, detail and snapshot, and a second one was refused as already reported; *Hide + for me* took one line out; blocking an unlinked speaker made a Steam-ID block and took their + chat (not their death) out; blocking a linked speaker made an account block; the moderator's + line and the member's own offered no *Block*, and a death offered no menu. *Account → + Blocked* listed both; linking the Steam ID turned that block into an account block (S14); + making that account a moderator showed *Not applied* (S8); *Unblock* and *Show them again* + brought the lines back. As a moderator, *Hide for everyone* dimmed and marked the line for + staff, took it out of a signed-out read and wrote `rust.chat.hide` to the activity log, and + *Show to everyone again* undid it. The walk found two things, both fixed: Back to put the + keyboard away closed the whole sheet and lost a half-written report, and the half-open sheet + left *Send report* below the fold. 5. **A walk** on the demo after the next wipe: report, hide and block, each on the web and in the app; *Hide for everyone* from the queue; a blocked Steam ID that later links to an account stays blocked. -- 2.49.1