Files
rfc-app/docs/QUICKSTART-VISION.md
T
Ben Stull 29c96ea300 Release 0.2.0: graduation merge race fix + VITE_APP_NAME + versioning infrastructure
- Fix §13.3 step 4 race against Gitea's async mergeability
  computation: gitea.wait_for_mergeable polls the mergeable
  field before calling merge, and bot._merge_with_retry rides
  out the transient 'Please try again later' response.
- Frontend now requires VITE_APP_NAME at build time
  (frontend/vite.config.js fails the build if unset). Header
  brand, landing H1, and browser title read the deployment's
  configured name.
- Establish framework versioning: VERSION (canonical) +
  frontend/package.json#version mirror; CHANGELOG.md as the
  release log with RFC 2119 / 8174 normative-language
  upgrade-steps; SPEC.md §20 as the binding policy; CLAUDE.md
  capturing the separation-of-concerns rule; docs/DEPLOYMENTS.md
  as the downstream operating manual; docs/QUICKSTART-VISION.md
  staking the future one-command-deploy capability.
- Surgical fix to SPEC.md opening so the spec no longer asserts
  OHM is the corpus the framework produces.
- SPEC.md §19.2 gains the 'Deployment-supplied subject framing'
  candidate that drives the 0.3.0 release.
2026-05-26 06:37:48 -07:00

189 lines
9.0 KiB
Markdown

