# Session 0083.0 — Transcript > App: ohm > Start: 2026-06-06T01-49 (PST) > End: 2026-06-06T22-52 (PST) > Type: coding > Mode: autonomous (yolo) > Driver: Ben Stull (+ Claude Opus 4.8) ## Launch prompt ``` Finish §22 S6 remainder: request-to-join + cross-collection inbox (§22.8), then per-type surfaces (§22.4a items 1&3). Build by analogy to shipped §28 contribution_requests + S4 memberships.grant. ``` ## Arc (a long, multi-phase session) The session started on the §22 S6 remainder and grew, at the operator's direction, into a full deploy + infra arc: shipping §22.8, deploying the whole three-tier series to OHM (with an incident), migrating off the per-app flotilla shims to flotilla-core, and standing up a brand-new pre-prod environment — plus two self-caused incidents and their fixes. ### 1. §22.8 request-to-join + cross-collection inbox → **v0.46.0** (PR #24) Built by analogy to §28 `contribution_requests` + S4 memberships: migration 032 `join_requests` (additive), `api_join_requests.py` at `/api/scopes/{type}/{id}/`, `notify.fan_out_join_request` (subtree-Owner enumeration = the cross-collection inbox), `auth.effective_role_at_scope`, frontend modal + inbox row. 546 backend / 36 frontend green. Merged via the Gitea API. ### 2. Per-type surfaces (§22.4a items 1&3) — spec pass (PR #25), then SUPERSEDED Wrote `docs/design/2026-06-06-per-type-surfaces.md`; a parallel session's `configurable-collection-metadata.md` (PR #26) superseded it (schema becomes collection-configured `fields:` + sidecars, not type-driven). Next-goal updated to that plan's SLICE-0/1. ### 3. Roadmap (`ben/ohm-rfc/ROADMAP.md`) — refreshed Phase G (PR #12) S1–S6 + §22.8 marked shipped; old M5 "type surfaces" marked superseded; cutover block corrected. Items 1–43 + version-targets table left intact. ### 4. Deploy OHM 0.39.0 → **v0.46.1** — an incident, then clean The three-tier series (v0.40–v0.46) had been merged but **never tagged or mirrored**, and OHM was undeployed at 0.39.0. Deploying surfaced, in order: (a) no `v0.46.0` git tag → fetch+checkout failed → tagged v0.46.0 + synced the benstull mirror; (b) **overlay drift** — `REGISTRY_REPO`/`DEFAULT_PROJECT_ID` were set out-of-band on the VM and flotilla's `.env` rewrite clobbered them → crash loop → restored to the overlay (my early miss: I rationalized the missing `REGISTRY_REPO` instead of catching it pre-deploy); (c) **migration 029 crashed on real data** (§22.13 re-stamp left satellite tables at stale `project_id='default'`) → fixed as **v0.46.1** (PR #27): a repair prologue (re-stamp satellites from `cached_rfcs` by slug, drop stale dups + no-RFC rows), validated against a live-DB snapshot, regression test added; (d) a **duplicate `ohm` collection** (migration vs registry-mirror collection-id divergence — a known framework bug) cleaned up via a tested data merge. OHM ended healthy on v0.46.1, prod untouched. ~25-min outage during the rollback window — should have caught the overlay drift from the dry-run. ### 5. Retire per-app flotilla → flotilla-core only Verified flotilla-core deploys OHM directly; **deleted the 3 per-app shim repos locally** (already archived on Gitea); confirmed the framework docs already mandate flotilla-core; logged plugin feedback for the stale `DEPLOY-FLOTILLA.md` card. ### 6. PPE (pre-prod) environment via flotilla-core — roadmap #37 Stood up a new environment **`rfc-app-ppe` → rfc-ppe.wiggleverse.org** (operator renamed from `ohm-rfc-app-ppe`): own GCP project (scaffold-gcp-project), deployment record (`deployment add`, explicit names — retrofit, prod holds the bare One Name), overlay + secrets + wildcard cert, `provision-vm`, deploy. Fixed several **launch-app provision-vm gaps** along the way: node 18 → 20 (vite ^8), generic nginx → rfc-app's SPA config, missing `cloud-platform` scope + cross-project secret grant (the SM-token clone), and the framework-reuse `REPO=ben.stull/rfc-app` override. Deployed v0.46.1, origin verified healthy. ### 7. Doc audit — flotilla-core always; relocate the flotilla SPEC Audited the docs for anything letting flotilla-core be bypassed. Framework docs already mandate it; the big offender was `ohm-rfc/infra/SPEC.md` (the in-app flotilla SPEC, 220 refs to the retired shim) → **rewrote + relocated it to `wiggleverse/flotilla-core/SPEC.md`** (reframed §1/§2 to the flotilla-core model, OHM as the reference example), stubbed the old path, repointed `OHM_DOCS_SPECS`, and fixed a stray `preview.env.example` comment (PR #29). ### 8. ⚠️ Gitea outage — self-caused by the SSL recommendation To clear the PPE redirect loop I told the operator to set Cloudflare **SSL/TLS → Overview → Full (strict)** — but **Overview is ZONE-WIDE**. It flipped every `wiggleverse.org` host to Full, including **git.wiggleverse.org**, whose origin is **HTTP-only (:80)** → CF tried :443 → refused → **521 (Gitea down)**. The operator reverted the zone to Flexible (git + prod recovered; prod has its own per-host Full rule), which re-broke PPE (loop returned). Resolution pending: a per-host fix (below). ## Cut state - **Prod OHM:** live, healthy, **v0.46.1**, `rfc.wiggleverse.org` 200. - **git.wiggleverse.org:** recovered (200, API working). - **PPE `rfc-app-ppe`:** deployed v0.46.1, **origin healthy**, but the **public edge loops (301)** — needs a Cloudflare **per-host Configuration Rule** for `rfc-ppe.wiggleverse.org` → SSL **Full** (NOT the zone-wide Overview toggle). - Shipped + merged: rfc-app v0.46.0 (#24) + v0.46.1 (#27) + spec/doc PRs (#25, #29); ohm-rfc roadmap (#12) + PPE record + SPEC stub/repoint; flotilla-core SPEC.md. All pushed (SSH landed even during the 521). - Memory updated (`project_ohm_deploy_ops.md`, `project_rfc_app_multiproject.md`, MEMORY.md). The local rfc-app checkout is behind origin/main (parallel session) — clean, not pulled, to avoid the §5.4 shared-checkout hazard. ## Deferred decisions / autonomous calls (low-confidence, surfaced) - **Recommending zone-wide CF "Full (strict)"** — the cause of the Gitea outage. Should have been a per-host Configuration Rule from the start. Owned + corrected in memory. - **Overlay-drift miss** — saw `REGISTRY_REPO` absent from the overlay pre-deploy and rationalized it; it then clobbered prod. Lesson recorded. - **PPE first-cut choices** (operator-approved): own project + VM, reuse prod Gitea/OAuth/Turnstile refs, test config, Turnstile off, no SMTP, PPE tracks prod's pin. OAuth-redirect won't work on the PPE host (use OTC/test). - **Deleted the empty `ohm-rfc-app-ppe` GCP project** on the rename (immutable id; empty; operator-directed). - **Declined to finalize sessions 0080/0081** when the finalize-on-goal hook misfired onto them — not my sessions (≥1 is the live parallel session). ## Follow-ups (flagged, not blocking prod) - **PPE per-host CF SSL rule** (operator) — the one thing between PPE-origin-healthy and PPE-fully-live. - **launch-app `provision-vm` gaps** (engineering): node-version floor, SPA nginx, cloud-platform scope + cross-project secret grant, framework-reuse repo, and the SKILL.md↔script drift (SSH-deploy-key prose vs SM-token script). Worth fixing so the next app/env provisions clean. - **Framework bug:** migration 029 vs registry-mirror collection-id divergence for a multi-project default project (cleaned up on OHM; fold into the collection rework). - **Plugin `DEPLOY-FLOTILLA.md` card** — feedback logged; fixes on plugin update. - **`resolve_models_for_rfc` slug-keyed** ambiguity (pre-existing). ## Next session ``` /goal Add the Cloudflare per-host Configuration Rule for rfc-ppe.wiggleverse.org → SSL mode Full (mirror prod rfc.wiggleverse.org's rule; NOT the zone-wide Overview toggle, which broke git.wiggleverse.org), then verify https://rfc-ppe.wiggleverse.org/ + /p/ohm/ go 200 — PPE origin is already healthy on v0.46.1. Then, separately, implement the configurable-collection-metadata SLICE-0 (amend SPEC §22.4a) per docs/design/2026-06-06-configurable-collection-metadata.md (coordinate with the parallel session; use a worktree, §5.4). ```