Files
session-history/ohm/0033/SESSION-0033.0-TRANSCRIPT-2026-05-28T19-44--2026-05-28T20-14.md

9.7 KiB
Raw Permalink Blame History

Session 0033.0 — Transcript

Date: 2026-05-28 Start: 2026-05-28T19-44 (PST implied) · End: 2026-05-28T20-14 Goal: Advance the OHM roadmap by one disjoint item, parallel-safe. Picked the recommended item: #28 Parts 2 + 3 — offer-to-create-an-RFC for strong-candidate terms, and offer-to-contribute-to-a-pending-RFC.

Outcome: rfc-app v0.29.0 shipped + deployed + verified live on ohm.wiggleverse.org (deploys.id=40). All three #28 parts are now live. One additive migration (024, contribution_requests); no config / overlay / secret / nginx / systemd change. 374 backend tests green (9 new); frontend builds clean. Merged as PR #3 (8a94e26), tagged v0.29.0, pushed origin + benstull mirror; ohm-rfc pin 0.28.0 → 0.29.0; ROADMAP #28 row struck through (all three parts shipped).


Launch prompt

OHM roadmap driver session, parallel-safe. Claim ID first; read SESSION-PROTOCOL §7 + ohm-rfc/ROADMAP.md. State at hand-off (end of 0031): OHM at v0.27.0; flotilla v1.2.0 merged+tagged. Recommended item: #28 Parts 2 + 3 → target v0.28.0 (possibly split). Avoid conflicting with session 0032 (then running) and v0.27.0's fresh security surfaces. Hard rules: never ask for secret bytes; fresh worktree+venv for rfc-app builds; coordinate the serialized deploy lock + version slot; FF-merge via gitea API; finalize+publish transcript LAST, handoff prompt before publish.


Plan / TODO

  • Claim session ID (→ 0033), read SESSION-PROTOCOL §7 + ROADMAP.
  • Reconcile stale brief state vs reality (0032 finished; v0.28.0 shipped).
  • Explore the #28 surfaces (scanner, propose flow, inbox, invite, roles, Haiku).
  • Isolated rfc-app worktree + venv off main; baseline tests green.
  • Part 2 — create-RFC offers (scanner candidate bucket + propose pre-fill + gating).
  • Part 3 — contribute-to-pending (scanner pending bucket + request flow + inbox actions + accept→invite + decline).
  • Tests (9 new), full backend suite, frontend build.
  • CHANGELOG + VERSION + frontend mirror.
  • Commit → PR #3 → FF-merge → tag v0.29.0 → push origin + benstull.
  • ohm-rfc pin bump → deploy → verify live.
  • ROADMAP #28 row struck through; worktree cleaned up.
  • Finalize + publish transcript (this file).

Pre-session state vs. reality (the brief was stale)

The launch brief said OHM was live at v0.27.0 and that session 0032 was actively running; it also implied v0.28.0 was un-tagged/un-deployed. By session start the picture had moved:

  • 0032 had finished (transcript …18-52--19-13). Its work: IAP-only SSH hardening, flotilla v1.2.0 re-verify, orphaned-db cleanup, and rfc-app v0.28.0 (audit I3 HTML-email guard + I4 async Turnstile) opened as PR #2. The only --INPROGRESS placeholders left were stale 0026 / 0027 (their security work already shipped as v0.27.0 — the brief said to ignore them).
  • The operator had since merged, tagged, AND deployed v0.28.0: live /api/health returned version=0.28.0, the ohm-rfc pin was 0.28.0, and tag v0.28.0 existed on main. This removed the version-slot ambiguity the brief worried about — there was no un-tagged predecessor to reconcile, so this session simply took the next slot, v0.29.0.

Claimed session 0033 via claim-session-id.sh --start 2026-05-28T19-44 (push to ohm-session-history is the atomic claim).


Scope decisions (documented in code, CHANGELOG, and ROADMAP)

