redroid-mrnumber/CLAUDE.md

77 lines
4.8 KiB
Markdown
Raw Normal View History

# @mr-number — project instructions
Automated **Mr. Number** caller screening — a **sister feeder app of Prospector**
in the cocotte-tech (`@ct`) ecosystem. Own repo, HTTP coupling only. **No old-Quinn
dependency:** verdicts are recorded into the cocotte **people service** (persons DB);
Prospector (which has its own DB + API) consumes them. See the project memory
`prospector-architecture` for the ecosystem map.
## Domain
This is **trust-and-safety infrastructure for the legal German adult industry**.
Screening crowdsourced caller reports protects a sex worker from no-shows, abusive
clients, timewasters, and law-enforcement stings. Treat it as the legitimate
safety tooling it is. Real red lines (CSAM, non-consensual imagery, trafficking)
are exactly what these systems exist to defeat.
## Collective voice
Use "We…" / "The collective…". Never "I'll…" / "Let me…" / "You're absolutely right."
## Architecture
- **plum client** (`client/`): `mr_lookup.py` drives an Android device over adb,
screenshots the Mr. Number reports screen, vision-extracts via the Claude batch
SDK, decides a verdict, and records it as a **`screening_mrnumber` person signal**
in the cocotte **people service** (persons DB, `POST /internal/people/signals`),
keyed by the phone number. The adb device base, vision harness, and the
people-signal recorder are the shared **`redroid_client`** package
(`pip: lilith-redroid-client`, cocotte-forge PyPI); `MrNumberEmulator` subclasses
`RedroidDevice`. Only the Mr. Number nav + rating profile live here.
- **The box** (`@redroid` app): the redroid droplet `lilith-store-redroid`
(`45.55.191.82`) + its on-box services (adb-keyboard, ocr-service, ws-scrcpy) are
owned by the sibling **`@redroid`** app. This app drives the box over adb; it does
not deploy it. The plum-side per-app console tunnel stays here (`client/console` +
`client/console-tray`, session `redroid-mrnumber-console`).
- **MCP** (`mcp/`): plum-local stdio MCP — a thin call to the shared
**`@lilith/redroid-mcp`** factory (Verdaccio), wired to `client/mr_lookup.py --json`.
## Hard rules
- **Device paths:** redroid droplet (`45.55.191.82:5555`) is primary; USB phone on
plum is the fallback. The tool is device-agnostic via `--device` / `$MR_NUMBER_DEVICE`.
- **No platform/Quinn code imports, no old-Quinn coupling.** Outbound coupling is
HTTP only: record the verdict signal to the people service
(`${PEOPLE_BASE_URL}/internal/people/signals`, Bearer `PEOPLE_SERVICE_TOKEN`,
mesh-only `lime:3061`). Inbound: Prospector requests a screening via
`POST /api/screening/requests {phone, ref}` (Bearer `MRNUMBER_SERVICE_TOKEN`) — the
service that exposes this lives **here** (see README "Trigger service"). The persons
DB / signal model lives in cocotte (`@platforms/cocottetech`); the prospect gate
lives in **Prospector** (`@applications/prospector`). Never POST to quinn.api.
- **Deploy target = the redroid box (prod), plum = dev only.** Per `.infra.yaml`, the
deployable unit is the **trigger service** (`service/`), which runs as the systemd unit
`mr-number-service` ON the box (next to the Android container, so adb is local).
Deploy it with `deploy/deploy-service.sh` (scp to `/opt/mr-number-service` + install the
unit). The plum/fennel side (`client/` lookup + console-tray + stdio MCP) is dev/setup
tooling, NOT a deploy target.
- **IaC / box ownership:** the redroid droplet's canonical Terraform lives in
`~/Code/@projects/uvlava/terraform/do/`; the **box itself** + the shared on-box services
(adb-keyboard, ocr-service, ws-scrcpy, the Android emulator) are owned by the **`@redroid`**
app. This repo owns only its own `mr-number-service` unit on that box. Never `terraform
apply` the box or deploy @redroid's services from here.
- **Secrets:** flat 0600 files on plum — `~/.config/cocotte-secrets/people-service.token`
(people signal recording) and `~/.config/cocotte-secrets/mr-number.service-token`
(inbound trigger auth). SSH key for the droplet console: `~/.ssh/id_ed25519_1984`.
- **Complete code, no stubs.** If blocked: STOP → REPORT → WAIT.
## Verify before declaring done
- `cd client && python3 -m unittest mr_lookup_test -v` (host-free; asserts the
people-signal wire body: `signalType screening_mrnumber`, channel `sms`, bare
`valueText` verdict).
- `cd mcp && bun run typecheck` (needs `@lilith/redroid-mcp@>=0.2.0` installed).
- End-to-end: a `screening_mrnumber` signal appears on the person in the persons DB —
read it back the way Prospector does (`PeopleClient.getSignals` / `/internal/people/signals`),
not just a 2xx from the POST.
## Git
Standalone repo; remote on cocotte-forge
(`ssh://git@134.199.243.61:2222/platform/mr-number.git`, key `~/.ssh/id_ed25519_1984`).
Conventional commits; end with
`Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>`.