16 KiB
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 branchfeature/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/metawebhook, 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:221description,:443PR conversation;RFCDiscussionPanel.jsx:282discussion) — not through theMarkdownPreviewsurface 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_rfcsactive set rather than persisting links at submit time. That also avoidsmain.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 viaexclude_slug.api_prs.pyget_pr(): builds the index once (exclude current slug), addsdescription_segmentsand per-commenttext_segments.api_discussion.pyget_discussion_thread_messages(): per-commenttext_segments.frontend/src/components/LinkedText.jsx(new): maps segments onto React text nodes +<a class="rfc-autolink">. NodangerouslySetInnerHTML→ XSS-safe by construction, independent of the security branch'ssanitizeHtml.js. Falls back to rawtextwhen segments are absent (older cached responses).- Wired into
PRView.jsx(description + PR conversation bodies) andRFCDiscussionPanel.jsx(discussion bodies).App.css: a tokenized.rfc-autolinkrule (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 changeoriginaltext must exist verbatim inSEED_BODY(else "stale"), and the PR description carries an appended §6.5On-behalf-of:trailer (so assert containment, not equality). - Full backend suite: 363 passed (351 baseline + 12 new).
- Frontend builds clean (
npm ci+npm run buildwith a throwaway.envprovidingVITE_APP_NAME; the chunk-size warning is pre-existing). - Committed
e794523; pushedfeature/v0.26.0-pr-rfc-linksto 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.
mainwas not checked out in any worktree (the shared rfc-app checkout holds the security branch with uncommitted work — untouchable). Created a fresh detached worktree onmain,git merge --no-ffthe feature branch (merge698821f), taggedv0.26.0(lightweight, house style), pushedmain+ 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.pychanges — the 0026/0027 secret-redaction WIP on_PhaseRunner— and its editable.venvruns the working tree. Rather than actuate a production deploy with another session's unmerged code, I deployed from a clean detached worktree on flotillamain(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 -12appeared 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 atailartifact (the log prints newest-first;tailhid 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 checkmatches. - 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
- 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). Extendingrfc_linksthere is a small follow-up if branch chat warrants it. - 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.
- rfc-app test deps aren't in
requirements.txt.pytest/httpx/pytest-asynciohad to be pip-installed into the fresh worktree venv by hand (the shared checkout's venv had them). Arequirements-dev.txt(or an extras group) would make a clean worktree test-ready in one step. Minor ergonomic gap, like thePYTHONPATH=.one CONTRIBUTING already notes.
What lands on the operator's plate
- 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>. - 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
mainthat'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). - The local flotilla
deploy.pyworking tree still has the 0026/0027 secret-redaction WIP uncommitted — I deployed from cleanmain(v1.1.0) and left their WIP untouched. Nothing for you unless you want to land it. - (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).
- 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.