|
|
|
@@ -23,6 +23,76 @@ skip versions are the composition of each intervening adjacent
|
|
|
|
|
release's steps in order — no A-to-B path is pre-computed beyond
|
|
|
|
|
that.
|
|
|
|
|
|
|
|
|
|
## 0.24.0 — 2026-05-28
|
|
|
|
|
|
|
|
|
|
**Minor — one new secret required before this version serves tag
|
|
|
|
|
suggestions; no schema migration; no behavior change for deployments
|
|
|
|
|
that do not bind the key.** Roadmap item #27: as a contributor fills in
|
|
|
|
|
the propose-RFC form, the backend asks Claude Haiku to recommend tags
|
|
|
|
|
drawn from the collection's existing tag set, surfaced as clickable
|
|
|
|
|
suggestion chips. Shipped from driver session 0025.0. This is the §9.1
|
|
|
|
|
"Slice 2" AI-suggested chips that the propose modal has carried a
|
|
|
|
|
deferred placeholder for since Slice 1.
|
|
|
|
|
|
|
|
|
|
- **`POST /api/rfcs/suggest-tags`** (contributor-gated, per-user
|
|
|
|
|
rate-limited). Takes the partial draft (`title`, `pitch`,
|
|
|
|
|
`use_case`) and returns `{ "suggestions": [{ "tag", "confidence" },
|
|
|
|
|
…] }`. The model is constrained to the corpus's existing tags — v1
|
|
|
|
|
tags are free-form chip input, so "the taxonomy" is the de-facto set
|
|
|
|
|
of distinct tags the existing RFCs carry. The model MUST NOT invent
|
|
|
|
|
tags; taxonomy extension is a deliberate out-of-scope follow-up.
|
|
|
|
|
- **Always Claude Haiku, for cost.** Tag suggestion uses Haiku
|
|
|
|
|
regardless of the `ENABLED_MODELS` chat-picker universe, via the new
|
|
|
|
|
`providers.construct_haiku()` factory. There is no RFC slug at propose
|
|
|
|
|
time, so the §6.7 per-RFC funder credential path does not apply — the
|
|
|
|
|
surface runs on the operator's own `ANTHROPIC_API_KEY`.
|
|
|
|
|
- **Degrades to silence, never error.** No key bound, an empty corpus,
|
|
|
|
|
an empty draft, a rate-limited caller, or an unparseable model reply
|
|
|
|
|
all yield an empty list; the propose modal hides its suggestion row,
|
|
|
|
|
and the rest of the app is unaffected. So a deployment that does not
|
|
|
|
|
set the key sees no change at all.
|
|
|
|
|
- **Privacy disclosure.** The modal carries an inline note that the
|
|
|
|
|
draft text is sent to Anthropic to generate the suggestions. This is
|
|
|
|
|
required for honesty (the text leaves the deployment before the RFC
|
|
|
|
|
is submitted); cookie-consent does not gate it because the user has
|
|
|
|
|
actively typed into a draft surface. The exact wording wants a
|
|
|
|
|
counsel pass before OHM's deploy, per the #22 drafting discipline.
|
|
|
|
|
- **Frontend.** `ProposeModal` debounce-posts the draft (700 ms, with a
|
|
|
|
|
stale-response guard); suggestion chips are clickable and add to the
|
|
|
|
|
tag list (nothing auto-applies). `api.suggestTags()` is forgiving —
|
|
|
|
|
any non-OK response resolves to `[]`.
|
|
|
|
|
|
|
|
|
|
Tests: 11 new (`test_tag_suggest_vertical.py`) — contributor-gating,
|
|
|
|
|
universe-constrained filtering, no-key / empty-corpus / rate-limit
|
|
|
|
|
paths, plus units for the universe gather, the tolerant reply parser,
|
|
|
|
|
the max cap, the empty-draft short-circuit, and provider-failure
|
|
|
|
|
fallback. Full suite 351 green.
|
|
|
|
|
|
|
|
|
|
Upgrade steps:
|
|
|
|
|
|
|
|
|
|
1. You **MUST** bind `ANTHROPIC_API_KEY` for the suggestion surface to
|
|
|
|
|
work. On OHM this is an operator gesture — the key never touches the
|
|
|
|
|
conversation. Set it from your own terminal via stdin (so the bytes
|
|
|
|
|
never land in shell history):
|
|
|
|
|
|
|
|
|
|
```bash
|
|
|
|
|
printf '%s' "$(pbpaste)" | .venv/bin/ohm-rfc-app-flotilla \
|
|
|
|
|
secret set ohm-rfc-app ANTHROPIC_API_KEY
|
|
|
|
|
```
|
|
|
|
|
|
|
|
|
|
(The §18 chat stack already reads this same key, so a deployment
|
|
|
|
|
that has chat configured **MAY** already have it bound — confirm with
|
|
|
|
|
`flotilla secret list ohm-rfc-app`.) If the key is absent the app
|
|
|
|
|
still boots and serves normally; tag suggestions are simply
|
|
|
|
|
unavailable until it is set.
|
|
|
|
|
2. You **MAY** tune the per-user rate limit via `TAG_SUGGEST_RATE_MAX`
|
|
|
|
|
(default 30) and `TAG_SUGGEST_RATE_WINDOW_SECONDS` (default 60). The
|
|
|
|
|
defaults apply when unset.
|
|
|
|
|
3. You **SHOULD** have counsel review the modal's disclosure wording
|
|
|
|
|
before exposing the surface to users, per the #22 drafting
|
|
|
|
|
discipline — the copy is honest as written, but the legal review is
|
|
|
|
|
the right call for any "your text is sent to a third party" notice.
|
|
|
|
|
|
|
|
|
|
## 0.23.0 — 2026-05-28
|
|
|
|
|
|
|
|
|
|
Roadmap item #29: signing in lands the user on their most recently
|
|
|
|
|