From 1558cc3a8b2d5f93355e9fadb1374bfcd841b997 Mon Sep 17 00:00:00 2001 From: Ben Stull Date: Fri, 29 May 2026 02:12:18 -0700 Subject: [PATCH] Release v0.30.0: sync user guide (DOCS.md) with the shipped app MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Documentation-only minor. The guide had drifted since it was first written; brought back in sync with v0.7.0–v0.29.0: - "Signing in" rewritten: email + one-time-code, optional passcode, trust-device 30d, optional Turnstile, and the beta-request → pending → admin-grant gate, plus admin-create + invite-claim. The vestigial email allowlist is no longer described as the gate. - "Proposing a new RFC": four → five fields (optional use-case #26) + AI tag-suggestion disclosure (#27). - "Roles & permissions": documents the pending state. - New "Invitations, cross-references, and contribution requests" section (#12 owner invites; #28 auto-link / create-RFC / ask-to- contribute). - New "Privacy and cookies" section (#11/#13). No code/schema/API/config/overlay/secret change — DOCS.md is served verbatim by /api/docs. VERSION + frontend/package.json bumped to 0.30.0. Co-Authored-By: Claude Opus 4.8 (1M context) --- CHANGELOG.md | 33 ++++++++++++ DOCS.md | 117 +++++++++++++++++++++++++++++++++++++----- VERSION | 2 +- frontend/package.json | 2 +- 4 files changed, 140 insertions(+), 14 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 14a6a6a..c96f760 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -23,6 +23,39 @@ 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.30.0 — 2026-05-29 + +**Minor — documentation: the user guide (`DOCS.md`, served at +`/docs/user-guide` via `/api/docs`) brought back in sync with the +shipped app. No code, schema, API, config, overlay, or secret change — +a plain code deploy serves the updated guide. Shipped from driver +session 0037.0.** + +The guide had drifted since it was first written: it still described +the pre-OTC email *allowlist* sign-in, listed four propose-RFC fields, +and predated several shipped surfaces. Updated to match v0.7.0–v0.29.0: + +- **Signing in** rewritten for the email + one-time-code flow (v0.7.0), + optional passcode (v0.10.0), trust-this-device for 30 days (v0.11.0), + optional Cloudflare Turnstile (v0.12.0), and the beta-access request → + `pending` → admin-`granted` gate (v0.8.0 / #6), plus the admin-create + + invite-claim path (v0.17.0 / #16). The vestigial allowlist is no + longer described as the gate. +- **Proposing a new RFC** now lists five fields, adding the optional + "What will you be using this RFC for?" use-case field (#26) and noting + the AI tag-suggestion disclosure (#27). +- **Roles & permissions** documents the `pending` state. +- New **Invitations, cross-references, and contribution requests** + section covers owner invitations (#12) and the RFC auto-link / + create-RFC / ask-to-contribute affordances (#28). +- New **Privacy and cookies** section covers the consent banner and + consent-gated analytics (#11 / #13). + +Upgrade steps: none — documentation-only; the change is the `DOCS.md` +file served verbatim by `/api/docs`. A plain code deploy at this tag +serves it. A deployment that overrides the guide via `DOCS_PATH` +supplies its own copy and is unaffected. + ## 0.29.0 — 2026-05-28 **Minor — roadmap #28 Parts 2 + 3: offer-to-create-an-RFC for strong- diff --git a/DOCS.md b/DOCS.md index 22fea51..3981163 100644 --- a/DOCS.md +++ b/DOCS.md @@ -39,23 +39,44 @@ thread. Every write affordance is replaced with a sign-in prompt. ## Signing in -While the framework is in private beta, only invited email addresses -can complete sign-in. If your email is on the allowlist, the -"Sign in" button in the header completes the flow and lands you on -the catalog with full read and write access. If your email is not on -the allowlist, you'll be sent to a short "pending" page explaining -the gate. +Anyone can start the sign-in flow with their own email address — there +is no invite-only allowlist. Sign-in is passwordless: -Once you have an account, you're a **contributor** by default — the -role that grants every write affordance the app exposes, scoped by -the per-RFC and per-branch rules described below. +1. **Enter your email.** If the deployment has human verification + enabled (a Cloudflare Turnstile challenge), you complete it here. +2. **Enter the one-time code.** The app emails you a short numeric + code; entering it signs you in. Codes expire after a few minutes, + and repeated wrong entries briefly lock the email. +3. **Set a passcode (optional).** After your first code sign-in you + can set a passcode. On later visits you sign in with email + + passcode, with the one-time code as the forgot-passcode fallback. +4. **Trust this device (optional).** You can mark a device trusted for + 30 days to skip the code/passcode step on it. Trusted devices are + listed in your settings and can be revoked individually or all at + once. + +### Getting write access + +Signing in gives you an account, but write access is gated. The first +time you sign in you're asked for your first name, last name, and a +short note on why you'd like access; you then land on a "request in +review" page. While your account is **pending**, you can read +everything an anonymous visitor can but cannot write — no chat, +propose, branch, PR, or discussion post. Once an admin **grants** your +account you become a **contributor**, the role that carries every +write affordance the app exposes, scoped by the per-RFC and per-branch +rules described below. + +An admin can also create your account ahead of time and email you an +invite link. Clicking it claims the account and signs you in with the +role the admin assigned, skipping the one-time-code step. --- ## Proposing a new RFC A new RFC begins as a proposal. The "+ Propose new RFC" button at -the bottom of the catalog opens a small modal that collects four +the bottom of the catalog opens a small modal that collects five things: - **Title.** The word, concept, or topic this RFC would define. @@ -65,8 +86,13 @@ things: inline. - **Pitch.** One or two paragraphs answering *why this RFC is needed*. This becomes the body of the entry. -- **Tags.** Optional. The AI suggests tags from the pitch; you can - accept, dismiss, or type your own. +- **Use case.** Optional. *What will you be using this RFC for?* — + the concrete application driving the proposal, as distinct from the + abstract case for it. Leaving it blank is fine. +- **Tags.** Optional. If the deployment has AI tag suggestion + enabled, suggested tags appear as you fill the form (with an inline + note that the text you've entered is sent to the model that + generates them); you can accept, dismiss, or type your own. Submitting the modal does one concrete thing: it opens a pull request against the framework's meta repository, adding one new @@ -167,6 +193,51 @@ either requires a contributor account. --- +## Invitations, cross-references, and contribution requests + +Three connected surfaces help the right people find and join the +right RFC. + +### Owner invitations + +An RFC's owner (or an app-wide admin or owner) can invite a specific +person to that RFC from the "Invitations" control in the RFC header. +The invite names an email and a role for *this RFC*: + +- **contributor** — can open PRs and join the discussion; +- **discussant** — can join the discussion only. + +The invitee gets an email with an accept link; accepting adds them as +a collaborator on that RFC. The invitations panel lists every invite +with its status (pending / accepted / expired / revoked); pending +invites can be revoked. An invitation is per-RFC — it does not change +the invitee's app-wide role, and it cannot lift the pending gate: the +invitee still needs a granted account to write. + +### RFC cross-links in PRs and comments + +When a PR description or a comment mentions an existing active RFC — +by its ID, its multi-word title, or its slug — the framework renders +that mention as a link to the RFC. The matching is conservative by +design (single common words are never auto-linked), and the links are +computed at read time, so nothing is rewritten in what you typed. + +### "Create" and "ask to contribute" offers + +The same scan surfaces two affordances inline: + +- If a term looks like it should have an RFC but none exists yet, a + reader who has create rights sees a **"create RFC for ''"** + link that opens the propose modal with the title pre-filled. +- If a term matches a *pending* RFC (a super-draft someone already + owns), a signed-in reader sees an **"ask to contribute"** offer + naming the owner. It opens a short request form — who you are, why + you're asking, and optionally what you'd use the RFC for. The + request lands in the owner's inbox; the owner can **accept** (which + sends you an owner invitation) or **decline** (which notifies you). + +--- + ## Working on a branch Contribute mode flips one branch into edit-enabled. The centre @@ -505,6 +576,14 @@ Each role is a strict superset of the one below it. entirely. The framework names a single "owner zero" at bootstrap. +Between anonymous and contributor sits one transient state: +**pending**. A freshly signed-in account that hasn't been granted +access yet (see [Signing in](#signing-in)) reads everything an +anonymous visitor can, but no write affordance unlocks until an admin +grants it. Granting promotes the account to contributor; an admin can +also revoke a granted account back to a no-write state. These +transitions are recorded in the `permission_events` log. + The practical difference between admin and owner is narrow but load-bearing: admin is the operational tier — it does the day-to- day moderation and stewardship work; owner is the tier that @@ -594,6 +673,20 @@ review. --- +## Privacy and cookies + +A consent banner appears on your first visit and lets you choose +which cookie categories to allow — essential always, with analytics +and other categories opt-in. The choice is remembered and can be +changed any time from the privacy/cookies controls in settings. + +Analytics only load if you opt in: the framework defers the analytics +SDK behind your consent, so declining means it is never initialized. +The `/privacy` and `/cookies` pages describe what's collected and +why; a deployment can point those pages at its own fuller policy. + +--- + ## Where to learn more - The framework's *why* lives in [the philosophy diff --git a/VERSION b/VERSION index ae6dd4e..c25c8e5 100644 --- a/VERSION +++ b/VERSION @@ -1 +1 @@ -0.29.0 +0.30.0 diff --git a/frontend/package.json b/frontend/package.json index 6aac60b..9d74d4c 100644 --- a/frontend/package.json +++ b/frontend/package.json @@ -1,7 +1,7 @@ { "name": "rfc-app-frontend", "private": true, - "version": "0.29.0", + "version": "0.30.0", "type": "module", "scripts": { "dev": "vite",