add 0053/SESSION-0053.0-TRANSCRIPT-2026-05-31T20-53--2026-06-01T03-02.md + replace placeholder/variant SESSION-0053.0-TRANSCRIPT-2026-05-31T20-53--INPROGRESS.md
This commit is contained in:
@@ -0,0 +1,269 @@
|
|||||||
|
# Session 0053.0 — Transcript
|
||||||
|
|
||||||
|
> Date: 2026-05-31 → 2026-06-01
|
||||||
|
> Goal: Build the **Patchwatch Phase 1 cloud runner** (ohm-rfc ROADMAP #43,
|
||||||
|
> proposal §6) — the always-on, read-only incarnation of `flotilla audit` as a
|
||||||
|
> scheduled Cloud Run job that alerts on fast/mitigation findings.
|
||||||
|
>
|
||||||
|
> Outcome: **Shipped flotilla v1.7.0 (cloud-runner code + image + provisioning)
|
||||||
|
> and v1.7.1 (provisioning-script fixes found live). The runner is fully
|
||||||
|
> provisioned in `wiggleverse-ohm` and verified end-to-end: a scheduler-triggered
|
||||||
|
> Cloud Run execution resolved the private pin 0.31.3, scanned all three
|
||||||
|
> network-readable layers with zero scanner_errors, and exited non-zero on the
|
||||||
|
> live tqdm fast-lane finding (the intended alert).**
|
||||||
|
>
|
||||||
|
> Highlights / surprises:
|
||||||
|
> - Two real bugs surfaced by the first-ever wheel install of flotilla (the
|
||||||
|
> runner image): a transient Secret Manager failure crashed the whole audit
|
||||||
|
> instead of degrading; `__version__` couldn't resolve in site-packages.
|
||||||
|
> - A parallel session's in-progress `SPEC.md` edit landed in the shared
|
||||||
|
> checkout mid-session and got swept into a commit — caught before push,
|
||||||
|
> un-committed, left intact for its owner (the worktree-isolation lesson,
|
||||||
|
> realized: see [[feedback_worktree_for_parallel_git]]).
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## Plan
|
||||||
|
|
||||||
|
- [x] **Slice 1 — `flotilla audit` cloud-runner readiness (v1.7.0).** `--layer`
|
||||||
|
repeatable; `--fail-on-lane` (lane-based exit gate); `--fail-on-scanner-error`
|
||||||
|
(blind-radar gate). Tests + SPEC §12.4 + CHANGELOG + VERSION. Tag + push.
|
||||||
|
- [x] **Slice 2 — runner container + provisioning artifacts.** `runner/Dockerfile`,
|
||||||
|
`runner/entrypoint.sh`, `runner/cloudbuild.yaml`,
|
||||||
|
`scripts/patchwatch-runner-deploy.sh`. Image builds + runs.
|
||||||
|
- [x] **Slice 3 — provision GCP resources.** AR repo, least-privilege runtime SA,
|
||||||
|
Cloud Run job, 6h Cloud Scheduler, Cloud Monitoring email alert. Verified.
|
||||||
|
- [x] **Slice 4 — docs + transcript.**
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## Pre-session state
|
||||||
|
|
||||||
|
- flotilla `main` = `70ba3b0` (v1.6.0 — authenticated Gitea reads). Tags through
|
||||||
|
v1.6.0 pushed. Working tree clean.
|
||||||
|
- Patchwatch radar logic complete and live from the laptop (`flotilla audit`);
|
||||||
|
session 0052 resolved the private-repo blocker with a dedicated read token
|
||||||
|
(`wiggleverse-ohm/ohm-rfc-app-gitea-read-token`). `audit` ran clean (9
|
||||||
|
findings, 0 scanner_errors).
|
||||||
|
- The handoff offered three unblocked moves; the operator chose **#3, the cloud
|
||||||
|
runner**, over the Phase 2 OS layer and a design-only pass (via AskUserQuestion).
|
||||||
|
- The tqdm fast-lane bump (#1) stays blocked on Track Δ; the Phase 5
|
||||||
|
auto-initiate tier was explicitly off-limits.
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## Turn-by-turn arc
|
||||||
|
|
||||||
|
### Arc 1 — Orient + scope the runner
|
||||||
|
|
||||||
|
Read the audit module, registry/DB, secret resolution, and `register-ohm.sh`.
|
||||||
|
Key findings that shaped the design:
|
||||||
|
- `secrets.read_secret` uses ADC via the google client library → in Cloud Run
|
||||||
|
the runtime SA's metadata creds resolve it; no gcloud CLI needed in the image
|
||||||
|
for the three network-readable layers.
|
||||||
|
- The deployment record lives in a local SQLite (`OHM_RFC_APP_FLOTILLA_DATA_DIR`).
|
||||||
|
The container bootstraps an **ephemeral** record (non-secret §13 coordinates +
|
||||||
|
the gitea-read **secret reference** — never the bytes; §3 invariant 1).
|
||||||
|
- The `os` layer needs IAP-SSH, which a read-only runner identity deliberately
|
||||||
|
lacks → the runner scans `py-app` + `node-app` + `flotilla` and omits `os`
|
||||||
|
(OS visibility stays a laptop / Phase-2 concern). This matched the operator's
|
||||||
|
mental model in the handoff ("Secret Manager access" only, no IAP).
|
||||||
|
|
||||||
|
### Arc 2 — Slice 1: audit cloud-runner gates (v1.7.0)
|
||||||
|
|
||||||
|
`--layer` made repeatable (`run_audit` already took a list). Added two
|
||||||
|
lane/blindness-aware exit gates because the design's alerting is **lane**-based
|
||||||
|
while the existing `--fail-on` is severity-based:
|
||||||
|
- `--fail-on-lane fast|routine|mitigation` (repeatable) — catches a
|
||||||
|
KEV-escalated sub-HIGH (`fast` at MEDIUM) that `--fail-on high` would miss.
|
||||||
|
- `--fail-on-scanner-error` — a blind radar (revoked token / lost SM access)
|
||||||
|
pages instead of silently reporting "all clear."
|
||||||
|
|
||||||
|
Verifying the exact runner invocation locally surfaced the **first real bug**:
|
||||||
|
the laptop's ADC had expired mid-session, and the resulting Secret Manager
|
||||||
|
failure came back as a `RetryError` (retry budget exhausted) — which
|
||||||
|
`secrets.read_secret` did NOT wrap, so it escaped as a raw google exception and
|
||||||
|
**crashed the whole audit** instead of degrading to a `scanner_error`
|
||||||
|
(violating §2 + the Phase-1 acceptance "degrade, don't crash"). Fixed by
|
||||||
|
catching the common base `GoogleAPIError` (covers both `GoogleAPICallError` and
|
||||||
|
`RetryError`) at the `read_secret` boundary. Re-ran: clean degrade — app layers
|
||||||
|
recorded `scanner_error`, the `flotilla` layer still scanned. This is
|
||||||
|
load-bearing for an unattended runner.
|
||||||
|
|
||||||
|
### Arc 3 — Slice 2: container + provisioning artifacts
|
||||||
|
|
||||||
|
`runner/Dockerfile` (osv-scanner binary copied from the pinned ghcr image +
|
||||||
|
`pip install .`), `runner/entrypoint.sh` (ephemeral record bootstrap → audit),
|
||||||
|
`runner/cloudbuild.yaml`, `scripts/patchwatch-runner-deploy.sh`.
|
||||||
|
|
||||||
|
The container run surfaced the **second bug**: this was flotilla's first real
|
||||||
|
**wheel** install, and `__version__` read VERSION via a repo-root-relative path
|
||||||
|
that exists for source/editable runs but not in site-packages → the installed
|
||||||
|
CLI crashed on import. Fixed to read the repo-root VERSION when present (live,
|
||||||
|
for dev) and fall back to the installed distribution metadata.
|
||||||
|
|
||||||
|
Re-ran the container: clean degrade (no GCP creds locally), the `flotilla` layer
|
||||||
|
scanned via the in-container osv-scanner (4 findings), and `--fail-on-scanner-error`
|
||||||
|
correctly exited non-zero on the blind app layers. Bumped VERSION/pyproject to
|
||||||
|
1.7.0, wrote the CHANGELOG, committed on `release/v1.7.0`, merged `--no-ff` to
|
||||||
|
`main`, tagged + pushed (via the SSH remote URL — the HTTPS origin's osxkeychain
|
||||||
|
helper can't unlock non-interactively).
|
||||||
|
|
||||||
|
### Arc 4 — Slice 3: provisioning (blocked on re-auth, then live)
|
||||||
|
|
||||||
|
Both the gcloud account token AND ADC needed interactive re-auth (expired during
|
||||||
|
the long session) — surfaced to the operator, who re-authed (`gcloud auth login`).
|
||||||
|
Then ran `scripts/patchwatch-runner-deploy.sh`. Real-world friction, each fixed
|
||||||
|
in-script (→ v1.7.1):
|
||||||
|
1. `gcloud builds submit` → `PERMISSION_DENIED` (account lacks Cloud Build).
|
||||||
|
Pivoted to a LOCAL `docker build --platform linux/amd64 --provenance=false` +
|
||||||
|
push (the `--provenance=false` matters — a buildx attestation manifest list
|
||||||
|
trips Cloud Run's single-image expectation), then `--skip-build`.
|
||||||
|
2. `--set-env-vars PATCHWATCH_FAIL_ON_LANE=fast,mitigation` — the comma parsed
|
||||||
|
as a second env-var pair; fixed with gcloud's `^@^` alternate-delimiter.
|
||||||
|
3. SA-creation propagation lag (binding ran before the SA was visible) — the
|
||||||
|
idempotent re-run cleared it.
|
||||||
|
4. The `beta`/`alpha` gcloud components weren't installed (non-interactive
|
||||||
|
prompt) — installed them.
|
||||||
|
5. The monitoring channel-list filter rejected the unquoted email as ambiguous —
|
||||||
|
quoted it.
|
||||||
|
|
||||||
|
Set `--max-retries 0` (a `--fail-on` exit is deterministic; the 6h schedule is
|
||||||
|
the retry cadence). Final idempotent re-run exited 0, no errors.
|
||||||
|
|
||||||
|
**Verified end-to-end.** A manual execution produced a full JSON report:
|
||||||
|
`pinned_version 0.31.3` (the SA resolved the private pin + lockfiles),
|
||||||
|
`scanner_errors: []`, `lane_counts fast=1 routine=7 mitigation=0`, and
|
||||||
|
`Container called exit(1)` — the live tqdm HIGH fast finding tripping
|
||||||
|
`--fail-on-lane fast`. Triggering the **scheduler** manually created a fresh
|
||||||
|
execution (proving the scheduler→job `run.invoker` auth path) that reached
|
||||||
|
terminal `failedCount=1` — the full chain through to the alert policy.
|
||||||
|
Least-privilege confirmed: the runner SA has **zero** project-wide roles, only
|
||||||
|
`secretAccessor` on the one secret + `run.invoker` on the one job.
|
||||||
|
|
||||||
|
### Arc 5 — Parallel-session SPEC collision (the wrong turn)
|
||||||
|
|
||||||
|
Committing v1.7.1, `git add -A` swept in an ~80-line `SPEC.md` addition (a §19.2
|
||||||
|
"per-PR preview environments" candidate) that a **parallel session** had written
|
||||||
|
into the shared checkout — not my work. Traced it (absent in v1.6.0 and my
|
||||||
|
v1.7.0 commit; present only in the working tree). A `git reset` then compounded
|
||||||
|
it: I reset to the stale remote-tracking ref `origin/main` (still at 70ba3b0,
|
||||||
|
because I'd pushed via the explicit SSH URL, which doesn't advance the tracking
|
||||||
|
ref) and rewound past v1.7.0 too. Nothing was lost (`--mixed` keeps the tree).
|
||||||
|
Recovered by resetting to the `v1.7.0` tag, re-committing v1.7.1 with **only my
|
||||||
|
five files** (SPEC.md left untouched, foreign content preserved uncommitted for
|
||||||
|
its owner), pushing via SSH, and manually syncing the tracking ref. This is the
|
||||||
|
[[feedback_worktree_for_parallel_git]] lesson realized — I worked in the shared
|
||||||
|
checkout rather than an isolated worktree; the SPEC collision is exactly what
|
||||||
|
that rule guards against.
|
||||||
|
|
||||||
|
### Arc 6 — Close-out
|
||||||
|
|
||||||
|
Verified the cloud resources + least-privilege. Updated
|
||||||
|
[[project_patchwatch_strategy]] memory (Phase 1 LIVE). Deliberately did NOT edit
|
||||||
|
the ohm-rfc ROADMAP #43 row — that checkout is parked on another session's
|
||||||
|
`roadmap/43-patchwatch` branch, and after the SPEC collision the disciplined
|
||||||
|
call was to leave it untouched and flag the annotation in the handoff.
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## Cut state (end of session)
|
||||||
|
|
||||||
|
| Repo / resource | State |
|
||||||
|
| --- | --- |
|
||||||
|
| flotilla `main` | `5cf5ecd` (Merge v1.7.1); tags `v1.7.0`, `v1.7.1` pushed |
|
||||||
|
| flotilla working tree | ONE uncommitted change: a parallel session's `SPEC.md` §19.2 "preview environments" addition (~80 lines at line 1501) — left for its owner |
|
||||||
|
| Cloud Run job | `patchwatch-radar` (us-central1), SA `patchwatch-runner@`, image `…/patchwatch/radar:1.7.0`, `--max-retries 0`, env `PATCHWATCH_FAIL_ON_LANE=fast,mitigation` |
|
||||||
|
| Cloud Scheduler | `patchwatch-radar-6h`, `0 */6 * * *`, ENABLED |
|
||||||
|
| Runner SA | `patchwatch-runner@wiggleverse-ohm` — ZERO project roles; `secretAccessor` on `ohm-rfc-app-gitea-read-token` + `run.invoker` on the job |
|
||||||
|
| Monitoring | email channel → ben@wiggleverse.org; alert policy "Patchwatch radar job failure (OHM)" (open incident: the tqdm fast finding) |
|
||||||
|
| OHM live | untouched (read-only session; no rfc-app deploy) |
|
||||||
|
| ohm-rfc | untouched; checkout parked on `roadmap/43-patchwatch` (clean) |
|
||||||
|
|
||||||
|
| #43 Patchwatch ledger | Status |
|
||||||
|
| --- | --- |
|
||||||
|
| Phase 1 — radar read-only + alert | ✅ detection logic (≤0052) + **always-on cloud runner (this session)** |
|
||||||
|
| Phase 2 — OS layer (`unattended-upgrades` + reboot handling) | ⏸ unblocked, not started |
|
||||||
|
| Phase 3 — mitigation lane (rfc-app kill-switches) | ⏸ needs rfc-app coordination |
|
||||||
|
| Phase 5 — tiered auto-initiate | ⛔ depends on Track Δ existing |
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## §19.2 candidates surfaced
|
||||||
|
|
||||||
|
1. **`flotilla-core` extraction** — unchanged from the proposal; the cloud
|
||||||
|
runner is the first piece of flotilla that runs off-laptop. The runner image
|
||||||
|
+ entrypoint + provisioning script are OHM-specific glue today; the generic
|
||||||
|
radar/classifier belongs in `flotilla-core` when a second product needs it.
|
||||||
|
2. **Alert de-duplication / acknowledgement.** The runner pages on every open
|
||||||
|
fast/mitigation finding; while a known finding is blocked (tqdm on Track Δ),
|
||||||
|
Monitoring's incident grouping mutes the spam, but there's no first-class
|
||||||
|
"acknowledge this finding until version X" affordance. Worth it once there
|
||||||
|
are several standing findings.
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## What lands on the operator's plate
|
||||||
|
|
||||||
|
1. **The parallel-session `SPEC.md` change** is sitting uncommitted in the
|
||||||
|
flotilla working tree (a §19.2 "preview environments" candidate). It's not
|
||||||
|
mine — its owning session (or you) should commit or discard it. I left it
|
||||||
|
exactly as found.
|
||||||
|
2. **ohm-rfc ROADMAP #43** wants a "Phase 1 + cloud runner DONE (flotilla
|
||||||
|
v1.7.0/v1.7.1)" annotation. I didn't touch ohm-rfc (parked on another
|
||||||
|
session's branch). Apply it on whichever branch owns #43.
|
||||||
|
3. **Recurring alert decision.** The radar will keep an open Monitoring incident
|
||||||
|
while the tqdm fast bump is blocked on Track Δ. If the email is unwelcome,
|
||||||
|
redeploy the job with `PATCHWATCH_FAIL_ON_LANE=mitigation` (the fast finding
|
||||||
|
stays visible in the JSON logs). No action strictly required.
|
||||||
|
4. **Optional:** re-auth ADC (`gcloud auth application-default login`) if you
|
||||||
|
want to run `flotilla audit` from the laptop again — the cloud runner doesn't
|
||||||
|
need it (it uses its SA).
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## Prompt the operator can paste into the next Claude Code session
|
||||||
|
|
||||||
|
```
|
||||||
|
You are picking up after session 0053. Reserve your own session ID via
|
||||||
|
claim-session-id.sh before any work.
|
||||||
|
|
||||||
|
STATE (all pushed):
|
||||||
|
- flotilla main = 5cf5ecd (v1.7.1). Tags v1.7.0 + v1.7.1 pushed.
|
||||||
|
- Patchwatch Phase 1 cloud runner is LIVE in wiggleverse-ohm and verified
|
||||||
|
end-to-end: Cloud Scheduler `patchwatch-radar-6h` (every 6h) → Cloud Run job
|
||||||
|
`patchwatch-radar` runs `flotilla audit ohm-rfc-app --layer py-app --layer
|
||||||
|
node-app --layer flotilla --fail-on-lane fast --fail-on-lane mitigation
|
||||||
|
--fail-on-scanner-error --json`. Runtime SA `patchwatch-runner@` is
|
||||||
|
least-privilege (secretAccessor on ohm-rfc-app-gitea-read-token + run.invoker
|
||||||
|
on the job; zero project roles). Failures → email alert + JSON in Cloud
|
||||||
|
Logging. v1.7.0 = the gates + image + script; v1.7.1 = provisioning-script
|
||||||
|
fixes found live. Reprovision: scripts/patchwatch-runner-deploy.sh (idempotent;
|
||||||
|
builds via LOCAL docker — the account lacks Cloud Build perms).
|
||||||
|
- The runner exits non-zero every cycle on the live tqdm HIGH fast finding
|
||||||
|
(blocked on Track Δ); Monitoring groups it into ONE open incident. To mute:
|
||||||
|
redeploy the job with PATCHWATCH_FAIL_ON_LANE=mitigation.
|
||||||
|
|
||||||
|
PLATE FROM 0053:
|
||||||
|
- flotilla working tree has ONE uncommitted change that is NOT 0053's: a
|
||||||
|
parallel session's SPEC.md §19.2 "per-PR preview environments" addition
|
||||||
|
(~line 1501). Leave it for its owner / commit-or-discard deliberately.
|
||||||
|
- ohm-rfc ROADMAP #43 wants a "Phase 1 + cloud runner DONE (v1.7.0/v1.7.1)"
|
||||||
|
annotation; ohm-rfc is parked on branch roadmap/43-patchwatch.
|
||||||
|
|
||||||
|
NEXT MOVES (Patchwatch, all independent of the off-limits Phase 5 auto-initiate):
|
||||||
|
1. Phase 2 — OS layer: unattended-upgrades (security pocket) on the VM + the
|
||||||
|
reboot-required the radar flags (linux-image). Touches the live VM (a reboot
|
||||||
|
= brief ohm.wiggleverse.org outage — confirm timing with the operator).
|
||||||
|
2. tqdm fast-lane bump still owed but rides Track Δ (#37-#42); needs a fixed
|
||||||
|
rfc-app tag first.
|
||||||
|
3. Phase 3 — mitigation lane: needs rfc-app kill-switch flags (framework
|
||||||
|
coordination).
|
||||||
|
|
||||||
|
Run form (osv on PATH + pinned gcloud config; needs ADC re-auth for laptop runs):
|
||||||
|
PATH="/opt/homebrew/bin:$PATH" CLOUDSDK_ACTIVE_CONFIG_NAME=wiggleverse \
|
||||||
|
.venv/bin/ohm-rfc-app-flotilla audit ohm-rfc-app
|
||||||
|
|
||||||
|
LESSON: do hands-on git in an isolated worktree when other sessions may share
|
||||||
|
the checkout — 0053 hit a parallel-session SPEC.md collision in the shared tree.
|
||||||
|
```
|
||||||
@@ -1,50 +0,0 @@
|
|||||||
# Session 0053.0 — Transcript
|
|
||||||
|
|
||||||
> Date: 2026-05-31
|
|
||||||
> Start: 2026-05-31T20-53 (PST implied)
|
|
||||||
> Status: **PLACEHOLDER — claimed at session start; finalized at session end.**
|
|
||||||
>
|
|
||||||
> This file reserves session ID 0053. The driver replaces this body
|
|
||||||
> with the full transcript before publishing, and renames the file to
|
|
||||||
> its final SESSION-0053.0-TRANSCRIPT-2026-05-31T20-53--<end>.md form.
|
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
## Launch prompt
|
|
||||||
|
|
||||||
```
|
|
||||||
You are picking up after session 0052. Reserve your own session ID via
|
|
||||||
claim-session-id.sh before any work.
|
|
||||||
STATE (all pushed):
|
|
||||||
- flotilla main = 70ba3b0 (v1.6.0): authenticated Gitea reads. Tags v1.5.0
|
|
||||||
(backfilled), v1.5.1, v1.6.0 all pushed.
|
|
||||||
- v1.5.1 fixed the `flotilla` audit self-scan layer (now scans the resolved
|
|
||||||
installed env via importlib.metadata — surfaces real pip advisories).
|
|
||||||
- v1.6.0 added the `gitea_read_secret_ref` deployment-record field (migration
|
|
||||||
008) + token-auth on every Gitea raw read (pin/deploy/plan/audit), because
|
|
||||||
the OHM org Gitea repos were made PRIVATE on 2026-05-31 (intentional) and
|
|
||||||
every anonymous read started 404ing.
|
|
||||||
BLOCKER: RESOLVED in session 0052.
|
|
||||||
- The deployment record points at wiggleverse-ohm/ohm-rfc-app-gitea-read-token —
|
|
||||||
a DEDICATED read token (NOT ohm-bot, which lacks access to the ben.stull/*
|
|
||||||
personal-namespace repos). Its identity reads both ben.stull/ohm-rfc (pin) and
|
|
||||||
ben.stull/rfc-app (lockfiles). `pin check` resolves 0.31.3; full `audit` runs
|
|
||||||
clean (9 findings, 0 scanner_errors). Nothing to do here — radar is live.
|
|
||||||
Run form (osv on PATH + pinned gcloud config):
|
|
||||||
PATH="/opt/homebrew/bin:$PATH" CLOUDSDK_ACTIVE_CONFIG_NAME=wiggleverse \
|
|
||||||
.venv/bin/ohm-rfc-app-flotilla audit ohm-rfc-app
|
|
||||||
NEXT MOVES:
|
|
||||||
1. tqdm RCE is live in the pin: py-app/tqdm 4.9.0 has a HIGH RCE
|
|
||||||
(GHSA-r7q7-xcjw-qx8q, fixed 4.11.2) — fast-lane pin-bump candidate, but needs
|
|
||||||
a fixed rfc-app tag to bump to first; the bump rides Track Δ (#37-#42), not
|
|
||||||
the audit verb. (Also live: py-app/idna 3.9.0→3.15, medium.)
|
|
||||||
2. Patchwatch Phase 2: OS unattended-upgrades (security pocket) on the VM +
|
|
||||||
the reboot-required the radar flagged (linux-image-6.1.0-49). Independent
|
|
||||||
of Track Δ.
|
|
||||||
3. Patchwatch cloud runner (proposal §6): Cloud Scheduler → read-only Cloud Run
|
|
||||||
job running `flotilla audit … --json --fail-on`. Now unblocked — the runner's
|
|
||||||
identity will need Secret Manager access to ohm-rfc-app-gitea-read-token (the
|
|
||||||
token approach is proven end-to-end).
|
|
||||||
Do NOT build the auto-initiate tier (Phase 5) — depends on Track Δ existing.
|
|
||||||
|
|
||||||
```
|
|
||||||
Reference in New Issue
Block a user