Repository navigation
Caramel 0.8.0
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 inboundtraceparentcontinues the caller's trace. The application logs one canonical line per request through thecremalog source, andserveandworkset up logging themselves: JSON in production, text in development and test (CARAMEL_LOG_FORMAT,LOG_LEVEL). The oldrequest_id=… error_type=…error line is gone; theerrorline carrieserror_classandfingerprintinstead.Caramel::DevelopmentError.responsenow takes aCaramel::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 newcaramel_jobs.contextcolumn (a framework migration, so runfrappe migrate); and each database pool names itself inapplication_name. Cold Brew's worker, maintenance, scheduler and hook error lines are nowerrorentries from thecremasource.Caramel::Database::Confighas anapplication_name.SugarORM::Repohas two private hooks,observeandobserve_checkout, thatcaramel/crema/sqlredefines.dump valueis a development aid. frappe devgets 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; setCARAMEL_EDITOR) and compile errors that link to the editor.frappe traces,frappe trace REFandfrappe errorsread what the session kept (frappe errorslists only what happened after the newest successful build, so a rebuild clears errors it fixed); MRDP gains the codesRUNTIMEandREPEATED_QUERY.frappe lintand new applications'.ameba.ymlenableCaramel/Dump, which reports a leftoverdump; add it to an existing application's.ameba.ymlto adopt it. The development gateway's status answerslatest, andLatte.apphas an Open inspector item.- A running application opens an owner-only ops socket (ADR 0028):
servenext to its application socket,workonly whenCARAMEL_OPS_SOCKETnames a path,offto 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) andAPP db diagnose(alsofrappe db diagnose) need only the database.Caramel::CommandLine.with_databaseis public for registered commands, andCrema.commandadds application commands. require "caramel/crema/recorder"makes an application keep per-minute counts and latency histograms incaramel_metrics, read byAPP insightsand the ops console. New applications require it inconfig/application.cr; add the line afterrequire "caramel"to adopt it, and runfrappe 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 endpointOTEL_EXPORTER_OTLP_ENDPOINTnames, with the usualOTEL_*headers, service name and sampler variables (ADR 0028). It does nothing without an endpoint.Caramel::Outboundcalls carry the sampling decision in theirtraceparent.- Latte's managed PostgreSQL preloads
pg_stat_statementsandauto_explain(ADR 0029); the next start of an existing cluster restarts it once. Each site's development database getspg_stat_statementsin acaramel_statsschema, whichfrappe db diagnosereads andfrappe db dumpleaves out. No role is grantedpg_read_all_stats, so a site's role sees statement text only for its own statements, and utility statements (such asALTER ROLE … PASSWORD) are not tracked.auto_explainlogs the text and plan of statements that take 250 ms or more topostgres.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
errorsandlast_error. Version 1 is still served and unchanged; Frappé, Corretto and Latte.app now ask for version 2, so runlatte stoponce 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'sX-Request-Id.proxy.logno 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 withOTEL_EXPORTER_OTLP_ENDPOINT=http://127.0.0.1:4318andOTEL_EXPORTER_OTLP_PROTOCOL=http/json;frappe devsends its application's traces there, and the inspector andfrappe trace REF --mdshow what other services did in the same trace under "Across services". If another program holds port 4318, Latte keeps running andfrappe servicesshows the collector unavailable. frappe newwrites anAGENTS.mdthat maps the application for coding agents, aCLAUDE.mdthat imports it, and a shorterREADME.md. Existing applications keep their files; copyAGENTS.mdandCLAUDE.mdfromtemplates/applicationin the release source to adopt them.- The
Caramel/ServiceNounlint 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 asfrappe make tenancy Account. That command adds the tenant's schema, migration, sign-up page and home page,require "caramel/tenancy"inconfig/application.cr, and atenant App::Account, by: :slug do … endblock inconfig/routes.cr. Resources generated after it belong to the tenant and live under/SLUG;frappe make resource … --centralmakes one every tenant shares. To make an existing populated table tenanted, follow the ADR's "Plugging in on existing data". SugarORM::Catalog::ForeignKeynow holdscolumnsandreferences_columnsarrays instead ofcolumnandreferences_column, so a key may span several columns. The schema document an application prints forfrappe db diffis 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)