reshape: move OHM transcripts under ohm/ for org-wide multi-app layout; add org-wide root README
This commit is contained in:
@@ -0,0 +1,316 @@
|
||||
# Session 0029.0 — Transcript
|
||||
|
||||
> Date: 2026-05-28
|
||||
> Goal: Advance the OHM roadmap autonomously as a parallel driver session;
|
||||
> pick one disjoint item that needs no operator input and doesn't collide
|
||||
> with the two in-flight sessions.
|
||||
>
|
||||
> Outcome: **rfc-app v0.26.0 SHIPPED + DEPLOYED — roadmap #28 Part 1
|
||||
> (auto-link accepted RFCs inside PR descriptions + PR/discussion
|
||||
> comments). 363 backend tests green, frontend builds clean. Merged to
|
||||
> main `698821f`, tagged v0.26.0 (origin + benstull), deployed to OHM as
|
||||
> deploys.id=34 — live at ohm.wiggleverse.org/api/health = 0.26.0. The
|
||||
> operator authorized merge + deploy mid-session.**
|
||||
>
|
||||
> Highlights:
|
||||
> - Discovered the only buildable rfc-app feature (#28) and scoped it to
|
||||
> its clean, non-colliding slice (Part 1).
|
||||
> - Deliberate, documented spec deviation: read-time enrichment, not
|
||||
> submit-time (§19.3-rule-2 note).
|
||||
> - Zero migration (a concurrent session already holds migration 023);
|
||||
> XSS-safe structured segments (no `dangerouslySetInnerHTML`).
|
||||
|
||||
---
|
||||
|
||||
## Pre-session state
|
||||
|
||||
- **OHM live**: rfc-app **v0.24.0** on the renamed VM `ohm-rfc-app`
|
||||
(deploys.id stack from Session 0028: v0.22.0→v0.23.0→v0.24.0 landed
|
||||
after the #1 VM-rename blocker cleared). Deploys unblocked, lock free.
|
||||
- **ohm-rfc pin** (`.rfc-app-version`): `0.24.0`.
|
||||
- **flotilla**: v1.2.0 built + pushed as a PR by Session 0028, NOT merged
|
||||
(operator to open/merge/tag).
|
||||
- **Active parallel sessions** at claim time (from `claim-session-id.sh`):
|
||||
**0026** and **0027**, both claimed 2026-05-28T13-46, both `--INPROGRESS`.
|
||||
- **rfc-app working dir** (`/Users/benstull/git/rfc-app`): a **shared**
|
||||
checkout, mid-edit on branch `feature/v0.25.0-security-hardening`
|
||||
(created 14:06 today off main/v0.24.0). Uncommitted, unpushed: OTC
|
||||
verify-lockout, in-process rate limiting (`backend/app/ratelimit.py`),
|
||||
HTML/XSS sanitization (`frontend/src/lib/sanitizeHtml.js` +
|
||||
`MarkdownPreview.jsx` / `ProposalView.jsx` / `Editor.jsx`), and
|
||||
**migration 023** (`023_otc_verify_lockout.sql`). This is one of the
|
||||
0026/0027 sessions' rfc-app side — the v0.25.0 slot is claimed.
|
||||
|
||||
---
|
||||
|
||||
## Turn-by-turn arc
|
||||
|
||||
### Arc 1 — Claim, survey, and the parallel-session hazard
|
||||
|
||||
Claimed session ID **0029** via `claim-session-id.sh --start
|
||||
2026-05-28T15-47` (placeholder pushed at `286e75f`). Read SESSION-PROTOCOL
|
||||
§7; pulled ohm-rfc/ROADMAP.md and read it end to end.
|
||||
|
||||
Surveyed the candidate set from the launch prompt against "what can an
|
||||
autonomous session actually ship tonight without operator input and
|
||||
without colliding with 0026/0027":
|
||||
|
||||
- #21 Part A (Amplitude audit) — time-gated to ~2026-06-04 (needs a week
|
||||
of real data). Not now.
|
||||
- #22 (pro-consent copy) — blocked on operator-drafted + counsel-reviewed
|
||||
text. Not now.
|
||||
- #20 DMARC Phase B — time-gated to ~2026-06-04. #18/#20 ops remainder
|
||||
(stale `wiggleverse/meta` webhook, bounce wiring) is operator/gitea-
|
||||
admin work.
|
||||
- #31b / #25-redesign — blocked on operator screenshots.
|
||||
- #33 / #34 (name alignment) — operator-led, URL-breaking moves.
|
||||
- **#28 (PR cross-references)** — Track B rfc-app feature, deps #3/#7/#12
|
||||
all shipped. The one item buildable with no operator input. Picked.
|
||||
|
||||
Then the hazard surfaced: the real rfc-app checkout
|
||||
(`/Users/benstull/git/rfc-app`) was a **shared working dir mid-edit** on
|
||||
`feature/v0.25.0-security-hardening`. Per the launch prompt's explicit
|
||||
warning ("branches alone do NOT isolate concurrent sessions sharing one
|
||||
working dir — take a manual git worktree with its own venv"), I created
|
||||
an isolated worktree:
|
||||
|
||||
```
|
||||
git worktree add /Users/benstull/git/rfc-app-s0029 \
|
||||
-b feature/v0.26.0-pr-rfc-links main
|
||||
```
|
||||
|
||||
…and never touched the shared checkout again. The v0.25.0 slot being
|
||||
claimed → I target **v0.26.0**.
|
||||
|
||||
### Arc 2 — Scoping #28 to its clean, non-colliding slice
|
||||
|
||||
#28 is explicitly "large, its own session" with three parts. I dispatched
|
||||
one **read-only Explore agent** to map the PR/comment/RFC surfaces (folded
|
||||
into this transcript per §5's driver-fold for read-only helpers — it did
|
||||
no commits and warranted no separate `.1` transcript). Key findings:
|
||||
|
||||
- **PR descriptions and comments render as plain text** (`PRView.jsx:221`
|
||||
description, `:443` PR conversation; `RFCDiscussionPanel.jsx:282`
|
||||
discussion) — **not** through the `MarkdownPreview` surface the
|
||||
security branch is hardening. **Zero frontend file overlap.**
|
||||
- The security branch already created **migration 023**. Decisive signal
|
||||
to make my slice **migration-free** — achievable by enriching at
|
||||
read-time against the live `cached_rfcs` active set rather than
|
||||
persisting links at submit time. That also avoids `main.py` (no new
|
||||
endpoint) and any migration collision.
|
||||
- RFC corpus: `SELECT slug, title, rfc_id FROM cached_rfcs WHERE
|
||||
state='active'`. RFC view route is `/rfc/:slug`. Codebase convention
|
||||
for internal nav inside these components is plain `<a href>` (e.g.
|
||||
`PRView.jsx:190`), not react-router `<Link>`.
|
||||
|
||||
Scoped to **Part 1 only** (auto-link existing accepted RFCs), the
|
||||
roadmap's recommended "easy win first". Parts 2 + 3 deferred.
|
||||
|
||||
### Arc 3 — Implementation (v0.26.0)
|
||||
|
||||
Read-time enrichment, migration-free, XSS-safe structured segments:
|
||||
|
||||
- **`backend/app/rfc_links.py`** (new): `build_index(conn, exclude_slug=)`
|
||||
→ `LinkIndex.segment(text)` → list of `{type:"text"}` /
|
||||
`{type:"rfc", slug, label, title}` segments. Conservative matching to
|
||||
avoid false positives: links only **rfc_id** tokens (`RFC-0001`),
|
||||
**multi-word** titles (whitespace present, e.g. `Open Human Model`), and
|
||||
**hyphenated** slugs (e.g. `open-human-model`). A single common-word
|
||||
title/slug (a hypothetical RFC titled "Human") is **not** linked — that
|
||||
would turn every prose "human" into a link; the roadmap's "curated
|
||||
canonical-terms list" stays an explicit future opt-in. Case-insensitive,
|
||||
word-boundary-anchored, longest-match-wins, self-reference suppressed
|
||||
via `exclude_slug`.
|
||||
- **`api_prs.py`** `get_pr()`: builds the index once (exclude current
|
||||
slug), adds `description_segments` and per-comment `text_segments`.
|
||||
- **`api_discussion.py`** `get_discussion_thread_messages()`: per-comment
|
||||
`text_segments`.
|
||||
- **`frontend/src/components/LinkedText.jsx`** (new): maps segments onto
|
||||
React text nodes + `<a class="rfc-autolink">`. No
|
||||
`dangerouslySetInnerHTML` → XSS-safe by construction, independent of the
|
||||
security branch's `sanitizeHtml.js`. Falls back to raw `text` when
|
||||
segments are absent (older cached responses).
|
||||
- Wired into `PRView.jsx` (description + PR conversation bodies) and
|
||||
`RFCDiscussionPanel.jsx` (discussion bodies). `App.css`: a tokenized
|
||||
`.rfc-autolink` rule (accent + dotted underline).
|
||||
- `VERSION` → `0.26.0`; `frontend/package.json` → `0.26.0` (the
|
||||
package-lock version field is stale at 0.21.0 across recent releases —
|
||||
left as-is to match convention).
|
||||
|
||||
**Deliberate spec deviation** (recorded per §19.3-rule-2): the roadmap row
|
||||
says the scan happens "at submit/post time"; I shipped **read-time**
|
||||
enrichment. The intent the row actually names — "not as live compose
|
||||
preview" — holds (drafts are never scanned). Read-time was chosen for
|
||||
correctness (links track the live active set: newly-accepted RFCs start
|
||||
linking, withdrawn ones stop), zero migration, and cheapness (the corpus
|
||||
is small + cache-resident).
|
||||
|
||||
### Arc 4 — Tests, build, ship
|
||||
|
||||
- New `backend/tests/test_rfc_links_vertical.py`: 12 tests (9 scanner
|
||||
units covering the gating rules, word boundaries, longest-match,
|
||||
case-insensitivity, casing preservation; 3 end-to-end that PR
|
||||
description + review comment + discussion comment all surface
|
||||
`*_segments`, plus self-reference suppression). Two integration-test
|
||||
fixes mid-flight: the change `original` text must exist verbatim in
|
||||
`SEED_BODY` (else "stale"), and the PR description carries an appended
|
||||
§6.5 `On-behalf-of:` trailer (so assert containment, not equality).
|
||||
- **Full backend suite: 363 passed** (351 baseline + 12 new).
|
||||
- **Frontend builds clean** (`npm ci` + `npm run build` with a throwaway
|
||||
`.env` providing `VITE_APP_NAME`; the chunk-size warning is pre-existing).
|
||||
- Committed `e794523`; pushed `feature/v0.26.0-pr-rfc-links` to **origin**
|
||||
(git.wiggleverse.org) + **benstull** (mirror).
|
||||
- ohm-rfc ROADMAP #28 row updated with a "Part 1 built + PR-pushed"
|
||||
status note (commit `0f09403`, pushed to ohm-rfc main) so a future
|
||||
driver doesn't re-pick Part 1.
|
||||
|
||||
I left the branch PR-ready and recorded a "built + PR-pushed" status note
|
||||
on the ohm-rfc ROADMAP #28 row — initially deferring the merge/deploy to
|
||||
the operator per the launch prompt's "coordinate the deploy lock + slot"
|
||||
rule.
|
||||
|
||||
### Arc 5 — Operator authorized merge + deploy
|
||||
|
||||
Mid-session the operator replied: **"go ahead and merge the PR and
|
||||
deploy."** So I carried it through, with two safety detours forced by the
|
||||
parallel-session environment:
|
||||
|
||||
- **Merge.** `main` was not checked out in any worktree (the shared rfc-app
|
||||
checkout holds the security branch with uncommitted work — untouchable).
|
||||
Created a fresh detached worktree on `main`, `git merge --no-ff` the
|
||||
feature branch (merge `698821f`), tagged `v0.26.0` (lightweight, house
|
||||
style), pushed `main` + tag to origin + benstull. Version-slot note:
|
||||
merging v0.26.0 makes the parallel v0.25.0 security session "last to
|
||||
merge" — it renumbers/rebases per the roadmap rule; flagged for the
|
||||
operator.
|
||||
- **Deploy.** The canonical flotilla checkout had **uncommitted
|
||||
`deploy.py` changes** — the 0026/0027 secret-redaction WIP on
|
||||
`_PhaseRunner` — and its editable `.venv` runs the working tree. Rather
|
||||
than actuate a production deploy with another session's unmerged code,
|
||||
I deployed from a **clean detached worktree on flotilla `main`
|
||||
(c26f251 = v1.1.0)** with its own venv. The state DB
|
||||
(`~/.ohm-rfc-app-flotilla/`) is a fixed user path, so the worktree saw
|
||||
the registered deployment + deploy log + §8.3 lock.
|
||||
- **A scare, resolved.** A `deploy log | tail -12` appeared to show the
|
||||
last *success* as v0.17.0 with three aborted v0.18.0 rows — seemingly
|
||||
contradicting "live at v0.24.0." I stopped and probed ground truth:
|
||||
`deploy status` + a direct curl both returned **0.24.0**. The "missing"
|
||||
rows were a `tail` artifact (the log prints newest-first; `tail` hid
|
||||
ids 26–34). No real discrepancy. (Lesson: probe live health before
|
||||
trusting a truncated log view.)
|
||||
- **Deploy.** Dry-run confirmed the plan (target v0.26.0, 7 secret refs
|
||||
resolve incl. the already-bound `ANTHROPIC_API_KEY`, renamed VM
|
||||
`/opt/ohm-rfc-app`, no migration step). Real deploy: all 9 phases ok,
|
||||
**deploys.id=34**, health verify in 7.3s — no SSE-keepalive abort
|
||||
despite deploying with pre-v1.2.0 flotilla (the intermittent failure
|
||||
didn't trigger). Live `/api/health` = `0.26.0`; `pin check` matches.
|
||||
- Updated the ohm-rfc ROADMAP #28 row to **Part 1 ✅ SHIPPED + DEPLOYED**
|
||||
(commit `b4d39a8`). Removed all three temporary worktrees.
|
||||
|
||||
---
|
||||
|
||||
## Cut state (end of session)
|
||||
|
||||
| Repo / surface | State |
|
||||
| --- | --- |
|
||||
| rfc-app | `main` @ `698821f` (merge), tag **v0.26.0** pushed to origin + benstull. 363 tests green, FE builds. Feature commit `e794523`. |
|
||||
| ohm-rfc | `main` @ `b4d39a8` — pin bumped to **0.26.0**, ROADMAP #28 Part 1 struck SHIPPED + DEPLOYED. |
|
||||
| OHM live | **v0.26.0** on `ohm-rfc-app`, healthy (`/api/health`=0.26.0). **deploys.id=34** succeeded (9/9 phases, verify 7.3s). |
|
||||
| Worktrees | All three temporary worktrees (rfc-app feature, rfc-app main-merge, flotilla deploy) removed. |
|
||||
|
||||
| #28 ledger | Status |
|
||||
| --- | --- |
|
||||
| #28 Part 1 (auto-link accepted RFCs) → v0.26.0 | ✅ shipped + deployed (deploys.id=34) |
|
||||
| #28 Part 2 (offer-to-create-RFC) | ⏸ not started |
|
||||
| #28 Part 3 (offer-to-contribute-to-pending) | ⏸ not started |
|
||||
|
||||
---
|
||||
|
||||
## §19.2 / process candidates surfaced
|
||||
|
||||
1. **Branch-chat auto-linking.** Part 1 enriches PR descriptions, PR
|
||||
review comments, and PR-less discussion comments — but not branch-chat
|
||||
messages (the AI-collaboration surface, `ChatPanel.jsx` +
|
||||
`api_branches.py`). Extending `rfc_links` there is a small follow-up if
|
||||
branch chat warrants it.
|
||||
2. **Curated canonical-terms / per-RFC alias list.** The conservative
|
||||
matcher deliberately skips single common-word titles/slugs. The roadmap
|
||||
names a "curated canonical-terms list" for exactly these; it's left as
|
||||
an explicit opt-in (config/content), not guessed at in framework code.
|
||||
3. **rfc-app test deps aren't in `requirements.txt`.** `pytest` /
|
||||
`httpx` / `pytest-asyncio` had to be pip-installed into the fresh
|
||||
worktree venv by hand (the shared checkout's venv had them). A
|
||||
`requirements-dev.txt` (or an extras group) would make a clean worktree
|
||||
test-ready in one step. Minor ergonomic gap, like the `PYTHONPATH=.`
|
||||
one CONTRIBUTING already notes.
|
||||
|
||||
---
|
||||
|
||||
## What lands on the operator's plate
|
||||
|
||||
1. **v0.26.0 is shipped + deployed (deploys.id=34) — nothing left here.**
|
||||
Worth a real-world eyeball: open a PR or post a comment on OHM that
|
||||
mentions an accepted RFC (RFC-0001 / "Open Human Model") and confirm
|
||||
the inline auto-link renders to `/rfc/<slug>`.
|
||||
2. **The parallel v0.25.0 security-hardening session (0026/0027) is now
|
||||
"last to merge."** Because v0.26.0 landed first, that session must
|
||||
rebase onto a `main` that's already at v0.26.0 and **renumber to
|
||||
v0.27.0** (its target slot is taken). Expect a trivial top-of-file
|
||||
CHANGELOG/VERSION resolution; the code regions are disjoint from
|
||||
v0.26.0's (their MarkdownPreview/otc/ratelimit vs. my rfc_links/PRView/
|
||||
discussion).
|
||||
3. **The local flotilla `deploy.py` working tree still has the 0026/0027
|
||||
secret-redaction WIP uncommitted** — I deployed from clean `main`
|
||||
(v1.1.0) and left their WIP untouched. Nothing for you unless you want
|
||||
to land it.
|
||||
4. (Carried from 0028) flotilla v1.2.0 PR still open + unmerged — the
|
||||
phase-7 SSE pre-drain it carries would have de-risked this deploy's
|
||||
restart phase (which happened to succeed without it).
|
||||
5. **Parts 2 + 3 of #28** remain unbuilt — the larger follow-up.
|
||||
|
||||
---
|
||||
|
||||
## Prompt the operator can paste into the next Claude Code session
|
||||
|
||||
```
|
||||
OHM roadmap driver session, parallel-safe. Claim your ID first:
|
||||
~/git/ohm-infra/scripts/claim-session-id.sh --start <now PST, YYYY-MM-DDTHH-MM>
|
||||
It prints active --INPROGRESS sessions — coordinate. Read SESSION-PROTOCOL §7
|
||||
+ pull ohm-rfc/ROADMAP.md.
|
||||
|
||||
STATE (end of 0029, 2026-05-28): OHM live at rfc-app **v0.26.0** on
|
||||
ohm-rfc-app (deploys.id=34, healthy), pin=0.26.0, deploy lock free.
|
||||
Session 0029 shipped + DEPLOYED #28 Part 1 (auto-link accepted RFCs in PR
|
||||
text + comments). Still built-but-unmerged / in-flight:
|
||||
- flotilla v1.2.0 (Session 0028) — PR open, not merged (its phase-7 SSE
|
||||
pre-drain de-risks deploy restarts; the v0.26.0 deploy succeeded
|
||||
without it).
|
||||
- rfc-app v0.25.0 security-hardening (Sessions 0026/0027) — uncommitted
|
||||
in the shared /Users/benstull/git/rfc-app checkout (+ uncommitted
|
||||
deploy.py redaction WIP in the flotilla checkout). Because v0.26.0
|
||||
merged first, this session is now "last to merge" → it must rebase
|
||||
onto main@v0.26.0 and **renumber to v0.27.0** (slot 0.25.0 superseded).
|
||||
Code regions are disjoint from v0.26.0's.
|
||||
|
||||
PICK ONE disjoint item. Open candidates: #28 Parts 2+3 (offer-to-create-RFC;
|
||||
offer-to-contribute-to-pending — the larger follow-up, its own session, and
|
||||
it will rebase on whatever v0.25.0's MarkdownPreview/sanitize work settled);
|
||||
#21 Part A Amplitude audit (real data ~2026-06-04); #22 pro-consent copy
|
||||
(operator-drafted + counsel text); #20/#18 ops (DMARC Phase B ~2026-06-04;
|
||||
stale wiggleverse/meta webhook still pointing at deprovisioned
|
||||
rfc.wiggleverse.org; bounce wiring); #31b/#25-redesign (operator
|
||||
screenshots); #33/#34 repo + GCP name alignment (operator-led).
|
||||
AVOID shipped/in-flight surfaces: #26/#27/#29/v0.21.0; the v0.25.0 security
|
||||
files (otc.py, ratelimit.py, MarkdownPreview/ProposalView/Editor.jsx,
|
||||
sanitizeHtml.js, migration 023); and v0.26.0's surfaces (rfc_links.py,
|
||||
LinkedText.jsx, get_pr/discussion enrichment).
|
||||
|
||||
Hard rules: never ask for secret bytes (give the
|
||||
`printf '%s' "$(pbpaste)" | .venv/bin/ohm-rfc-app-flotilla secret set
|
||||
ohm-rfc-app <KEY>` gesture); coordinate the serialized deploy lock + version
|
||||
slot with the operator; if you build in rfc-app, take a manual git worktree
|
||||
with its own venv (the shared /Users/benstull/git/rfc-app checkout may be
|
||||
mid-edit by another session); subagents write their own §5 subsession
|
||||
transcripts; finalize + publish your transcript LAST (deliver the handoff
|
||||
prompt before publish). Use branches + PRs. Claim your ID, then go.
|
||||
```
|
||||
Reference in New Issue
Block a user