203 lines
9.7 KiB
Markdown
203 lines
9.7 KiB
Markdown
# 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.
|