← All posts

v1.4.1 - Production Analytics, Mermaid Diagrams, and Release Guardrails

Keating 1.4.1 is a patch release for the browser app: production PostHog analytics now initialize and proxy correctly, Mermaid diagrams render again after SVG validation, chat markdown handles Mermaid fences directly, open-ended quizzes get model-judged grading, fine-tune datasets can be imported, and the repo's release/version guardrails are documented in the public update trail.

1.4.1 is a correctness release for the shipped web app. The last release added analytics, richer model/provider surfaces, Dio provider plumbing, and more public-facing instrumentation. This patch makes the production path match that intent: analytics now survive the Docker build, the production server handles the same /ingest proxy path as local development, and Mermaid diagrams no longer disappear because a safety check was stricter than Mermaid's SVG output.

Production Analytics Actually Starts

The previous integration had the right event call sites in the bundle, but production builds could compile PostHog initialization away when VITE_POSTHOG_PROJECT_TOKEN was missing at build time. The web Dockerfile now forwards the PostHog Vite variables into the build, so initPostHog() can create the provider client in the deployed app instead of returning null.

The second half of the fix is server-side: Nitro now proxies /ingest, /ingest/static, and /ingest/array in production, matching the Vite development proxy. That keeps analytics traffic same-origin without letting missing proxy routes fall through to the SPA HTML shell.

Mermaid Diagrams Render Again

A security hardening pass added SVG sanitization before diagrams are inserted into the page. That was the right boundary, but the first implementation parsed Mermaid's SVG with a strict XML parser and rejected otherwise safe output that contained HTML-style entities. The sanitizer now tries strict XML first, falls back to a lenient HTML parse when Mermaid emits safe-but-not-XML-perfect markup, and still strips unsafe elements, event handlers, JavaScript URLs, and unsafe CSS.

Mermaid handling is also more direct in chat. Fenced mermaid blocks now render as diagrams in live chat, shared-session markdown, and artifact markdown instead of only being syntax-highlighted as code. The fence parser also accepts uppercase and parameterized fences such as `````Mermaid title="..."``.

Quiz Grading and Fine-Tune Import

Open-ended quiz questions no longer pretend a string match is a real grade. Short-answer, transfer, and single-blank fill-in questions now render as "pending review" with the reference answer and a clearly labeled, non-authoritative heuristic hint, and they are excluded from the auto-graded tally. The teacher grades them by meaning through a new grade_quiz tool whose per-question verdicts flow back into the result card. Markdown also gained ||spoiler|| click-to-reveal masks so hints can be hidden until the learner is ready.

On the data side, Keating can now import fine-tune datasets in the CLI and the web app. ChatML, Alpaca, and JSONL inputs are parsed by a dependency-free shared parser, paired with export improvements and tests, so a learning corpus can travel back into Keating rather than only out of it.

Release and Provider Notes

The public update trail now covers the provider-auth recovery, voice default, and provider-aware search cleanup that landed after the last tagged release. The repo also has a documented devenv.nix release path with optional bumpy, a bump-version helper, and repo-local version/test hooks so release chores are less dependent on memory.

Verification

This patch adds a Mermaid regression test for uppercase and parameterized fences, keeps the existing SVG safety checks in place, and verifies the web app through the Bun test suite plus the full Vite/Nitro production build.