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

203 lines
9.7 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
# 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
- [x] Claim session ID (→ 0033), read SESSION-PROTOCOL §7 + ROADMAP.
- [x] Reconcile stale brief state vs reality (0032 finished; v0.28.0 shipped).
- [x] Explore the #28 surfaces (scanner, propose flow, inbox, invite, roles, Haiku).
- [x] Isolated rfc-app worktree + venv off main; baseline tests green.
- [x] Part 2 — create-RFC offers (scanner candidate bucket + propose pre-fill + gating).
- [x] Part 3 — contribute-to-pending (scanner pending bucket + request flow + inbox actions + accept→invite + decline).
- [x] Tests (9 new), full backend suite, frontend build.
- [x] CHANGELOG + VERSION + frontend mirror.
- [x] Commit → PR #3 → FF-merge → tag v0.29.0 → push origin + benstull.
- [x] ohm-rfc pin bump → deploy → verify live.
- [x] ROADMAP #28 row struck through; worktree cleaned up.
- [x] 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.py`** — `fan_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/health``version=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.