Skip to content

Caramel 0.8.0

Choose a tag to compare

@edreesjalili edreesjalili released this 06 Oct 13:00
· 28 commits to main since this release

Caramel 0.8.0

0.8.0 - 2026-10-06

Upgrade notes

  • Crema, Caramel's observability (ADR 0027), traces every routed request. Each response carries X-Request-ID, and a valid inbound traceparent continues the caller's trace. The application logs one canonical line per request through the crema log source, and serve and work set up logging themselves: JSON in production, text in development and test (CARAMEL_LOG_FORMAT, LOG_LEVEL). The old request_id=… error_type=… error line is gone; the error line carries error_class and fingerprint instead. Caramel::DevelopmentError.response now takes a Caramel::Crema::ErrorReport.
  • Crema times every SQL statement, job, schedule run, outbound call, view render and cache read inside a trace. Statements start with a comment such as /*action='App%3A%3ABooks%3A%3AShow'*/; a job continues the trace of the request that enqueued it through the new caramel_jobs.context column (a framework migration, so run frappe migrate); and each database pool names itself in application_name. Cold Brew's worker, maintenance, scheduler and hook error lines are now error entries from the crema source. Caramel::Database::Config has an application_name. SugarORM::Repo has two private hooks, observe and observe_checkout, that caramel/crema/sql redefines. dump value is a development aid.
  • frappe dev gets an inspector at /__caramel/dev/inspector, a toolbar on each page, richer error pages (editor links, the source, the request, queries and Copy as Markdown; set CARAMEL_EDITOR) and compile errors that link to the editor. frappe traces, frappe trace REF and frappe errors read what the session kept (frappe errors lists only what happened after the newest successful build, so a rebuild clears errors it fixed); MRDP gains the codes RUNTIME and REPEATED_QUERY. frappe lint and new applications' .ameba.yml enable Caramel/Dump, which reports a leftover dump; add it to an existing application's .ameba.yml to adopt it. The development gateway's status answers latest, and Latte.app has an Open inspector item.
  • A running application opens an owner-only ops socket (ADR 0028): serve next to its application socket, work only when CARAMEL_OPS_SOCKET names a path, off to disable. The binary is its own client: ops status|requests|fibers|metrics|tail|errors|error|traces|trace|debug-token|console. It serves Prometheus text, a read-only console, in-memory rings of errors (with redacted messages) and of failed, slow and debug traces, and signed debug tokens that record one person's requests. APP jobs (stats, failed, show, retry) and APP db diagnose (also frappe db diagnose) need only the database. Caramel::CommandLine.with_database is public for registered commands, and Crema.command adds application commands.
  • require "caramel/crema/recorder" makes an application keep per-minute counts and latency histograms in caramel_metrics, read by APP insights and the ops console. New applications require it in config/application.cr; add the line after require "caramel" to adopt it, and run frappe migrate (a new framework migration creates the table). It stores aggregates only: route templates and parameterized SQL, never paths, bind values or messages.
  • require "caramel/crema/otlp" exports traces as OTLP/HTTP JSON to the endpoint OTEL_EXPORTER_OTLP_ENDPOINT names, with the usual OTEL_* headers, service name and sampler variables (ADR 0028). It does nothing without an endpoint. Caramel::Outbound calls carry the sampling decision in their traceparent.
  • Latte's managed PostgreSQL preloads pg_stat_statements and auto_explain (ADR 0029); the next start of an existing cluster restarts it once. Each site's development database gets pg_stat_statements in a caramel_stats schema, which frappe db diagnose reads and frappe db dump leaves out. No role is granted pg_read_all_stats, so a site's role sees statement text only for its own statements, and utility statements (such as ALTER ROLE … PASSWORD) are not tracked. auto_explain logs the text and plan of statements that take 250 ms or more to postgres.log; application statements carry placeholders, and no bind values are logged. The spec database is unchanged.
  • Latte's control API gains version 2 (ADR 0029): a site lists its development session's errors and last_error. Version 1 is still served and unchanged; Frappé, Corretto and Latte.app now ask for version 2, so run latte stop once after upgrading so the next command starts the new Latte. Latte.app shows error counts, counts new alerts beside its icon and posts macOS notifications for build failures and new errors; it opens the inspector from a site's menu.
  • Latte's proxy writes a per-site access log to the site's log directory, and frappe logs access [--follow] prints it (ADR 0029). Each line carries the application's X-Request-Id. proxy.log no longer carries access lines. The daemon restarts the proxy's configuration on its next reconcile, so no action is needed.
  • Latte runs a local trace collector on 127.0.0.1:4318 (ADR 0029). Point any service at it with OTEL_EXPORTER_OTLP_ENDPOINT=http://127.0.0.1:4318 and OTEL_EXPORTER_OTLP_PROTOCOL=http/json; frappe dev sends its application's traces there, and the inspector and frappe trace REF --md show what other services did in the same trace under "Across services". If another program holds port 4318, Latte keeps running and frappe services shows the collector unavailable.
  • frappe new writes an AGENTS.md that maps the application for coding agents, a CLAUDE.md that imports it, and a shorter README.md. Existing applications keep their files; copy AGENTS.md and CLAUDE.md from templates/application in the release source to adopt them.
  • The Caramel/ServiceNoun lint message and description no longer cite the design RFC. The rule is unchanged.
  • The release source no longer ships the design RFC, the research notes or the separate testing, views and editor-tools guides. The notes are in caramel-notes, and the guides are on the website.
  • An application can be multi-tenant (ADR 0025). Nothing changes until it runs frappe make tenancy MODEL, such as frappe make tenancy Account. That command adds the tenant's schema, migration, sign-up page and home page, require "caramel/tenancy" in config/application.cr, and a tenant App::Account, by: :slug do … end block in config/routes.cr. Resources generated after it belong to the tenant and live under /SLUG; frappe make resource … --central makes one every tenant shares. To make an existing populated table tenanted, follow the ADR's "Plugging in on existing data".
  • SugarORM::Catalog::ForeignKey now holds columns and references_columns arrays instead of column and references_column, so a key may span several columns. The schema document an application prints for frappe db diff is now version 2: upgrade the application's Caramel and Frappé together.

