1a9374aa52
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>
165 lines
7.2 KiB
Markdown
165 lines
7.2 KiB
Markdown
# 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.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. `version` is the running
|
|
framework version (the contents of `VERSION` per §20.1, read at
|
|
process start and cached as a module-level constant in
|
|
`backend/app/health.py`); `status` is `"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 after `systemctl restart` catches the failure mode
|
|
where a restart did not pick up the new code. See `SPEC.md` §17
|
|
and the §19.2 settlement.
|
|
|
|
### Upgrade steps (from 0.2.2)
|
|
|
|
1. The deployment **MAY** configure its monitoring (Pingdom,
|
|
Healthchecks.io, the flotilla deploy control panel, etc.) to
|
|
probe `/api/health` and compare the returned `version` against
|
|
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.jsx` parsed PHILOSOPHY.md with
|
|
the bare `marked` import and `dangerouslySetInnerHTML`, so
|
|
```` ```mermaid ```` fences fell through as `<pre>` blocks rather
|
|
than rendered diagrams. Swapped to `MarkdownPreview`, 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 its `PHILOSOPHY_PATH` override.
|
|
|
|
## 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.jsx`
|
|
declared its `threadsByKind` `useMemo` *after* the early-return
|
|
guard for the loading state (`if (!pr) return …`). On first mount
|
|
`pr` was null so the early return fired and 14 hooks were called;
|
|
on the second render `pr` was populated and execution reached the
|
|
`useMemo`, calling 15 hooks — violating the Rules of Hooks and
|
|
unmounting the page subtree (blank screen). The `useMemo` is now
|
|
declared above the early returns with optional-chaining on `pr`,
|
|
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)
|
|
|
|
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` `<title>` is rewritten at build time via Vite's
|
|
HTML transform.
|
|
|
|
### Added
|
|
|
|
- `frontend/.env.example` documenting the new required variable.
|
|
- Top-level `VERSION` file and this `CHANGELOG.md` as the canonical
|
|
release log.
|
|
- `SPEC.md` §20 (versioning and downstream deployments) as the
|
|
binding policy for the framework/deployment relationship.
|
|
- `docs/DEPLOYMENTS.md` as the practical guide for building on
|
|
rfc-app and upgrading existing deployments to new versions.
|
|
- `CLAUDE.md` at 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.
|