docs: correct the deployment and configuration docs, and fix the all-in-one health check - #61
Merged
Merged
Conversation
The image's HEALTHCHECK asked for /health, which no router registers. With the SPA mounted, the fallback answers any unmatched path with index.html and a 200, so the probe reported healthy whatever state the application was in. Point it at /system/health/livez, the endpoint the standard compose file already uses. Adds a test that reads the probe URLs out of deploy/ and asserts each one names a route the health router registers, and one that pins the SPA fallback behaviour that made the bad probe silent.
The AI providers page documented AI_PROVIDER, AI_API_KEY, AI_MODEL and AI_BASE_URL as dotenv settings. None of those names exist in the service: providers are created through the settings form (POST /api/v1/ai-providers) and stored in ai_providers.yaml. The page also named the types anthropic and openai-compatible; the real ones are claude, openai and openai_compat, and the quick start repeated the same two wrong names. Rewrites the page against the code — types, fields and their defaults, how base_url is used, where the model list comes from, and the per-dispatch options — and drops the recommended-model table in favour of the endpoint's own list. Documents that a provider's concurrency cap is fixed at first use and only changes on a restart.
Both .env.example files listed MR_REVIEW__LOGGING__LEVEL and
MR_REVIEW__LOGGING__USE_JSON, and the configuration guide documented them as
.env variables. Compose reads .env only to substitute ${...} in the compose
file; neither compose file lists those names under environment: or sets
env_file:, so setting them there does nothing. USE_JSON is additionally
hard-coded to "true" in both compose files, which would win anyway.
Drops the inert lines from the examples and splits the configuration page into
the variables .env can change (PORT, API_PORT, WEB_PORT, DATA_DIR) and the
application settings, which belong in the environment: block.
The home page, installation guide and configuration guide all described a SQLite database. The three repositories are file-backed — hosts.yaml, ai_providers.yaml and reviews/<uuid>.yaml under the data directory — and sqlite appears nowhere in the service. Also notes in the installation guide that the all-in-one image is amd64 only, which is what publish.yml builds, so on Apple Silicon the recommended deployment is the emulated one.
The hosts page described GitLab and GitHub only. Gitea, Forgejo and Bitbucket
have been supported for a while, and Bitbucket is the odd one: base_url is
ignored (it is always Bitbucket Cloud) and the token field takes
username:app_password for Basic auth, with a colon-less value sent as a bearer
token.
Also corrects two claims that no longer hold: nothing tests a host connection
automatically after saving — GET /api/v1/hosts/{id}/test is the check, and it
is not called by the form — and deleting a host removes the host from
hosts.yaml, not the reviews created against it.
The development block told contributors to run 'uv sync --group dev', 'make fmt', 'make check', 'make test-unit' and 'make test' at the repository root, and to branch from and target 'main'. The root pyproject has no dev group (only docs), the root Makefile has none of those four targets, and the default branch is master: $ uv sync --group dev error: Group `dev` is not defined in the project's `dependency-groups` table $ make check make: *** No rule to make target `check'. Stop. Per-service setup and checks instead, since that is where the toolchains live, plus the root targets that do exist (dev, run-services, fmt-services, docs-serve). 'make check' and 'make test-unit' now exist in services/mr-review — both guides already documented them, and they run exactly what CI runs. Also drops the SQLAlchemy and AsyncUnitOfWork rules from the architecture section: neither exists in this project, and the release section described a manual tag push that release-please and publish.yml took over.
docs/ROADMAP.md and docs/specs/inline-fix-suggestions.md were built into the site and, since scripts/emit_markdown.py landed, published as .md twins too — while being written in Russian, absent from the nav, and reachable only by someone who guessed the URL. Both are drafts about intent, not documentation of what is deployed, so they move to ROADMAP.md and specs/ in the repository instead of being translated. The agents page's documentation map points at where they went.
Quick start and the all-in-one section said http://localhost:8000, and the
standard section 8000/8080. The shipped compose files map ${PORT:-17240}:8000,
${API_PORT:-17241}:8000 and ${WEB_PORT:-17242}:8080, which is what the docs
site says.
Also repoints the documentation table: /quick-start/ and /configuration/ are
under /getting-started/, and /deployment/ and /development/ are not pages on
the site at all.
…hosts Same two corrections one level down: the backend README claimed SQLite via SQLAlchemy and GitLab/GitHub only, and pointed at a 'make dev' target the service Makefile does not have (it is 'make run-api'; 'make dev' is the root target that starts both services). The pipeline page said comments go back to the MR 'in GitLab or GitHub'.
Follows the move: the agents page's documentation map no longer lists two pages the site does not build, and says where they went instead; the roadmap's own link to the spec drops the docs/ prefix.
The site build reported '## [Unreleased]' as an unresolved link reference — the brackets read as a Markdown reference link. The file's other headings carry no brackets either.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Writing
docs/agents.mdagainst the source turned up nine defects in the docs and thedeployment files. This fixes them. One section per finding: what was wrong, how I know,
what changed. Nothing here is breaking; the only behaviour change is the all-in-one
container's health check.
1. The AI providers page documented environment variables that do not exist
docs/features/ai-providers.mddescribedAI_PROVIDER,AI_API_KEY,AI_MODELandAI_BASE_URLas dotenv configuration, and named the provider typesanthropicandopenai-compatible.None of those four names appear anywhere outside that page:
Providers are created through the settings form —
POST /api/v1/ai-providers— and storedin
ai_providers.yaml. The types areclaude,openaiandopenai_compat(
AIProviderTypeincore/ai_providers/entities.py; the form offers Claude / OpenAI /OpenAI-compat).
Rewrote the page against the code: the three types and the two backends behind them, the
fields with their real defaults, how
base_urlis used (and ignored byclaude), wherethe model list comes from, and the per-dispatch
temperature/reasoning_budget/reasoning_effort. Dropped the recommended-model table —GET /api/v1/ai-providers/{id}/modelsasks the endpoint itself, which cannot go stale. The quick start repeated the same two
wrong type names; corrected there too.
2.
MR_REVIEW__*in a compose.envdoes nothingBoth
deploy/*/.env.examplefiles listedMR_REVIEW__LOGGING__LEVELandMR_REVIEW__LOGGING__USE_JSON, andgetting-started/configuration.mddocumented them as.envvariables. Compose reads.envonly to substitute${...}in the compose file;neither compose file lists those names under
environment:and neither setsenv_file:,so an operator who edits them gets no change.
MR_REVIEW__LOGGING__USE_JSONisadditionally hard-coded to
"true"in both compose files, which would win in any case.Fixed on the docs side rather than by adding
env_file:: the compose files are correct asthey are,
env_file:on a file the installation guide never tells you to create would makedocker compose upfail for anyone who followed the guide, anddocs/agents.mdalreadystates the current behaviour as rule 6. The examples now carry only the four names Compose
actually substitutes, and the configuration page splits "what
.envcan change" from"application settings, which go in the
environment:block".3. The all-in-one health check probed a route that does not exist
deploy/all-in-one/Dockerfileprobedhttp://localhost:8000/health. No router registersthat path. Because the image sets
MR_REVIEW__STATIC_DIR, the SPA fallback answers anyunmatched path with
index.htmland a 200 — so the probe was green regardless of the stateof the application. Reproduced against the app the image runs:
The probe now names
/system/health/livez, whichdeploy/standard/docker-compose.ymlalready used.
Two tests come with it.
tests/unit/test_deploy_health_probes.pyreads the probe URLs outof
deploy/and asserts each one is a route the health router registers — it fails onmasterand passes here:tests/integration/http/test_spa_fallback.pypins the fallback behaviour that made the badprobe silent. That path had no coverage at all before.
4. There is no SQLite database
docs/index.md,getting-started/installation.mdandgetting-started/configuration.mdall described SQLite storage, and so did
services/mr-review/README.md("SQLite(SQLAlchemy)").
grep -rniE 'sqlite|sqlalchemy|alembic'overservices/returns nothing:the three repositories are file-backed (
FileHostRepository,FileAIProviderRepository,FileReviewRepository) and writehosts.yaml,ai_providers.yamlandreviews/<uuid>.yaml. The pages now say what is actually on disk, and that it holds tokensand API keys in plain text.
The
v0.1.0entry inCHANGELOG.mdalso claims SQLite storage. I left it alone — it is areleased entry, and rewriting history felt like your call rather than mine. It is published
as the site's changelog, so you may want to decide either way.
5. Three host types were missing from the docs
docs/features/hosts.mdand the configuration and quick start pages described GitLab andGitHub only.
Host.typehas beengitlab | github | gitea | forgejo | bitbucketfor awhile, each with its own auth, and Bitbucket is the awkward one:
base_urlis ignored (itis always Bitbucket Cloud) and the token field holds
username:app_passwordfor Basicauth, with a colon-less value sent as a bearer token.
The hosts page now covers all five, with the API base each type derives from
base_url,the token each one wants, the
owner/reporule (only GitLab takes nested groups) and what"add repository by URL" does.
Two smaller claims on that page went with it, both checked against the code:
nothing calls
GET /api/v1/hosts/{id}/testfrom the UI (hostApi.testhas no caller),and there is no such indicator. The page now describes the endpoint instead.
DeleteHostUseCaseremovesthe host from
hosts.yamland nothing else; reviews stay.6. README ports did not match the compose files it hands you
The quick start said
http://localhost:8000twice and the standard section 8000/8080,while
deploy/all-in-one/docker-compose.ymlmaps${PORT:-17240}:8000and the standardfile
${API_PORT:-17241}:8000and${WEB_PORT:-17242}:8080.While there: the documentation table linked
/quick-start/and/configuration/, whichlive under
/getting-started/, and/deployment/and/development/, which are not pageson the site at all. Confirmed against a local
zensical build.7. The contributing guide described a repository that is not this one
It told contributors to branch from and target
main, and to run these at the root:The root
pyproject.tomlhas only adocsgroup, the default branch ismaster, and thetoolchains live in the two service directories. The setup and check sections are now
per-service, plus the root targets that do exist (
dev,run-services,fmt-services,docs-serve— those I ran).make checkandmake test-unitnow exist inservices/mr-review/Makefile. Both thisguide and
services/mr-review/CONTRIBUTING.mdalready documented them and CI already runsexactly those commands, so the Makefile was the side that had drifted:
Also in that file: the architecture section forbade SQLAlchemy in the domain and required
use cases to accept
AsyncUnitOfWork— neither exists in this project — and the releasesection described a manual
git tag && git push origin mainthat release-please andpublish.ymltook over.8. Two Russian planning drafts were being published
docs/ROADMAP.mdanddocs/specs/inline-fix-suggestions.mdwere built into anEnglish site, absent from the nav, reachable only by guessing the URL — and since
scripts/emit_markdown.pylanded, published as.mdtwins as well.I moved them out of
docs_dirrather than translating them: they are drafts about intent(the roadmap still says "SQLAlchemy + SQLite, Python 3.11+"), not documentation of what is
deployed, and translating a draft would have meant guessing at your intent in two long
documents. They are now
ROADMAP.mdandspecs/inline-fix-suggestions.mdin therepository; the agents page's documentation map says where they went. The site builds ten
pages instead of twelve, with no issues.
Say the word if you would rather have the roadmap in the nav in English and I will
translate it.
9. Documented, not changed
Both confirmed and both left as they are:
fence.pycreates the semaphoreon the first dispatch and keeps it for the process lifetime, deliberately and per its own
docstring. Worth noting that
max_concurrenthas no field in the settings form at all —it is set through the API or by editing
ai_providers.yaml— so the effect is smallerthan it sounds. Both facts are now on the AI providers page.
publish.ymlbuildsapiandweb-appforlinux/amd64,linux/arm64and the combined image forlinux/amd64, so on Apple Siliconthe recommended deployment is the emulated one. Said so in the installation guide, where
someone choosing between the two deployments will see it.
Verification
uv syncwas run with--frozen; neitheruv.lockchanged. The frontend is untouched.Noticed, not touched
make helpat the repository root fails on macOS and Linux: the help targets inMakefileandscripts/*/Makefileuse the Windowsecho.idiom, and the shell answersmake: echo.: No such file or directory. It is the default goal, and the README pointsat it.
CHANGELOG.md— the one the site publishes — has a singlev0.1.0entry whilethe services are at 0.2.1 and 0.2.2, whose own changelogs release-please maintains.
scripts/tools/Makefilestill offersalembic-new-migration.