diff --git a/CHANGELOG.md b/CHANGELOG.md new file mode 100644 index 0000000..8ec7302 --- /dev/null +++ b/CHANGELOG.md @@ -0,0 +1,93 @@ +# Changelog + +The binding policy for what each kind of version bump means and what +the changelog has to carry is in [`SPEC.md` §20](./SPEC.md). The +practical recipe downstream deployments follow when reading this file +is in [`docs/DEPLOYMENTS.md`](./docs/DEPLOYMENTS.md). + +The canonical version is the `VERSION` file at the repo root; +`frontend/package.json#version` mirrors it. Deployments pin to a +specific framework version in their own `.rfc-app-version` file +(per §20.5). + +While the framework is pre-1.0, minor-version bumps may introduce +breaking changes; the entry below each such bump documents the +upgrade steps a deployment must apply. + +Upgrade-steps blocks use the [RFC 2119](https://www.rfc-editor.org/rfc/rfc2119) +/ [RFC 8174](https://www.rfc-editor.org/rfc/rfc8174) normative- +language convention per `SPEC.md` §20.4. **MUST** / **SHALL** steps +are required; **SHOULD** steps are recommended (the framework's +default and tested path); **MAY** steps are optional. Upgrades that +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.2.0 — 2026-05-26 + +**Breaking config change.** The frontend now requires +`VITE_APP_NAME` to be set at build time. `npm run build` fails with a +clear message if it is missing. There is no default; every deployment +names itself. + +### Upgrade steps (from 0.1.0) + +1. The deployment **MUST** create a `frontend/.env` file before + building. See `frontend/.env.example` for the contract. +2. The deployment **MUST** set `VITE_APP_NAME` in `frontend/.env` to + the user-visible name it wants to ship — the string used as the + browser tab title, the header brand, and the landing H1. The + build will fail loudly if this is unset or blank. +3. The deployment **MUST** rebuild the frontend (`npm install && npm + run build`) and redeploy the resulting bundle. The previous + bundle does not read `VITE_APP_NAME`. +4. The deployment **SHOULD** verify the name appears correctly in + the browser tab and the header after redeploy before bumping its + `.rfc-app-version` pin to `0.2.0`. +5. The deployment **MAY**, in the same upgrade, take the opportunity + to retire any local overrides it was using to brand the + pre-0.2.0 hardcoded strings — those overrides are now obsolete. +6. The deployment **MUST NOT** continue to expect graduation step 4 + to fail on Gitea's "Please try again later" race; that path is + now handled by `wait_for_mergeable` + bounded retry. Any local + workaround retrying graduation at the deployment level is now + redundant and **SHOULD** be removed. + +### Fixed + +- **Graduation merge race.** §13.3 step 4 (`merge_pr`) used to call + Gitea's merge endpoint the instant step 3 returned, which races + Gitea's background mergeability computation and produces the + `405 "Please try again later"` response. Step 4 now waits for the + `mergeable` field to become non-null (bounded by a 30s timeout) and + retries the merge call up to three times on the transient response. + See `backend/app/gitea.py#wait_for_mergeable` and + `backend/app/bot.py#_merge_with_retry`. + +### Changed + +- `frontend/src/App.jsx` header brand reads `VITE_APP_NAME` instead of + a hardcoded string. +- `frontend/src/components/Landing.jsx` H1 reads `VITE_APP_NAME` + instead of a hardcoded string. The pitch / deck / attribution copy + in this file is still deployment-specific and tracked as a follow-up + for extraction into deployment config. +- `frontend/index.html` `
An open dictionary of the words humans and machines need to agree on.
diff --git a/frontend/vite.config.js b/frontend/vite.config.js index aaa2e40..76ca792 100644 --- a/frontend/vite.config.js +++ b/frontend/vite.config.js @@ -1,15 +1,46 @@ -import { defineConfig } from 'vite' +import { defineConfig, loadEnv } from 'vite' import react from '@vitejs/plugin-react' // In dev, the frontend runs on Vite's port and proxies the API // (and /auth/*, /api/webhooks/*) to the FastAPI process. -export default defineConfig({ - plugins: [react()], - server: { - port: 5173, - proxy: { - '/api': 'http://localhost:8000', - '/auth': 'http://localhost:8000', +// +// VITE_APP_NAME is the user-visible name of this deployment — used in +// the browser tab title, the header brand, and the landing page H1. +// The framework intentionally ships no default: every deployment must +// supply its own name via `frontend/.env` so a fresh build never ships +// the wrong brand. See `frontend/.env.example`. +export default defineConfig(({ mode }) => { + const env = loadEnv(mode, process.cwd(), '') + const appName = env.VITE_APP_NAME + + if (!appName || !appName.trim()) { + throw new Error( + 'VITE_APP_NAME is required but not set. Copy frontend/.env.example to ' + + 'frontend/.env and set VITE_APP_NAME=... before building. The framework ' + + 'ships no default on purpose — each deployment names itself.' + ) + } + + return { + plugins: [ + react(), + // Build-time HTML token substitution: `%VITE_APP_NAME%` inside + // `index.html` becomes the configured name. Vite already does this + // for env vars referenced as `%VITE_*%` in HTML, but we wire it + // explicitly so the failure mode (token left in title) is loud. + { + name: 'inject-app-name', + transformIndexHtml(html) { + return html.replace(/%VITE_APP_NAME%/g, appName) + }, + }, + ], + server: { + port: 5173, + proxy: { + '/api': 'http://localhost:8000', + '/auth': 'http://localhost:8000', + }, }, - }, + } })