Two interpretive calls shaped the build; both were made to match Part 1's conservative, false-positive-averse philosophy and were written into the code docstrings so they aren't re-litigated later:

  1. "Pending RFC" = a super-draft (cached_rfcs.state='super-draft'), not a pre-merge idea PR. A super-draft is in cached_rfcs (so the #12 rfc_invitations FK the accept path reuses resolves), is owned (owners_json — routes the request, names the owner), and has a contribution surface to open. Pre-merge idea PRs satisfy none of those cleanly, so they're deliberately out of scope — a documented future extension.
  2. Part 2 candidate heuristic = multi-word #27-taxonomy tags with no defining RFC. Multi-word is the same guard Part 1 uses for titles; a single common tag word (identity) would turn every prose occurrence into an affordance. The roadmap sanctions "a heuristic OR the Haiku path"; the cheap deterministic tag heuristic was chosen, with capitalized-phrase mining / repeated-term detection / the #27 Haiku (ANTHROPIC_API_KEY) pathway noted as sanctioned-but-deferred extensions (mirroring how Part 1 deferred the curated canonical-terms list).

Turn-by-turn arc

Arc 1 — Claim + orient

Claimed 0033. Read SESSION-PROTOCOL §7, ROADMAP (#28 detail + operating instructions), and 0032's transcript. Confirmed live OHM = v0.28.0, pin = 0.28.0, deploy lock free, no competing active sessions.

Arc 2 — Explore (two parallel Explore agents)

Mapped the surfaces #28 Parts 2+3 touch: the role model (require_contributor gates propose; permission_state='granted' is "has create rights"); the RFC lifecycle (idea-PR-open → super-draft → active); the notification / §15 inbox system (_emit_one chokepoint, render_summary, kinds, the recipient-scoped inbox); and the #12 owner-invite flow (rfc_invitations

  • rfc_collaborators, accept writes the membership row). Verified migrations top out at 023 → 024 free.

Arc 3 — Backend build (isolated worktree + venv)

Took a git worktree off main on branch feature/v0.29.0-pr-rfc-create-contribute with its own .venv; baseline 63 tests green. Then:

  • rfc_links.py rewritten to a three-bucket scanner (Term namedtuple
    • kind ∈ active/pending/candidate; precedence active > pending > candidate then longest-match-first). Kept backward-compat with the legacy (key, slug, title) 3-tuple so all Part 1 unit tests pass untouched. build_index now also gathers super-draft terms (with resolved owner display) and candidate tags.
  • notify.pyfan_out_contribution_request (one actionable notification per owner) + notify_contribution_decided; three new render_summary branches; the inbox list item now carries extras (recipient-scoped, so safe) for inline who/why/use-case.
  • api_invitations.py — extracted the invite issue path into one reusable issue_invitation(...) chokepoint shared by the manual endpoint and Part 3's accept.
  • api_contributions.py (new) — the GET target + request + accept + decline endpoints; accept fires issue_invitation (role contributor), reusing an existing pending invite if one exists.
  • migration 024 — additive contribution_requests table (partial unique index = one open request per (RFC, user)).
  • Registered the new router in api.py.

Arc 4 — Frontend build

LinkedText.jsx renders the two new segment kinds as query-param-routed affordances (no prop-threading from deep in comment lists): rfc-candidate?propose=<term> (gated on create rights), rfc-pending?contribute= <slug>&term=<term> (gated on signed-in). App.jsx reads the params and opens ProposeModal (new initialTitle) / the new ContributeRequestForm (3-field). Inbox.jsx gained a ContributionRequestRow — the first actionable inbox kind — showing who/why/use-case with Accept/Decline. api.js + CSS additions. viewer/canCreate threaded into the three LinkedText call sites (PRView ×2, RFCDiscussionPanel). Frontend builds clean.

Arc 5 — Tests

3 scanner-bucket unit tests + 6 end-to-end (PR-view segment surfacing; request→accept→invite→notify; decline; owner-cannot-self-request; active-RFC-rejected; eligibility). Full backend suite 374 passing.

Arc 6 — Release + deploy

VERSION + frontend mirror → 0.29.0; CHANGELOG entry with RFC-2119 upgrade steps. Committed; pushed branch; opened PR #3 via gitea API; FF-merged (8a94e26); tagged v0.29.0; pushed tag + main to origin and the benstull mirror (the VM fetches rfc-app from the mirror — tag must be there before deploy). Bumped ohm-rfc pin 0.28.0 → 0.29.0, pushed. Ran flotilla deploy ohm-rfc-app — all 9 steps OK, deploys.id=40, verify 4.6s. Live checks: /api/health = 0.29.0; the new /api/rfcs/{slug}/contribution-target route returns the handler's {"detail":"RFC not found"} (route wired); GET /api/rfcs still 200.

Arc 7 — Record + cleanup

ROADMAP #28 row struck through (all three parts shipped, with the deploys.id=40 + v0.29.0 link + the scope decisions); committed + pushed to ohm-rfc. Worktree removed; shared /Users/benstull/git/rfc-app checkout fast-forwarded to the merge.


Friction / notes

  • The brief's pre-state was stale (OHM was already on 0.28.0, 0032 done). Verifying live state + tags first — rather than trusting the brief — avoided a phantom version-slot reconciliation.
  • No secret bytes were needed or requested (this release adds no secret/ config). Hard rule held trivially.
  • issue_invitation extraction is a small §19.2-style consolidation: the manual invite endpoint and the new accept path now share one chokepoint, so the dup-guard / token / email stay identical.

Cut state (end of session)

  • OHM live: https://ohm.wiggleverse.org/api/healthversion=0.29.0, status=ok. Deploy lock free.
  • rfc-app: main = 8a94e26 (PR #3 merge); tag v0.29.0 on origin + benstull. 374 backend tests green.
  • ohm-rfc: pin .rfc-app-version = 0.29.0; ROADMAP #28 struck through. main pushed (62929b2).
  • deploys.id=40 records the v0.29.0 deploy.

Operator-plate (manual gestures, if any)

None. v0.29.0 needed no secret/config/overlay/nginx/systemd change; the additive migration 024 ran automatically during the deploy. Nothing is waiting on the operator.