# Vision: a one-command path to a new rfc-app deployment
This document is **not** an implementation plan. It is the vision that
the current build does not yet deliver — the experience we want for
anyone who reads about the RFC framework and decides they'd like to
run their own. Today, standing up a deployment is the multi-step
journey in [`DEPLOYMENTS.md`](./DEPLOYMENTS.md). The aspiration in
this doc is to compress that journey to a single command (or a small
handful), so the friction between *I want to run an instance of this*
and *I have a working instance of this* is as close to zero as we can
get it.
We are writing this down now so the principles are settled before any
code lands.
## Who this is for
The framework is the substrate for collaborative, RFC-style
standardization of any subject where a community needs to agree on
the meaning of its terms and where the argument that produced the
agreement is itself worth preserving. The deployments we imagine the
quickstart serving include — but are not limited to:
- **Medicine.** A public, model-assisted revision of the DSM's
diagnostic criteria. Each diagnosis becomes an RFC; the criteria
and their boundaries are argued in transcript; graduation gives a
diagnosis a stable identifier and a reviewable history of how it
came to be defined the way it is. The same shape applies to
clinical protocols, drug-interaction taxonomies, and rare-disease
registries.
- **Law.** Model statutes, regulatory definitions, or clause
libraries. An RFC per clause, with the drafting argument
preserved alongside the final text. The framework's audit log
doubles as legislative history.
- **Bioethics and biosecurity.** Vaccine protocols, gene-editing
guidelines, dual-use research review criteria. Domains where
consensus saves lives and the reasoning behind the consensus
matters as much as the consensus itself.
- **Literature.** Canonical-edition standardization for works with
contested manuscripts; lexicons for technical or constructed
languages; controlled vocabularies for archives.
- **Software.** Library API contracts written as prose, before the
code. RFC-style definitions of cross-language behaviors that
multiple implementations must respect.
- **Policy and governance.** Municipal ordinance templates, NGO
governance rubrics, standards-body procedural definitions.
- **Education.** Curriculum standards, assessment rubrics, the
meaning of competencies and credentials.
- **Natural language itself.** The original case — the Open Human
Model deployment — standardizing the vocabulary humans and
machines need to share.
The quickstart's goal is to make the path from *"I run one of these
communities and we need this"* to *"my community has a working
deployment to start arguing on"* short enough that the choice is
about the work the community wants to do, not the operational lift
of getting started.
## The intended experience
A reader who has just finished `PHILOSOPHY.md` and decides they want
their own deployment should be able to:
1. Pick a name for their deployment (one user-visible string).
2. Run a single command from a clean machine — `npx
create-rfc-deployment <name>`, or `docker compose up` from a tiny
template, or `curl ... | bash`, or whatever shape the design
settles on.
3. Answer a small number of questions the command can't infer:
their Gitea endpoint (or an offer to spin one up locally), an
admin email, the OAuth callback URL.
4. End up with: a running rfc-app instance reachable in a browser, a
meta repository seeded with the right structure, a first sign-in
that hands the OWNER role to the operator, and a deployment repo
on disk holding their `.rfc-app-version` pin, their `.env`
defaults (sans secrets), and a `CLAUDE.md` describing the
two-repo loop.
From the operator's point of view, the framework should feel like
infrastructure they instantiated, not a codebase they cloned.
## Why this isn't there yet
The current bring-up requires the operator to do work the framework
could do for them. Specifically:
- **Gitea provisioning.** The operator stands up Gitea by hand,
creates the bot account, generates the bot token, registers the
OAuth2 application, copies credentials into `backend/.env`. A
quickstart could spin up Gitea in a sibling container, create the
bot via Gitea's first-run admin API, and emit the credentials
straight into the deployment's environment.
- **Meta-repo seeding.** Today `scripts/seed_meta_repo.py` is a
manual step. A quickstart could run it as part of the first boot,
detect an already-seeded repo (idempotent), and report what it did.
- **Frontend `.env`.** The operator copies `.env.example` and hand-
fills `VITE_APP_NAME`. A quickstart could ask once and write the
file.
- **Deployment repo bootstrap.** Today the deployment repo is a
thing the operator creates manually. A quickstart could generate
it: a fresh git repo containing `.rfc-app-version`, a README
template, a `CONTRIBUTING.md` template, a `CLAUDE.md` template
cloned from this repo's pattern, and a placeholder
`rfcs/RFC-0001-...md` the operator fills in.
- **OAuth callback wiring.** The current bring-up requires the
operator to register an OAuth app in Gitea by hand. A quickstart
could do this through Gitea's API once the bot token exists.
- **Process supervision.** Today `deploy/RUNBOOK.md` walks an
operator through systemd / nginx by hand. A quickstart could ship
a Docker Compose file (or systemd unit templates) that bring up
backend + frontend + Gitea in one shot.
Each of these is a small lift on its own. Together they're a
quickstart product — and that's what this doc is staking out.
## Design principles for when the work gets picked up
The quickstart is downstream of every other contract in this repo.
The principles below keep it that way:
**The quickstart does not embed deployment values.** It collects
them from the operator and writes them where they belong (the new
deployment's repo, the server's `.env`, etc.). The framework remains
deployment-agnostic; the quickstart is a configurator, not a
template renderer that bakes in OHM-like choices.
**The quickstart respects `SPEC.md` §20.** It pins the new
deployment to the current framework version (the `VERSION` file).
Future upgrades go through the §20.5 sequence — the quickstart does
not invent a parallel upgrade path. If the quickstart needs to bump
the pin, it does so by editing `.rfc-app-version` in the deployment
repo, the same way an operator would by hand.
**The quickstart produces a deployment repo that an operator can
own.** The output is plain files in a git repo, not a runtime that
hides the configuration. An operator who never wants to think about
the quickstart again can read the generated `CLAUDE.md` and
`.rfc-app-version` and continue from there with `DEPLOYMENTS.md` as
their guide.
**Loud failures, not silent defaults.** If the operator declines to
supply a required value, the quickstart refuses to continue. We do
not ship a "demo" deployment that produces something running but
useless; the framework's separation-of-concerns rule is upstream of
the quickstart's UX.
**One thing at a time.** A quickstart that tries to handle every
deployment topology (single-machine, Kubernetes, managed Gitea,
self-hosted Gitea, Cloud Run, Fly, etc.) on day one is a project
that ships nothing. The first cut targets a single happy path —
likely a single-machine Docker Compose with a local Gitea — and the
others are §19.2-style follow-ups.
## Open questions to settle before building
When this work gets picked up, the design session will need to
settle:
- **Where does the quickstart live?** A separate repo? A `tools/`
directory in this repo? A published npm package? Each has trade-
offs (versioning, discoverability, upgrade story).
- **What's the shape of "one command"?** `npx create-rfc-deployment`,
`docker compose up`, `curl | bash`, a TUI installer, a web wizard
hosted by the framework's docs site? The shape determines the
audience.
- **Does the quickstart bring up Gitea or assume it exists?** Both
are valid; "bring up Gitea" is friendlier for new operators but
enlarges the quickstart's surface; "assume Gitea" is cleaner but
leaves a real bring-up step in the operator's lap.
- **How does the quickstart handle secrets?** Generate them and
write them to disk? Print them to stdout? Both? What's the
rotation story?
- **What does the upgrade story look like for an operator who used
the quickstart?** The pin lives in the deployment repo per §20.5;
the quickstart should never become a parallel upgrade path. But
it might offer an `rfc-app upgrade` command that just runs the
§20.5 sequence in one shot.
These are the conversations to have when the time comes. None of them
need answering today; this doc exists so that whoever picks this up
has the shape of the goal in front of them.
## Status
Not started. This doc is the seed. When work begins, it gets its own
§19.2 candidate in `SPEC.md` and the design session follows the
existing decision-and-fold pattern. Until then, [`DEPLOYMENTS.md`](./DEPLOYMENTS.md)
is the path an operator follows.