Changes for version 0.49 - 2026-09-11

  • ADDS: i18n catalogues are held in a Frozen block instead of an arena built here. The block holds a tree, so a level and a leaf are different nodes.
  • FIXES: a literal key containing a dot and the nested form it looks like were the same key, and which one answered was decided by the hash order of the process that loaded it. Two workers in one pool could serve different translations for the same key. A dotted key is now a boot error.
  • FIXES: a catalogue value that is not text no longer renders as the key. null, an array and a boolean are boot errors naming the path; numbers are stored as their digits and read back unchanged.
  • FIXES: UTF-8 is preserved through interpolation. A substituted value was appended as raw bytes into a string that was then flagged UTF-8, so a non-ASCII entry plus a downgraded substitution produced malformed output. Reachable from a form field.
  • FIXES: a catalogue from any producer keeps its encoding. Only the JSON path was correct before, and only because that decoder happens to decode to UTF-8.
  • FIXES: the documentation described a language-switcher cookie that was never implemented. Punk reads punk.lang and has never written it; the POD now says so and shows the handler that does.
  • ADDS: the locale hash can be iterated. keys, each and scalar used to die. The order is the same in every process.
  • BREAKING: _build takes catalogues that have been through Frozen's builder; a catalogue key may not contain a dot; a catalogue value must be text.
  • Requires Frozen 0.06.

Documentation

the Punk command line

Modules

a MVC web framework
the per-application registry and boot compiler
async and await in Punk apps, controllers and models
the authentication battery
password hashing
cross-origin resource sharing
single-use CSRF tokens
a pluggable cache with TTL
a cache store on disk, shared by the whole worker pool
an in process cache store, bounded by bytes
the punk command line: registry, dispatcher and commands
YAML configuration with secrets kept out of the file
the per-request object
base class for Punk controllers
the development error page
an async result that runs on the loop, or blocks
scaffold a new Punk application
security response headers
a level-based logger
the storage-agnostic model tier
the default DBI backend for Punk models
a non-blocking backend for Punk models
a directory of markdown as a documentation site
the api mount: spec-first operations
base class for Punk plugins
content addressed storage for uploads
Content-Security-Policy with a per request nonce
ETags, Last-Modified and 304s for dynamic responses
liveness and readiness probes that mean different things
translations and language negotiation
Idempotency on unsafe methods
a Prometheus endpoint whose labels cannot run away
give every request an id
sitemap.xml and robots.txt from the route table
rate limiting and IP blocking over Hyperman's shared arena
a lazy wrapper over the PSGI environment
a response builder
the compiled-at-boot route tables (XS)
the handle an under returns
a Server-Sent Events stream
the bounded body of a ranged send_file response
signed cookie sessions
server-side sessions, on any store
serving files from a directory
a streamed response for an ordinary route
an in-process test client for Punk applications
a pure-Perl RFC 6455 codec for testing WebSocket servers
the client side of one WebSocket connection
the transaction a < $c-txn >> block receives
the outbound HTTP agent on the context
an uploaded file from a multipart form
collecting request validation
the Template::Stencil view engine
the pluggable view engine registry (XS)
a WebSocket connection
pub/sub groups of WebSocket connections