Changelog
All notable changes to this project will be documented in this file.
The format is based on Keep a Changelog, and this project adheres to Semantic Versioning and to Conventional Commits.
Unreleased
v0.2.0 (2026-07-14)
Added
rails g briefly:install— a Rails generator that writesconfig/initializers/briefly.rb: a workingAppfacade plus a commented, concern-grouped map of every shortcutuse "rails"installs. Pass a name (rails g briefly:install Facade) to rename the constant; re-run it after upgrading to refresh the map, as Rails prompts before overwriting. It loads only underrails generate, so no Rails runtime dependency is added.Briefly::Rails::Configgainserror(Rails.error, the framework's handled-error reporter) andconfig_for(per-environment YAML viaRails.application.config_for). Both are live lookups;config_fortakes an argument, so it never memoizes — compose one that does by chaining.memoizeonto a shortcut:shortcut(:x) { config_for(:x) }.memoize.Briefly::Rails::DBgainsconnected_to,readingandwritingfor multi-database routing.connected_toforwards the full Rails surface (role:,shard:,prevent_writes:, custom roles);reading/writingare sugar that pin their role and forward the rest.basemust beActiveRecord::Baseor an abstract connection class; a concrete model raisesNotImplementedError.Briefly::Rails::DBgainsselect— a raw-SQL read throughselect_all, returning anActiveRecord::Resulton the query-cache-preserving path, with the same positional and named bind-safety asquery.querykeeps running arbitrary SQL (writes and DDL included) viaexec_query.Briefly::Rails::Envgainsdev?andprod?, aliases ofdevelopment?andproduction?.Briefly::Rails::Instrument— a new"rails/instrument"pack with oneinstrumentshortcut overActiveSupport::Notifications.instrument(name, payload) { }. Usable on its own;use "rails"includes it, soApp.instrumentcomes for free.
Changed
- BREAKING: Facade management moved behind a single
App.brieflyaccessor —App.briefly.configure,App.briefly.shortcuts,App.briefly.shortcut?andApp.briefly.clear_memos!. This freesconfigure,shortcuts,shortcut?andclear_memos!for use as your own shortcut names; onlybriefly,inspectandto_sstay reserved on the facade's public surface. - BREAKING:
Briefly::Rails::DB#connection/#connis now an auto-releasing block that forwards tobase.with_connection, yielding the leased connection and releasing it at block exit — the shape oftransaction. It requires a block; the old barebase.lease_connectionaccessor (held on the thread and never released, a leak outside a request) is gone, with no compatibility shim. Anyone needing a held raw lease callslease_connectionon their model directly. - The DB pack's tests now run against real Active Record on in-memory SQLite, so its Active Record
calls are verified rather than mocked.
activerecordandsqlite3joinactivesupportas dev-only dependencies; the gem still declares no Rails runtime dependency. - BREAKING:
shortcutnow returns theBriefly::Shortcutit declares instead of the canonical name Symbol. Refine it in place —shortcut(:x) { ... }.memoize,.rescue_from(Error) { fallback }, in any order — so a shortcut's name is never written twice to annotate it. A bodilessshortcut(:x)fetches an already-declared shortcut (canonical or alias) to refine, raisingBriefly::UnknownShortcutErroron an unknown name; it never re-declares. A shortcut's memoization and its own error handlers live on the shortcut itself, so refining it after a redeclaration affects the declaration you named, exactly as its body does. - BREAKING: The top-level
rescue_from(error_class)verb is now facade-wide only and takes no shortcut names; passing any raisesArgumentErrorpointing atshortcut(name).rescue_from(...). Scope a handler to a shortcut by chaining.rescue_fromonto it. GlobalBriefly.rescue_fromis unchanged. - BREAKING: the rescue-handler registry is now
Briefly::Rescues(wasBriefly::ErrorRegistry), reached throughBriefly.rescues(wasBriefly.errors) — it holdsrescue_fromhandlers, not errors.Briefly.rescues.clearstill resets globally registered handlers; the internal#wideenumerator is gone, replaced by#sizefor counting registrations.
Removed
- BREAKING:
App.reset!— useApp.briefly.clear_memos!. It was a pure alias forclear_memos!with no internal callers. - BREAKING: The top-level
memoizeDSL verb — chain.memoizeonto the shortcutshortcutreturns (shortcut(:x) { ... }.memoize), orshortcut(:x).memoizefor one declared elsewhere. - BREAKING: Scoping
rescue_fromby shortcut name on the top-level verb — both single-namerescue_from(Error, :x)and multi-namerescue_from(Error, :a, :b). Scope on the shortcut instead:shortcut(:x).rescue_from(Error) { ... }, chaining onto each of several.
v0.1.0 (2026-07-10)
Added
Briefly.definebuilds a facade of real, introspectable, stubbable methods — nomethod_missing.shortcut(canonical, *aliases, &body)with argument, keyword and block forwarding; predicate and bang names; last-declaration-wins overrides. Each shortcut compiles to a real method carrying its body'sarityand parameter kinds, with asource_locationpointing at the block you declared — keyword names are exact, positionals get generated ones (__p0,__r1, …). A wrong-arity call, a missing required keyword and an unknown keyword raiseArgumentErrorat the call site, before anyrescue_fromhandler is consulted.namespace(name) { ... }— groups shortcuts behind a child facade, soApp.db.queryworks without burning root-level names. Takes the whole DSL, including nested namespaces.clear_memos!cascades into it.configurestays atomic across the whole tree: a pass that raises anywhere leaves the root and every namespace untouched. Ashortcutof the same name overrides a namespace and drops the child.memoize— permanent per-process caching, correct fornil/false, never caching a rescued fallback.rescue_from— facade-scoped, facade-wide and global (Briefly.rescue_from) handlers whose return value becomes the shortcut's value.clear_memos!/reset!,configure,shortcuts,shortcut?,inspect.- Pack protocol: any object responding to
#install(builder, **opts).useaccepts keywords, forwarded to the pack'sinstall.Briefly.register(name, pack)/Briefly.pack(name)provide a pack registry, souse "rails/db"resolves; values may be a pack or a constant path resolved on first use, and an unknown name raisesBriefly::UnknownPackError. - Method fabrication — the arity,
parametersandsource_locationeach shortcut reports — is provided by candor, the sole runtime dependency (candor itself has none). Compiled bodies live underCandor::BODY_PREFIX; a shortcut may not take a name there. Briefly::Rails—config/c,config_x/x,envand its predicates,root,cache,logger/log,credentials/cred,helpers/h,routes/r,renderer,render, plus adbnamespace. Nothing in the pack is memoized. ItsConfig,EnvandViewgroups are usable alone.Briefly::Rails::DB—connection/conn,transaction/txn,query.querytakes positional (query(sql, 1)) or named (query(sql, id: 1)) binds, and passes a bindless statement through unsanitized. Takesbase:(default"ApplicationRecord"), resolved on every call so a reloaded class is never captured. Memoizes nothing and wires no lifecycle hook, so it works without a booted application.Briefly::Rails::Reload— clears memos viaRails.application.reloader.to_prepare.- RBS signatures in
sig/.