Breaking changes

  • sugar_orm: support multi-column foreign keys (bc8ffb0)

Features

  • core: add opt-in multi-tenancy with caramel/tenancy (0d7ea4a)
  • frappe: add make tenancy and tenant resources (76dfef8)
  • frappe: give new applications AGENTS.md and a short README (3074d5a)
  • crema: trace requests with request ids, traceparent and wide log lines (7a271cd)
  • crema: instrument SQL, jobs, schedules, outbound calls, cache and views (5343a1b)
  • frappe: add the development inspector, toolbar and richer error pages (fd8090e)
  • crema: add the ops socket, console and production commands (5c458d7)
  • crema: add the opt-in Postgres recorder (4ca9978)
  • crema: add the opt-in OTLP trace exporter (6e05b8c)
  • latte: collect query statistics in the managed PostgreSQL (7ddbcd8)
  • latte: show error badges and notifications through control API v2 (938f4fe)
  • latte: write per-site access logs (ea9d9b0)
  • latte: collect local traces across sites (8fb4dd8)

Fixes

  • sugar_orm: drop undeclared foreign keys before column drops (cf0f186)
  • core: match only tenant routes in a tenant, even for an empty block (dcbea8f)
  • frappe: check tenant names' length and refuse a missing anchored file (7384b6d)
  • crema: act on review findings: no log text, paths or statements in production surfaces (5822a1b)
  • latte: narrow the collector's rescue and prove the statistics grant is gone (ed9d6af)
  • latte: answer 400 to a collector body that is not an object (b3dab3d)