Adds an unauthenticated GET /api/health endpoint returning JSON
{version, status} for ops tooling. version is the running framework
version (read from VERSION at process start, cached as a module-level
constant in backend/app/health.py); status is "ok" with HTTP 200 in
v1, with the "degraded" / 503 path reserved in the response shape for
future degradation conditions.
The structural value is the version-match check: a deploy control
panel (flotilla, in particular) polls the endpoint after
`systemctl restart` reports active and verifies the returned version
equals the tag just deployed, catching the failure mode where a
restart did not pick up the new code.
Patch-shaped per SPEC.md §20.2 — no operator action required, no env
vars, no schema changes. The CHANGELOG carries one MAY-language step
naming the optional monitoring affordance.
SPEC.md §17 now lists the endpoint; the §19.2 candidate-topic entry
records the topic's settlement (version source = VERSION file at
import time; degraded = reserved v1 scaffold; CHANGELOG = patch shape
with MAY-language).
Tests: backend/tests/test_health.py (3 tests — 200/payload shape,
unauthenticated, version-matches-VERSION). Full suite 128/128 green.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
7.2 KiB
Changelog
The binding policy for what each kind of version bump means and what
the changelog has to carry is in SPEC.md §20. The
practical recipe downstream deployments follow when reading this file
is in 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
/ RFC 8174 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.3 — 2026-05-26
Patch — no operator action required. Rebuild and restart per the
routine deploy steps; no .env changes, no schema changes, no
behavior changes a deployment would notice in steady state beyond
the new endpoint below.
Added
GET /api/health— an unauthenticated probe returning JSON{version, status}for ops tooling.versionis the running framework version (the contents ofVERSIONper §20.1, read at process start and cached as a module-level constant inbackend/app/health.py);statusis"ok"with HTTP 200 in v1. The"degraded"/ HTTP 503 path stays reserved in the response shape so a later release can wire real degradation conditions without breaking the contract. The version-match check is the structural value — a deploy-control-panel polling the endpoint aftersystemctl restartcatches the failure mode where a restart did not pick up the new code. SeeSPEC.md§17 and the §19.2 settlement.
Upgrade steps (from 0.2.2)
- The deployment MAY configure its monitoring (Pingdom,
Healthchecks.io, the flotilla deploy control panel, etc.) to
probe
/api/healthand compare the returnedversionagainst the tag last deployed. The endpoint is unauthenticated by design — no PII in the payload, no session required.
0.2.2 — 2026-05-26
Patch — no operator action required. Rebuild the frontend and
restart per the routine deploy steps; no .env changes, no schema
changes, no behavior changes a deployment would notice in steady
state beyond the fix below.
Fixed
- Mermaid blocks rendered as raw code on
/philosophy.frontend/src/components/Philosophy.jsxparsed PHILOSOPHY.md with the baremarkedimport anddangerouslySetInnerHTML, so```mermaidfences fell through as<pre>blocks rather than rendered diagrams. Swapped toMarkdownPreview, which already carries the lazy mermaid loader + SVG render path used by the RFC body view, so the philosophy surface now renders mermaid the same way RFC bodies do. Pre-existing gap, surfaced when a deployment authored a mermaid block in itsPHILOSOPHY_PATHoverride.
0.2.1 — 2026-05-26
Patch — no operator action required. Rebuild the frontend and
restart per the routine deploy steps; no .env changes, no schema
changes, no behavior changes a deployment would notice in steady
state.
Fixed
- PR view blank page (React #310).
frontend/src/components/PRView.jsxdeclared itsthreadsByKinduseMemoafter the early-return guard for the loading state (if (!pr) return …). On first mountprwas null so the early return fired and 14 hooks were called; on the second renderprwas populated and execution reached theuseMemo, calling 15 hooks — violating the Rules of Hooks and unmounting the page subtree (blank screen). TheuseMemois now declared above the early returns with optional-chaining onpr, keeping the hook count stable between the loading and loaded renders. Pre-existing bug in the post-Contribute-rewrite PR view; surfaced in production by 0.2.0's graduation merge race fix enabling the workflow that opens this code path.
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)
- The deployment MUST create a
frontend/.envfile before building. Seefrontend/.env.examplefor the contract. - The deployment MUST set
VITE_APP_NAMEinfrontend/.envto 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. - The deployment MUST rebuild the frontend (
npm install && npm run build) and redeploy the resulting bundle. The previous bundle does not readVITE_APP_NAME. - The deployment SHOULD verify the name appears correctly in
the browser tab and the header after redeploy before bumping its
.rfc-app-versionpin to0.2.0. - 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.
- 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 the405 "Please try again later"response. Step 4 now waits for themergeablefield to become non-null (bounded by a 30s timeout) and retries the merge call up to three times on the transient response. Seebackend/app/gitea.py#wait_for_mergeableandbackend/app/bot.py#_merge_with_retry.
Changed
frontend/src/App.jsxheader brand readsVITE_APP_NAMEinstead of a hardcoded string.frontend/src/components/Landing.jsxH1 readsVITE_APP_NAMEinstead 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<title>is rewritten at build time via Vite's HTML transform.
Added
frontend/.env.exampledocumenting the new required variable.- Top-level
VERSIONfile and thisCHANGELOG.mdas the canonical release log. SPEC.md§20 (versioning and downstream deployments) as the binding policy for the framework/deployment relationship.docs/DEPLOYMENTS.mdas the practical guide for building on rfc-app and upgrading existing deployments to new versions.CLAUDE.mdat the repo root capturing the separation-of-concerns rule for working sessions.
0.1.0 — v1 build
Initial release. See docs/DEV.md for the slicing plan and build
history.