add 0025/SESSION-0025.0-TRANSCRIPT-2026-05-28T13-06--2026-05-28T13-30.md + replace placeholder/variant SESSION-0025.0-TRANSCRIPT-2026-05-28T13-06--INPROGRESS.md
This commit is contained in:
@@ -0,0 +1,302 @@
|
||||
# Session 0025.0 — Transcript
|
||||
|
||||
> Date: 2026-05-28
|
||||
> Goal: Pick one roadmap item disjoint from v0.21.0's polished surfaces
|
||||
> and from #26/#29, build it on a manual worktree while deploys are
|
||||
> frozen. Recommended fits from the 0022 handoff: #19 (CONTRIBUTING
|
||||
> docs) or #27 (Haiku tag suggestions).
|
||||
>
|
||||
> Outcome: **#19 turned out to be already shipped (Session 0013.1) but
|
||||
> never struck in the ROADMAP — which is exactly what misdirected this
|
||||
> session to it. Pivoted to #27. Built Claude Haiku tag suggestions on
|
||||
> the propose-RFC modal, tagged rfc-app [v0.24.0](https://git.wiggleverse.org/ben.stull/rfc-app/src/tag/v0.24.0),
|
||||
> pushed to origin + benstull. 351 backend tests green, frontend builds
|
||||
> clean. NOT deployed — deploys frozen behind the #1 VM-rename blocker
|
||||
> (Session 0022); pin held at 0.22.0. ROADMAP bookkeeping corrected
|
||||
> (#19 struck, #21 Part B noted shipped, #27 recorded as built+staged).**
|
||||
>
|
||||
> Highlights:
|
||||
> - The §9.1 "Slice 2" AI-suggested tag chips, deferred since the
|
||||
> propose modal first landed, are now wired.
|
||||
> - Reused the existing §18 provider abstraction (`AnthropicProvider`,
|
||||
> `_CLAUDE_VARIANTS["claude-haiku"]`) — added one small factory
|
||||
> `providers.construct_haiku()`. `ANTHROPIC_API_KEY` was already a
|
||||
> config var (the chat stack reads it), so #27's "new secret" may
|
||||
> already be bound on OHM — flagged for the operator to check.
|
||||
> - Held the pin and staged the deploy, consistent with how v0.23.0's
|
||||
> pin is being held during the freeze.
|
||||
|
||||
---
|
||||
|
||||
## Pre-session state
|
||||
|
||||
| repo | sha | state |
|
||||
| --- | --- | --- |
|
||||
| rfc-app | `daebb54` | `main`; last tag v0.23.0 (#29). Backend 340 tests green. |
|
||||
| ohm-rfc | `9f0c4e7` | `main` clean; pin `.rfc-app-version` = 0.22.0 |
|
||||
| ohm-rfc-app-flotilla | `85f01f8` | session anchored here; `main` clean except untracked `.claude/` |
|
||||
| OHM live | running v0.21.0 (per the 0019.0 / 0024.0 ledger), healthy | — |
|
||||
|
||||
**Deploy freeze in force.** The 0022 handoff: flotilla deploy of
|
||||
v0.22.0 failed preflight (install dir `/opt/ohm-app` missing on the VM;
|
||||
clean failure, no lock held, no partial deploy). Session 0022 is
|
||||
investigating whether the #1 VM rename (`ohm-app` → `ohm-rfc-app`) was
|
||||
started on the VM, leaving the §13 deployment record pointing at the
|
||||
old path. Deploys blocked until 0022 clears it; OHM still healthy at
|
||||
v0.21.0. Deploy order when it unblocks: v0.22.0 → v0.23.0 → mine.
|
||||
|
||||
Sessions 0022 (deploy-blocker, INPROGRESS), 0023, 0024 (roadmap-capture
|
||||
#33/#34, done) preceded this. None were building #27.
|
||||
|
||||
---
|
||||
|
||||
## Turn-by-turn arc
|
||||
|
||||
### Arc 1 — Claim, orient, pick an item
|
||||
|
||||
Claimed session ID **0025** via `claim-session-id.sh --start
|
||||
2026-05-28T13-06` (pushed the placeholder; the push is the atomic
|
||||
claim). Read SESSION-PROTOCOL.md §7 + the session-start gesture, and
|
||||
the full ROADMAP (PULL'd ohm-rfc first — already up to date).
|
||||
|
||||
Reasoned to **#19** over #27 initially: deploy-free (ships as PRs the
|
||||
operator merges), zero code-surface collision with the avoid-list,
|
||||
fully completable this session. #27 by contrast needs a new secret, a
|
||||
counsel pass, and a deploy — none closeable during the freeze.
|
||||
|
||||
### Arc 2 — #19 is already done (the ledger lied)
|
||||
|
||||
Before touching anything, checked the repos for existing artifacts.
|
||||
**Both `CONTRIBUTING.md` files already existed and were committed:**
|
||||
|
||||
- rfc-app `CONTRIBUTING.md` + SPEC §21 analytics chapter landed on
|
||||
`main` via `213f686` (merge `ac3513a`, *"Session 0013.1"*) — the
|
||||
commit message literally reads *"Lands roadmap item #19 ... and #21
|
||||
Part B ... as a single docs commit."* Verified `213f686` is an
|
||||
ancestor of `origin/main` and the file is in the `main` tree.
|
||||
- ohm-rfc `CONTRIBUTING.md` committed (`90965d4` + later edits).
|
||||
|
||||
So **#19 + #21 Part B shipped back in Session 0013.1** and were simply
|
||||
never struck in the ROADMAP version-target table. The 0022 handoff
|
||||
recommended #19 not realizing it was done — the un-struck row is what
|
||||
misdirected this session. This is the session's main friction finding
|
||||
(see §19.2 candidates).
|
||||
|
||||
Pivoted to the other named fit, **#27**. Confirmed via local
|
||||
transcripts + rfc-app tags/branches that no live session was building
|
||||
it (0024 only *lists* #27 as a future candidate; no `v0.24.0` tag, no
|
||||
`#27` branch).
|
||||
|
||||
### Arc 3 — Map the surfaces
|
||||
|
||||
Mapped before building (all reads, no subagents — #27 is one cohesive
|
||||
feature, so the driver built it directly; no §5 subsession transcripts
|
||||
warranted):
|
||||
|
||||
- **Existing LLM infra (§18 chat stack).** `backend/app/providers.py`
|
||||
already has a multi-provider abstraction with `AnthropicProvider` and
|
||||
`_CLAUDE_VARIANTS["claude-haiku"] = ("claude-haiku-4-5-20251001",
|
||||
"Claude Haiku")`. `ANTHROPIC_API_KEY` is already a config var
|
||||
(`config.py:44/91`) and `anthropic>=0.39` is already a dep. The
|
||||
`models_resolver` docstring even anticipates *"the §9.1 tag
|
||||
suggestions"*. So #27's "new secret" is the same key the chat stack
|
||||
uses — it may already be bound on OHM.
|
||||
- **Tags are free-form chip input** ("free-form for slice 1; the
|
||||
AI-suggested chips of §9.1 are deferred to Slice 2"). No curated
|
||||
taxonomy. So "the existing tag taxonomy" #27 references = the
|
||||
de-facto set of distinct tags across `cached_rfcs` (`tags_json`).
|
||||
- **Propose endpoint** is in `api.py`'s `make_router(config, gitea,
|
||||
bot, providers)` closure, gated by `auth.require_contributor`.
|
||||
- **Provider-call convention** (`api_prs._draft_with_provider`): async
|
||||
endpoints call `provider.send()` directly (no threadpool), wrapped in
|
||||
try/except → graceful stub fallback. Matched it.
|
||||
- **Test harness**: no shared conftest; tests self-bootstrap via
|
||||
`app_with_fake_gitea` / `sign_in_as` / `provision_user_row` from
|
||||
`test_propose_vertical.py`. Runner `./.venv/bin/python -m pytest`
|
||||
from `backend/` (340 tests pre-change).
|
||||
|
||||
### Arc 4 — Build #27 (worktree)
|
||||
|
||||
Manual worktree per the handoff (Agent worktree isolation is broken):
|
||||
`git worktree add -b feature/v0.24.0-haiku-tags
|
||||
/Users/benstull/git/rfc-app-v0.24.0-haiku-tags main`, then symlinked
|
||||
`frontend/node_modules` + `backend/.venv` in. (`.gitignore` ignores
|
||||
`.venv/`/`node_modules/` as directories; the symlinks showed as
|
||||
untracked, so every commit staged explicit files — never `-A`.)
|
||||
|
||||
Backend:
|
||||
- **`backend/app/tag_suggest.py`** (new) — `gather_tag_universe()`
|
||||
(distinct corpus tags, most-common first, capped 200); `Draft`
|
||||
dataclass; `haiku_provider(config)` seam (monkeypatchable; `None`
|
||||
when no key); `build_messages` + tolerant `parse_reply` (drops
|
||||
invented tags, dedupes case-insensitively to canonical spelling,
|
||||
clamps confidence, caps); `suggest()` orchestration; in-process
|
||||
per-user sliding-window rate limit (`TAG_SUGGEST_RATE_MAX` /
|
||||
`_WINDOW_SECONDS`, defaults 30/60).
|
||||
- **`providers.construct_haiku(api_key)`** — dedicated Haiku provider,
|
||||
model id sourced from `_CLAUDE_VARIANTS`. Independent of
|
||||
`ENABLED_MODELS`; no RFC slug at propose time so the §6.7 funder path
|
||||
doesn't apply.
|
||||
- **`POST /api/rfcs/suggest-tags`** in `api.py` — `require_contributor`,
|
||||
rate-limit → 429, `SuggestTagsBody {title, pitch, use_case}`. Returns
|
||||
`{suggestions:[{tag,confidence}]}`. Degrades to `[]` (200, never an
|
||||
error) for no key / empty corpus / empty draft / parse failure.
|
||||
- `backend/.env.example` — documented that `ANTHROPIC_API_KEY` also
|
||||
powers tag suggestions + the two optional rate-limit vars.
|
||||
|
||||
Frontend:
|
||||
- `ProposeModal.jsx` — debounced (700 ms, stale-response-guarded)
|
||||
suggestion fetch on `[title, pitch, useCase]`; clickable suggestion
|
||||
chips that add to the tag list (nothing auto-applies); the required
|
||||
inline disclosure ("Suggestions are generated by Claude (Anthropic).
|
||||
The text you've entered above is sent to Anthropic to produce them.").
|
||||
- `api.suggestTags()` — forgiving; any non-OK → `[]`.
|
||||
|
||||
Tests: **`test_tag_suggest_vertical.py`** (11) — anon→401, contributor
|
||||
gets universe-filtered suggestions (invented tag dropped), no-key→[],
|
||||
empty-corpus→[] (model never called), rate-limit→429, plus units for
|
||||
gather/parser-tolerance/max-cap/empty-draft-short-circuit/provider-
|
||||
failure. One initial failure (the gather unit test needed the db
|
||||
initialized, which happens in the TestClient lifespan) — fixed by
|
||||
wrapping in a `TestClient(app)` context. Full suite **351 green**;
|
||||
frontend `npm run build` clean (needed the deployment `.env` copied in
|
||||
from the main checkout — gitignored, not committed).
|
||||
|
||||
### Arc 5 — Release (tag), staged deploy, bookkeeping
|
||||
|
||||
Followed the established release shape: feature commit on the branch
|
||||
(`fb9b4fa`) → `--no-ff` merge to `main` (`376a6da`) → release commit
|
||||
bumping `VERSION` + `frontend/package.json` + `CHANGELOG.md` (`28015ed`)
|
||||
→ tag **`v0.24.0`** → pushed `main` + branch + tag to **origin** and
|
||||
**benstull**. Re-ran the full suite on `main` post-merge: 351 green.
|
||||
|
||||
CHANGELOG `Upgrade steps:` (RFC 2119) names the **MUST**
|
||||
`flotilla secret set ohm-rfc-app ANTHROPIC_API_KEY` gesture (stdin
|
||||
pbpaste form; never paste bytes), notes the chat stack may already have
|
||||
it bound, the optional rate-limit knobs, and a **SHOULD** counsel pass
|
||||
on the disclosure wording (per #22).
|
||||
|
||||
**Pin deliberately NOT bumped** — held at 0.22.0, consistent with how
|
||||
v0.23.0's pin is being held during the freeze. Bumping to 0.24.0 would
|
||||
have jumped ahead of un-deployed 0.22.0/0.23.0 and scheduled a frozen
|
||||
deploy. The deploy + pin bump are staged for the operator.
|
||||
|
||||
ROADMAP corrected + pushed (`f62cb90`): struck **#19** (with the
|
||||
"misdirected 0025" note), annotated **#21 Part B** as shipped in
|
||||
0013.1, recorded **#27** as built+tagged v0.24.0 with the full
|
||||
operator-pending-gesture list. Did **not** touch #26/#29 rows — those
|
||||
are tagged-but-not-struck pending deploy and belong to the still-open
|
||||
Session 0022.
|
||||
|
||||
Removed the build worktree (branch preserved on both remotes).
|
||||
|
||||
---
|
||||
|
||||
## Cut state (end of session)
|
||||
|
||||
| | |
|
||||
| --- | --- |
|
||||
| rfc-app | `28015ed` `main`, tag **v0.24.0** (#27) — pushed origin + benstull. 351 tests green, frontend builds clean. |
|
||||
| ohm-rfc | `f62cb90` `main` — ROADMAP corrected; **pin held at 0.22.0** |
|
||||
| OHM live | unchanged — v0.21.0, healthy. **No deploy** (frozen). |
|
||||
| flotilla | untouched |
|
||||
|
||||
| Roadmap ledger | Status |
|
||||
| --- | --- |
|
||||
| #19 CONTRIBUTING + onboarding | ✅ was already shipped (0013.1); struck this session |
|
||||
| #21 Part B analytics discipline | ✅ was already shipped (0013.1) with #19; noted |
|
||||
| #27 Haiku tag suggestions (v0.24.0) | 🟡 built + tagged + pushed; ⏸ deploy staged (freeze) |
|
||||
|
||||
---
|
||||
|
||||
## §19.2 candidates surfaced
|
||||
|
||||
1. **The ROADMAP version-target ledger lags reality and it cost a
|
||||
session's worth of misdirection.** #19 + #21 Part B shipped in
|
||||
0013.1 but were never struck; #26 (v0.22.0) and #29 (v0.23.0) are
|
||||
tagged-but-not-struck pending deploy. A future session reading the
|
||||
table can't tell "available" from "shipped-but-unbooked." Worth a
|
||||
convention call: either (a) strike on *tag* (not deploy) with a
|
||||
separate "deployed?" column, or (b) a fast `git tag` vs. table
|
||||
reconciliation pass at session start. The first gesture of an
|
||||
implementer session should be "is this already done?" — this session
|
||||
only avoided wasted work by checking the tree before building.
|
||||
2. **`ANTHROPIC_API_KEY` is overloaded across two surfaces** (the §18
|
||||
chat stack and now #27 tag suggestions). Fine today (same provider),
|
||||
but if a deployment wants a *cheaper/separate* key for the
|
||||
high-volume suggestion path vs. interactive chat, that's a future
|
||||
`TAG_SUGGEST_ANTHROPIC_KEY`-style split. Noted, not built.
|
||||
3. **Tag suggestion quality is bounded by corpus size.** Constrained to
|
||||
existing tags (per #27's explicit scope), a near-empty corpus yields
|
||||
near-empty suggestions. The roadmap already names taxonomy-extension
|
||||
(letting the model propose genuinely new tags) as the deferred
|
||||
follow-up; this is the data point that it'll matter early for OHM.
|
||||
|
||||
---
|
||||
|
||||
## What lands on the operator's plate
|
||||
|
||||
1. **Clear the deploy freeze** (Session 0022's `/opt/ohm-app` blocker),
|
||||
then deploy in order: v0.22.0 → v0.23.0 → **v0.24.0**, bumping the
|
||||
ohm-rfc pin at each step and verifying.
|
||||
2. **Before/at the v0.24.0 deploy:** set `ANTHROPIC_API_KEY` —
|
||||
`printf '%s' "$(pbpaste)" | .venv/bin/ohm-rfc-app-flotilla secret set
|
||||
ohm-rfc-app ANTHROPIC_API_KEY` (never paste the bytes). **Check
|
||||
first** whether it's already bound for the §18 chat stack:
|
||||
`flotilla secret list ohm-rfc-app`. Without it the app still serves;
|
||||
suggestions are just unavailable.
|
||||
3. **Counsel pass** on the propose-modal disclosure wording before
|
||||
exposing the surface, per #22 discipline. The copy is honest as
|
||||
written.
|
||||
4. End-to-end verification of the suggestion surface happens
|
||||
post-deploy (couldn't be done this session — no deploy, and no key
|
||||
should ever touch the model).
|
||||
|
||||
---
|
||||
|
||||
## Prompt the operator can paste into the next Claude Code session
|
||||
|
||||
```
|
||||
You are an OHM roadmap driver session. Claim your session ID first
|
||||
(~/git/ohm-infra/scripts/claim-session-id.sh --start <now PST>); your
|
||||
number is not assigned here. Read SESSION-PROTOCOL.md §7 + ohm-rfc/
|
||||
ROADMAP.md (PULL ohm-rfc first).
|
||||
|
||||
State at handoff (from session 0025):
|
||||
- rfc-app main @ 28015ed: v0.24.0 tagged + pushed (origin + benstull) —
|
||||
roadmap #27, Claude Haiku tag suggestions on the propose-RFC modal.
|
||||
351 backend tests green, frontend builds clean. NOT deployed.
|
||||
- THREE rfc-app releases now sit un-deployed behind the freeze:
|
||||
v0.22.0 (#26), v0.23.0 (#29), v0.24.0 (#27). ohm-rfc pin still 0.22.0
|
||||
(all three pin-bumps held for deploy).
|
||||
- ⛔ DEPLOYS STILL BLOCKED pending Session 0022's /opt/ohm-app VM-rename
|
||||
investigation. Do NOT run flotilla deploy until that clears —
|
||||
coordinate with the operator. Deploy order: v0.22.0 → v0.23.0 →
|
||||
v0.24.0, bump pin + verify at each.
|
||||
- #19 + #21 Part B were already shipped (Session 0013.1) — struck/noted
|
||||
in the ROADMAP this session. The ledger had lagged; check the rfc-app
|
||||
git tags against the version-target table before assuming a row is
|
||||
available (#26/#29 are tagged-but-not-struck pending deploy).
|
||||
|
||||
Operator gestures pending for v0.24.0 (#27), at deploy time:
|
||||
- Set ANTHROPIC_API_KEY (operator-run pbpaste|flotilla secret set; never
|
||||
paste bytes). It may already be bound for the §18 chat stack — check
|
||||
`flotilla secret list ohm-rfc-app` first.
|
||||
- Counsel pass on the propose-modal disclosure copy (per #22).
|
||||
|
||||
Your job: pick one roadmap item that's shippable and disjoint from the
|
||||
un-deployed surfaces (#26 ProposeModal/PRModal/RFCView/PRView,
|
||||
#29 App.jsx sign-in region, #27 ProposeModal suggestion row +
|
||||
tag_suggest.py + the suggest-tags endpoint) and from v0.21.0's polished
|
||||
CSS. Build on a manual git worktree (git worktree add -b <branch>
|
||||
<path> main; symlink frontend/node_modules + backend/.venv). Good
|
||||
deploy-free fits while frozen: #21 Part A (Amplitude audit — but it
|
||||
wants real-world data) or another Track-A surface that can build + tag +
|
||||
stage. Avoid touching the three un-deployed features' code regions.
|
||||
|
||||
Hard rules: never ask for secret bytes; subagents write their own §5
|
||||
subsession transcripts; finalize + publish your transcript last,
|
||||
delivering the next handoff prompt to the operator before publish.
|
||||
|
||||
Claim your ID, then go.
|
||||
```
|
||||
@@ -1,15 +0,0 @@
|
||||
# Session 0025.0 — Transcript
|
||||
|
||||
> Date: 2026-05-28
|
||||
> Start: 2026-05-28T13-06 (PST implied)
|
||||
> Status: **PLACEHOLDER — claimed at session start; finalized at session end.**
|
||||
>
|
||||
> This file reserves session ID 0025. The driver replaces this body
|
||||
> with the full transcript before publishing, and renames the file to
|
||||
> its final SESSION-0025.0-TRANSCRIPT-2026-05-28T13-06--<end>.md form.
|
||||
|
||||
---
|
||||
|
||||
## Launch prompt
|
||||
|
||||
_(launch prompt not captured at claim time)_
|
||||
Reference in New Issue
Block a user