Skip to content
quarry Timeline
Login

Timeline

10 most recent check-ins occurring on or after 2026-08-31 15:39:21.

More ↑
2026-08-31
21:02
warm four repositories at once, not two check-in: 7a4e0fcfc7 user: quarry tags: trunk
21:00
reap orphaned zit serve children at startup check-in: 0cb8f48a5f user: quarry tags: trunk
20:49
selection: underline means tab; toggles wear the button chip

See the wiki page [Selected states] for the states and the reasoning. check-in: baecdf8460 user: quarry tags: trunk

20:33
pin the nonce alphabet: a + in the attribute silently kills CSP mode check-in: 47064a1033 user: quarry tags: trunk
20:30
url-safe nonce: no + to escape in the attribute check-in: ce8dcd1ae6 user: quarry tags: trunk
20:02
a strict CSP: nonces, no unsafe-eval, no inline handlers

quarry served no page policy at all. The blocker was never the data-on:* attributes — script-src does not govern data attributes — it was unsafe-eval, because datastar compiled expressions with Function(). 1.0.3 takes a nonce instead.

Removed all 14 inline handlers: 11 identical onchange=this.form.submit() became data-on:change with requestSubmit (which validates, unlike submit), two selection handlers became expressions, and the copy-hash button moved to a delegated assets/copy.js. Scripts now carry content-hashed immutable URLs instead of revalidating daily.

The audit found the expressions already safe, for a reason worth pinning: html/template strips a data- prefix before classifying, so data-on:drop gets the JAVASCRIPT escaper. That matters because an HTML-escaped quote decodes back to a quote before any script reads the attribute, and a board column status comes from .quarry/tickets.json — upstream content on a mirror. check-in: ef352402f6 user: quarry tags: trunk

17:10
datastar 1.0.0-RC.7 to 1.0.3

A release candidate was shipping in production. No breaking changes across the three patch releases; two fix things quarry leans on — select signal typing and dynamic multiple (the ticket sidebar and board are native selects) — and 1.0.3 adds the CSP mode that would let the forge drop unsafe-eval. check-in: e13cb74667 user: quarry tags: trunk

16:08
gzip what benefits, never the event streams

Nothing was compressed: a request carrying Accept-Encoding got byte-identical bytes back. Measured here, the timeline page is 309,584 to 36,599 (88%), a ticket list 84%, a highlighted source page 92%.

gzip rather than brotli deliberately — brotli q5 beat gzip 6 on both size and time, but that is a dependency for ~7% on a page already 88% smaller. SSE is excluded by content type: 22 stream writers, and a buffered stream is a live update that never arrives. check-in: d598ecafa3 user: quarry tags: trunk

15:49
serve the stylesheet instead of inlining it in every page

112,118 bytes of <style> rode on every response — 40% of a 309,584-byte timeline page, byte-identical each time and uncacheable because it had no URL, while the JS assets already carried Cache-Control. Now one hashed asset served immutable: a rule change mints a new URL, so a stale cache is impossible without anyone revalidating. check-in: eb4793ee8e user: quarry tags: trunk

15:39
the zit figure's count suffix is two bytes, not one

The multiplication sign in 'zit 34.1ms×2' never matched a byte compare, so the duration parsed as zero and the store note appeared beside an identical zit figure — claiming a wait already accounted for. check-in: 433a022052 user: quarry tags: trunk

More ↓