2026-06-28 09:06:51 -04:00
|
|
|
# @mr-number — project instructions
|
|
|
|
|
|
2026-06-29 13:44:25 -04:00
|
|
|
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.
|
2026-06-28 09:06:51 -04:00
|
|
|
|
|
|
|
|
## 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."
|
|
|
|
|
|
2026-06-28 15:05:33 -04:00
|
|
|
## Architecture
|
2026-06-28 09:06:51 -04:00
|
|
|
- **plum client** (`client/`): `mr_lookup.py` drives an Android device over adb,
|
|
|
|
|
screenshots the Mr. Number reports screen, vision-extracts via the Claude batch
|
2026-06-29 13:44:25 -04:00
|
|
|
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.
|
2026-06-28 15:05:33 -04:00
|
|
|
- **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`.
|
2026-06-28 09:06:51 -04:00
|
|
|
|
|
|
|
|
## 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`.
|
2026-06-29 13:44:25 -04:00
|
|
|
- **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.
|
feat(deploy): trigger service deploys to the redroid box (systemd), not plum (launchd)
Per the corrected .infra.yaml, the trigger service is a PROD unit that runs ON the
redroid box (next to the Android container → local adb), with plum as dev-only. Replace
the (wrong) macOS LaunchAgent with the box-native pattern, mirroring @redroid's
deploy-droplet.sh / mrnumber-ocr.service:
- deploy/mr-number-service.service: systemd unit (multi-user.target, EnvironmentFile for
tokens, MR_NUMBER_DEVICE=localhost:5555, __BUN__ resolved at deploy time).
- deploy/deploy-service.sh: prereq-checks the box (bun/python3/redroid_client/adb), scp's
service+client to /opt/mr-number-service, installs the unit, seeds a 0600 env template,
enables only once tokens are filled (no crashloop). Does NOT mint tokens.
- service/run: drop launchd installer; plain dev launcher (loads cocotte-secrets).
- install.sh: plum = dev setup only; points prod at deploy-service.sh.
- CLAUDE.md/README: box-deploy ownership split (@redroid owns the box; we own our unit).
Syntax-checked; box SSH (:22) unreachable from this env so not yet run against the box.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-06-29 17:19:40 -04:00
|
|
|
- **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.
|
2026-06-28 15:05:33 -04:00
|
|
|
- **IaC / box ownership:** the redroid droplet's canonical Terraform lives in
|
feat(deploy): trigger service deploys to the redroid box (systemd), not plum (launchd)
Per the corrected .infra.yaml, the trigger service is a PROD unit that runs ON the
redroid box (next to the Android container → local adb), with plum as dev-only. Replace
the (wrong) macOS LaunchAgent with the box-native pattern, mirroring @redroid's
deploy-droplet.sh / mrnumber-ocr.service:
- deploy/mr-number-service.service: systemd unit (multi-user.target, EnvironmentFile for
tokens, MR_NUMBER_DEVICE=localhost:5555, __BUN__ resolved at deploy time).
- deploy/deploy-service.sh: prereq-checks the box (bun/python3/redroid_client/adb), scp's
service+client to /opt/mr-number-service, installs the unit, seeds a 0600 env template,
enables only once tokens are filled (no crashloop). Does NOT mint tokens.
- service/run: drop launchd installer; plain dev launcher (loads cocotte-secrets).
- install.sh: plum = dev setup only; points prod at deploy-service.sh.
- CLAUDE.md/README: box-deploy ownership split (@redroid owns the box; we own our unit).
Syntax-checked; box SSH (:22) unreachable from this env so not yet run against the box.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-06-29 17:19:40 -04:00
|
|
|
`~/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.
|
2026-06-29 13:44:25 -04:00
|
|
|
- **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`.
|
2026-06-28 09:06:51 -04:00
|
|
|
- **Complete code, no stubs.** If blocked: STOP → REPORT → WAIT.
|
|
|
|
|
|
|
|
|
|
## Verify before declaring done
|
2026-06-29 13:44:25 -04:00
|
|
|
- `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.
|
2026-06-28 09:06:51 -04:00
|
|
|
|
|
|
|
|
## 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>`.
|